iptables + firewalld
CentOS7默认用firewalld iptables也有
CentOS6 用的是iptables
iptables:
iptables的规则方式有表、链、规则。
其中表的范围最大,表上有多个链,链上是规则。
工作原理:
工作空间之用户空间–iptables firewall
工作空间之内核空间–net filter
在用户空间使用命令,编写规则,规则编写好以后,直接作用在内核空间,立即生效。但是此时不是保存,关机重启就丢失。
iptables的语法结构:iptables [-t 表名] 选项 链 规则信息 -j 动作
表:
raw:高级功能,如:网址过滤。
mangle:数据包修改(QOS),用于实现服务质量。
net:地址转换,用于网关路由器。 **
filter:包过滤,用于防火墙规则。 **
链:
INPUT链:处理输入数据包。 **
OUTPUT链:处理输出数据包。 **
PORWARD链:处理转发数据包。
PREROUTING链:用于目标地址转换(DNAT)。
POSTOUTING链:用于源地址转换(SNAT)。
动作:
ACCEPT:接收数据包。 **
DROP:丢弃数据包。 **
REDIRECT:重定向、映射、透明代理。
SNAT:源地址转换。
DNAT:目标地址转换。
MASQUERADE:IP伪装(NAT),用于ADSL。
LOG:日志记录。
选项:
-t<表>:指定要操纵的表; **
-A:向规则链中添加条目; **
-D:从规则链中删除条目; **
-i:向规则链中插入条目;
-R:修改规则链中的条目; **
-L:显示规则链中已有的条目; **
______-n 跳过域名、端口解析 -L 的选项
______–line-number 显示规则编号 -L的选项
-F:清楚规则链中已有的条目; **
-Z:清空规则链中的数据包计算器和字节计数器;
-N:创建新的用户自定义规则链;
-P:定义规则链中的默认目标; **
-h:显示帮助信息;
-p:指定要匹配的数据包协议类型; **
______ tcp
______ --dport 目的端口
______ --sport 源端口
-s:源地址;
-d<目标>:目标地址;
-i<网络接口>:从哪个网卡进;
-o<网络接口>:从哪个网卡出。
-X 删除多余的链 **
-I 插入规则 **
-j 动作 **
______ ACCEPT 允许访问
______ DROP 拒绝访问
规则的匹配顺序:
从上到下 !!!
编写规则的注意事项:
(1)规则的数量不要写太多;
(2)将匹配访问大的规则置于最下面;
[root@lamp ~]# iptables -A INPUT -s 172.16.12.85 -p tcp --dport 22 -j ACCEPT
允许172.16.12.85这个IP通过tcp协议走22 端口访问 。
这里没写 -t 指定表,因为默认就是filter
表。
[root@lamp ~]# iptables -A INPUT -s 172.16.0.0/16 -p tcp --dport 80 -j ACCEPT
允许172.16这个网段,通过80端口访问web服务。
[root@lamp ~]# iptables -A INPUT -p tcp --dport 80-j DROP
拒绝所有通过80端口的访问。
规则的保存:
[root@lamp ~]# yum install iptables-services -y
[root@node2 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
就将规则保存在 /etc/sysconfig/iptables
这个文件中了。
防火墙的模块:
在编写规则的过程中,让规则更人性化。
目录在/usr/lib/modules/3.10.0-693.el7.x86_64/kernel/net/netfilter
,这里的都是模块,都是.ko结尾由xz压缩。
【1】state
状态模块
- NEW:连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。
- ESTABLISHED:我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接已建立。
- RELATED:从字面上理解RELATED译为关系,建立新的数据发送指令,数据报文和命令报文必须是有关系的。
- INVALID:无效的,数据包被丢弃或不能被识别。
- UNTRACKED:数据包未被跟踪。
可以用ftp来做例子:ftp要用到2个端口,2个进程。主动模式是20端口传递命令,21 端口传递数据。
传输命令的进程建立了一个连接,命令连接,也就是客户端进行三次握手连接服务端20端口。其中第一次握手就可以理解成是NEW状态。后两次就是ESTABLISHED状态。
而建立了命令连接后,准备传输数据,用21 端口建立数据连接,那么发什么数据或者收什么数据是由命令连接控制的。
这时数据连接中的报文就是RELATED模式的,因为这个连接中的报文和命令连接中的报文有关系。
栗子:
1、本机禁止被连接,但可以连接其他人
[root@zabbix-ms ~]# iptables -A INPUT -m state --state NEW -j DROP
[root@zabbix-ms ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere state NEW
将NEW模式的包拦截,这样别人就不能建立新的连接连到主机了,这个主机可以连接别人,发给别人的第一次握手可以出去,别人响应的时候发包就变为ESTABLISHED 了也能通过,所以连接别的主机可以连接。但是创建规则前建立的连接并不会失效。
2、开放本机的ftp服务
要开放 20 和 21 和 大于1024的随机端口。
随机端口不好设置,可以固定FTP的端口。
pasv_min_port=20070
pasv_max_port=20075
然后开放这几个端口。
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m multiport -p tcp --dport 20:21,20070:20075 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP
【2】iprange
IP地址范围。
–src-range 源地址范围
–dst-range 目的地址范围
[root@localhost netfilter]# iptables -A INPUT -m iprange --src-range 172.16.12.1-172.16.12.10 -p tcp --dport 22 -j ACCEPT
[root@localhost netfilter]# iptables -A OUTPUT -m iprange --dst-range 172.16.12.90-172.16.12.100 -j ACCEPT
【3】multiport
多端口模块:
iptables -A INPUT -m multiport -p tcp --dport 20:21,20070:20075 -j ACCEPT
用逗号分隔。
注:
- 软件防火墙无法阻挡DOS攻击,不要过分相信它;
- 在调试防火墙规则的时候,先写一个计划任务,5分钟关闭一次防火墙服务;提示完毕,再删除计划任务;
- 尽量不要修改默认规则;
- 打开本地回环网卡
[root@node2 ~]# iptables -A INPUT -i lo -j ACCEPT
[root@node2 ~]# iptables -A OUTPUT -o lo -j ACCEPT
------测试本机的网络配置,能PING通127.0.0.1说明本机的IP协议安装没有问题。
------某些SERVER/CLIENT的应用程序在运行时需调用服务器上的资源,一般要指定SERVER的IP地址,但当该程序要在同一台机器上运行而没有别的SERVER时就可以把SERVER的资源装在本机,SERVER的IP地址设为127.0.0.1同样也可以运行。- 采购硬件防火墙,置于整个系统前面,保护内部环境;
filter表的FORWARD链:
forward就是转发,在这里表示将请求转发给别人。
比如用3台主机简单演示:
正常来说他们都只能找到网关,而不能直接和对方网络直接通信,毕竟这个不是路由。
在防火墙上,设置数据包转发:
[root@firewall ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
就可以通信了。但是这时所有的请求都会转发,不够安全。
在中间的机器上,设置转发规则。
[root@firewall ~]# iptables -A FORWARD -p icmp -j ACCEPT
[root@firewall ~]# iptables -A FORWARD -j DROP
ICMP是ping协议。
允许ping。
[root@172.16.12.9 ~]# ping 221.122.126.100
PING 221.122.126.100 (221.122.126.100) 56(84) bytes of data.
64 bytes from 221.122.126.100: icmp_seq=1 ttl=63 time=2.52 ms
64 bytes from 221.122.126.100: icmp_seq=2 ttl=63 time=0.733 ms
能够通信。
转发web请求。 web请求不光要去还要返回包,所以要开放ESTABLISHED和RELATED模式的。
web-server用的是apache 在221.122.126.100上。
index.html文件:
<h1>172.16.12.32<h1>
[root@firewall ~]# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@firewall ~]# iptables -A FORWARD -s 172.16.12.92 -p tcp --dport 80 -j ACCEPT
[root@firewall ~]# iptables -A FORWARD -j DROP
[root@172.16。12.92 ~]# curl 221.122.126.100
<h1>221.122.126.100<h1>
这个IP 能访问。
[root@172.16.12.73 playbook]# curl 221.122.126.100
别的就不能访问
NAT表:
把web-server端的网关去掉。
这时 172.16.12.92相当于客户端,172.16.12.32 相当于是路由,221.122.126.100是web-server。
设置SNAT:
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -p tcp --dport 80 -j SNAT --to-source 221.122.126.254
这时221.122.126.100网络没有网关,只能由局域网连接,这个规则就是将172.16.0.0网段的转换为221.122.126.254 网络,221.122.126.254是实际存在的网卡,与100网络在同一局域网,就能通信了。
[root@zabbix-ms ~]# curl 221.122.126.100
<h1>221.122.126.100<h1>
去掉client端的网关
此时172.16.12.92相当于client端 ,172.16.12.32 相当于防火墙,221.122.126.100相当于web-server端
设置DNAT:
[root@localhost ~]# iptables -t nat -A PREROUTING -d 172.16.12.32 -p tcp --dport 80 -j DNAT --to-destination 221.122.126.100
[root@172.16.12.92 ~]# curl 172.16.12.32
<h1>221.122.126.100<h1>
和SNAT类似DNAT也是转换,不过是转换的目标地址。SNAT是转换源地址,DNAT是转换目标地址。这个例子是将防火墙的地址172.16.12.32转换为web-server的服务地址221.122.126.100,客户端直接访问172.16.12.32就是访问221.122.126.100。
网络包的请求和响应过程
主机请求web-server。
主机 -> 路由 -> 防火墙 -> web-server
主机发包给web-server。
主机发送请求包,经由路由器,路由器会先查路由表,确定地址可达,再做源地址转换(私有地址不能在公网通信,要将私有地址192.168.1.1转化为路由器的出口IP213.79.68.54),然后请求发送到防火墙(web-server也是私有地址,不能直接找到),防火墙还要做目的地址转换,将目标地址转化成网络公司内web-server的地址,再查路由表找到对应的web-server。
回包时: web-server -> 防火墙 -> 路由 -> 主机
和请求时相反,身份发生变化,web-server变成了发包的角色,client变成了收包的角色。
防火墙先做查询路由表,再做源地址转换,找到路由,然后路由做目标地址转化,再查路由表,返回包给主机。
端口映射/端口转发:
需求很简单,把本地80端口映射到8080端口上
本机
1.所有的81请求转发到了8080上。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
2.如果需要本机也可以访问,则需要配置OUTPUT链:
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 8080
需要打开ip_forward
功能。(上边的数据转发)
跨网络、跨主机的映射Full-Nat
我们想到达主机B的80端口,但是由于网络限制可能无法直接完成。但是我们可以到达主机A的8080端口,而主机A可以直接到达B的80端口。
这时候可以使用iptables,将主机B的80端口映射到主机A的8080端口,通过访问A的8080相当于访问B的80。实现如下:
在主机A上直接如下命令,实现端口映射的Full-Nat
#!/bin/bash
pro='tcp'
NAT_Host='Host_A'
NAT_Port=8080
Dst_Host='Host_B'
Dst_Port=80
iptables -t nat -A PREROUTING -m $pro -p $pro --dport $NAT_Port -j DNAT --to-destination $Dst_Host:$Dst_Port
iptables -t nat -A POSTROUTING -m $pro -p $pro --dport $Dst_Port -d $Dst_Host -j SNAT --to-source $NAT_Host
说明:
NAT_Pro表示NAT的协议,可以是tcp或udp
NAT_Host表示中间做端口映射的主机。这里也就是主机A
NAT_Port表示中间做端口映射的端口。这里也就是主机A的8080口
Dst_Host表示被NAT的主机。这里也就是主机B
Dst_Host表示被NAT的端口。这里也就是主机B的80口
firewall:
在CentOS7 上用的是firewall,但是这个和iptables在本质上一样都是做限制。
启用firewalld要先关闭iptables。
[root@firewall ~]# systemctl stop iptables
[root@firewall ~]# systemctl disable iptables
[root@firewall ~]# systemctl restart firewalld
[root@firewall ~]# systemctl enable firewalld
firewall 的原理是区域:
网络区域定义了网络连接的可信等级。这是一个 一对多的关系,这意味着一次连接可以仅仅是一个区域的一部分,而一个区域可以用于很多连接。
[root@firewall ~]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
有以上9个区域。
trusted 信任 :可接收所有的网络连接
drop 丢弃:任何接收到的网络数据都被丢弃,没有任何回复,公有发送出去的网络连接
block 拒绝:任何接收的网络连接都被IPV4 的icmp-host-prohibited信息和IPV6的icmp6-adm-prohibited信息所拒绝
dmz 非军事区 :(非军事区) 用于你的非军事区的电脑 ,此区域内可公开访问,可以有限的进入你的内部网络,仅接收经过选择的连接。
external外部区域 :(外部)特别是为路由器启用了伪装功能的外部网。你不能信任来自网络的其它计算,不能信任它们不会对你的计算机造成危害,只能接收经过选择的连接。
home 家庭 :(家庭) 用于家庭网络,可以基本信任网络内的其它计算机不会危害你的计算机,仅接收经过选择的连接。
internal内部区域 :(内部)用于内部网络,可以基本信任网络内的其它计算机不会危害你的计算机,仅接收经过选择的连接
public 公共,默认的区域 :(公共) 在公共区域内使用,不能相信网络内的其它计算机不会对你的计算机造成危害,只接收经过选取的连接
work 工作 : (工作) 可以基本信任网络内的其它计算机不会危害你的计算机,仅接收经过选择的连接。
[root@firewall ~]# firewall-cmd --list-all --zone=public
public (active) //区域的名字
target: default //动作
icmp-block-inversion: no //icmp报文阻塞,可以选择Internet控制报文协议的报文。这些报文可以是信息请求亦可以是对信息请求或错误条件创建的响应。
interfaces: ens33 ens37 //列出了这个区域上关联的接口
sources: //列出了这个区域的ip源。现在这里什么都没有,192.168.1.0/24 192.16.1.2
services: ssh dhcpv6-client //服务列表,允许的服务
ports: //列出了一个允许通过这个防火墙的目标端口
protocols: //协议
masquerade: no //表示这个区域是否允许 IP 伪装
forward-ports: //列出转发的端口
source-ports: //源端口
icmp-blocks: //阻塞的 icmp 流量的黑名单
rich rules: //在一个区域中优先处理的高级配置
查看public区域的信息。
当一个区域处理它的源或接口上的一个包时,但是,没有处理该包的显式规则时,这时区域的目标target决定了该行为:
target
ACCEPT:通过这个包。
%%REJECT%%:拒绝这个包,并返回一个拒绝的回复。
DROP:丢弃这个包,不回复任何信息。
default:不做任何事情。该区域不再管它,把它踢到“楼上”。
命令格式:
firewall-cmd [选项 ... ]
--state //显示firewalld的状态;
--reload //不中断服务的重新加载;
--complete-reload //中断所有连接的重新加载;
--runtime-to-permanent //将当前防火墙的规则永久保存;
--check-config //检查配置正确性;
--permanent //永久的的规则配置,覆盖当前运行时配置,如果没有这个不会执行修改
--get-log-denied //获取记录被拒绝的日志;
--set-log-denied=<value> //设置记录被拒绝的日志,只能为 'all','unicast','broadcast','multicast','off' 其中的一个;
向public区,添加web服务:
[root@firewall ~]# firewall-cmd --permanent --zone=public --add-service=http
success
[root@firewall ~]# firewall-cmd --reload
success
然后查看区域的信息。
[root@firewall ~]# firewall-cmd --list-all --zone=public
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client http
ports:
//发现已经有了http
此时打开了防火墙也能访问Web服务。
[root@172.16.12.92 ~]# curl 172.16.12.32
<h1>172.16.12.32<h1>
向trusted区加入172.16.0.0/16网段:
[root@firewall ~]# firewall-cmd --permanent --zone=trusted --add-source=172.16.0.0/16
success
[root@firewall ~]# firewall-cmd --reload
success
查看trusted的信息
[root@firewall ~]# firewall-cmd --list-all --zone=trusted
trusted (active)
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources: 172.16.12.92 172.16.0.0/16
services:
看到source 源地址有IP。
删除trusted区域的ip:
[root@firewall ~]# firewall-cmd --permanent --zone=trusted --remove-source=172.16.0.0/16
success
[root@firewall ~]# firewall-cmd --reload
success
[root@firewall ~]# firewall-cmd --permanent --list-all --zone=trusted
trusted
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources: 172.16.12.92
services:
172.16.0.0被删除了。
web 白名单
将公司的公网IP引入trusted
其他的都写入drop
或者
public区域的服务和源IP清空。
work区域添加服务和源IP
web 黑名单
在public区域加上http服务
work 加入ssh服务
drop加上禁止的IP。
firewall的工作原理及过程:
1、虽然各个区域之间相互独立,但是在各个区域中添加的规则在区域之间不能重复,简单来说就是例如:在public中添加了源IP192.168.1.1,那么在其他任何区域的源IP中都不能添加192.168.1.1了。
2、当一个请求进入防火墙时先进行源地址的判断,如果被某个区域匹配,就将请求接入那个区域,能做的操作都在相应区域的服务列表中。栗子:在work中添加172.16.12.1,public中添加192.168.100.1,这时172.16.12.1请求服务器,那就直接由work区域接收,享受work区域的权限。
3、如果源地址没有被任何一个区域匹配,那么则接入public区域,这也是默认区域的意思。
4、防火墙的匹配没有先后顺序,做完判断就直接进入对应区域中,不会跳到别的区域里。
文件的位置。
firewall的区域也是有文件存储的,位置在/etc/firewalld/zones
,这里显示了所有的激活区域,激活区域就是生效的可以用的区域。
除了可以在命令行中修改规则,也可以在配置文件中修改
[root@localhost ~]# cd /etc/firewalld/zones
[root@localhost zones]# ls
drop.xml drop.xml.old public.xml public.xml.old trusted.xml trusted.xml.old work.xml work.xml.old
这里的配置文件都是xml的。
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short> 区域的名字
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description> 描述
<service name="ssh"/> 服务
</zone>
用命令修改的话只能一条一条修改,在这个文件中修改可以改很多。就按照文件中原来的进行修改就好了,修改之后保存,重启防火墙,就可以生效了。
比如在public区域添加http的服务。
<service name="http"/>
/usr/lib/firewalld/services
服务的位置
/usr/lib/firewalld/zones
这个是目录里的是各个区域默认的状态
[root@localhost zones]# cd /usr/lib/firewalld/zones/
[root@localhost zones]# ls
block.xml dmz.xml drop.xml external.xml home.xml internal.xml public.xml trusted.xml work.xml
如果想恢复到默认状态时,可以删除/etc/firewalld/zones
这里的文件,然后把默认状态的文件复制到这,再重启服务。就恢复到默认状态了。
其实大部分的命令都类似,add添加remove删除等等,还有一些额外的命令。
查看默认的区域:
[root@localhost zones]# firewall-cmd --get-default-zone
public
查看激活区域:
[root@localhost zones]# firewall-cmd --get-active-zone
work
sources: 172.16.12.95
drop
sources: 221.122.126.100
public
interfaces: ens33 ens37
查看服务名列表
[root@localhost zones]# firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-
//特别多
添加端口服务:
[root@localhost zones]# firewall-cmd --permanent --zone=work --add-port=80/tcp
success
端口要注意几点:
1、如果有服务修改的默认端口,那么将服务加入 防火墙规则是不能用的。此时要使用端口来进行控制,比如将apache的80端口改为81。此时添加http的服务是不能访问的。
[root@localhost zones]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh http
ports:
protocols:
masquerade: no
//改为81后添加http服务
[root@ldap_server tmp]# curl 172.16.12.32:81
curl: (7) Failed connect to 172.16.12.32:81; No route to host
访问报错
但是此时不添加http而添加81端口则可以访问。
[root@localhost zones]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh
ports: 81/tcp
protocols:
masquerade: no
//只添加81端口
[root@ldap_server tmp]# curl 172.16.12.32:81
<h1>172.16.12.32<h1>
//能够访问
2、正常来说端口是和IP一起使用的,可以在防火墙上添加IP加端口来指定限制客户端的请求。
[root@localhost zones]# firewall-cmd --list-all --zone=work
work (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 172.16.12.95
services: ssh
ports: 80/tcp
protocols:
masquerade: no
//这个是work区域的,这样的话就算public没有任何的服务开放,172.16.12.95也可以通过work区域访问apache。
//前提自然是apache没有改端口。