一、简介
iptables其实并不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过它将设定执行到对应的“安全框架”中,这个框架叫netfilter,才是真正的防火墙,位于内核空间。iptables其实是命令行工具,位于用户空间。我们用这个工具操作真正的框架。
netfilter/iptables组成linux平台下的包过滤防火墙 ,完成 封包过滤、封包重定向、网络地址转换NAT 等功能。
二、基础
1、链:当我们启用防火墙时,报文需要经过如下图,根据实际情况,报文经过“链”不同。
如上图报文的流向:
到本机某进程的报文: PREROUTING-->INPUT
由本机转发的报文: PREROUTING-->FORWARD-->POSTROUTING
由本机的进程发出报文:OUTPUT-->POSTROUTING
PREROUTING: 数据包进入路由表之前
INPUT: 通过路由表后目的地为本机
FORWARD: 通过路由表后,目的地不为本机
OUTPUT: 由本机产生,向外转发
POSTROUTING:发送到网卡接口之前
2、表 :把具有相同功能的规则的集合叫做表。iptables定义了4种表。
filter表:负责过滤功能,防火墙;
nat表: network address translation,网络地址转换功能;
mangle表:拆解报文,做出修改,并重新封装的功能;
raw表: 关闭nat表上启用的连接追踪机制;
默认表是filter(没有指定表的时候)
表的处理优先级: raw>mangle>nat>filter
3、链与表的关系
链的规则存放哪些表中(从链到表的对应关系):
PREROUTING 规则可以存在于: raw mangle nat
INPUT 规则可以存在于: mangle filter
FORWARD 规则可以存在于: mangle filter
OUTPUT 规则可以存在于: raw mangle nat filter
POSTROUTING 规则可以存在于: mangle nat
但,我们在实际的使用过程中,往往是通过 表 作为操作入口,对规则进行定义的。
表(功能) <------------> 链(钩子):
raw 表规则被哪些链使用 PREROUTING OUTPUT
mangle 表规则被哪些链使用 PREROUTING INPUT FORWARD OUTPUT POSTROUTING
nat 表规则被哪些链使用 PREROUTING OUTPUT POSTROUTING
filter 表规则被哪些链使用 INPUT FORWARD OUTPUT
4、数据包经过防火墙的流程
基本步骤如下:
1、数据包到达网络接口,比如eth0
2、进入raw表的PREROUTING链,这个链的作用是在连接跟踪之前处理数据包。
3、如果进行了连接跟踪,再次处理。
4、进入mangle表的PREROUTING链,在此可以修改数据包,比如QOS等。
5、进入nat表的PREROUTING链,可以在此做DNAT,但不要做过滤。
6、决定路由,看是交给本地主机还是转发给其它主机。
到这里分两种不同的情况,一种情况是数据包要转发给其它主机,依次经过:
7、进入mangle表的FORWARD链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,我们仍然可以对数据包进行某些修改。
8、进入filter表的FORWARD链,在这里我们可以对所有转发的数据包进行过滤。 需要注意的是:经过这里的数据包是转发的,方向是双向的。
9、进入mangle表的POSTROUTING链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,我们还可以进行某些修改。
10、进入nat表的POSTROUTING链,在这里一般都是用来做SNAT,不要在这里进行过滤。
11、进入出去的网络接口。完毕。
另一种情况是,数据包就是发给本地主机的,依次经过:
7、进入mangle表的INPUT链,这里是在路由之后,交由本地主机之前,我们也可也进行一些相应的修改。
8、进入filter表的INPUT链,在这里我们可以对流入的所有数据包进行过滤,无论它来自哪个网络接口。
9、交给本地主机的应用程序进行处理。
10、处理完毕后进行路由决定,看该往那里发出。
11、进入raw表的OUTPUT链,这里是在连接跟踪处理本地的数据包之前。
12、连接跟踪对本地的数据包进行处理。
13、进入mangle表的OUTPUT链,在这里我们可以修改数据包,但不要做过滤。
14、进入nat表的OUTPUT链,可以对防火墙自己发出的数据做NAT。
15、再次进行路由决定。
16、进入filter表的OUTPUT链,可以对本地出去的数据包进行过滤。
17、进入mangle表的POSTROUTING链,同上一种情况的第9步。注意,这里不光对经过防火墙的数据包进行处理,还对防火墙自己产生的数据包进行处理。
18、进入nat表的POSTROUTING链,同上一种情况的第10步。
19、进入出去的网络接口。完毕。
5、规则
匹配条件
源地址 Source IP 目标地址 Destination IP
源端口 Source Port 目标端口 Destination Port
处理动作
ACCEPT: 允许数据包通过。
DROP: 直接丢弃数据包,不给任何回应信息,客户端过了超时时间才会有反应。
REJECT: 拒绝数据包通过,必要时会给客户端一个响应信息,客户端刚请求就会收到拒绝的信息。
SNAT: 源地址转换,解决内网用户用同一个公网地址上网的问题。
MASQUERADE: 是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
DNAT: 目标地址转换。
REDIRECT: 在本机做端口映射。
LOG: 在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。
三、查看规则
iptables -t 表名 -L 链名 ######默认为filter表,即 iptables -L
iptables -t 表名 -L 链名 -v #####展示更多信息
[root@bogon]# iptables -vL
Chain INPUT (policy DROP 9971K packets, 3853M bytes)
pkts bytes target prot opt in out source destination
4626 199K ACCEPT tcp -- any any anywhere anywhere tcp dpt:http
25726 2136K ACCEPT tcp -- any any anywhere anywhere tcp dpt:msgsrvr
5309K 659M ACCEPT all -- any any bogon/24 anywhere
439M 159G ACCEPT all -- any any bogon/24 anywhere
6331K 1167M ACCEPT all -- any any 103.17.42.0/24 anywhere
各字段的含义
pkts: 对应规则匹配到的报文的个数
bytes: 对应匹配到的报文包的大小总和
target: 规则对应的traget,表示对应的动作,即规则匹配成功后需要采取的措施。
prot: 表示规则对应的协议,是否只针对某些协议应用此规则。
opt: 表示规则对应的选项。
in: 表示数据包由哪个接口流入,可以设置哪块网卡流入的报文需要匹配当前规则。
out: 表示数据包由哪个接口流出,可以设置哪块网卡流出的报文需要匹配当前规则。
source: 表示规则对应的源头地址,可以是一个ip,也可以是一个网段。
destination:表示规则对应的目标地址,可以是一个ip,也可以是一个网段。
上面,源地址与目标地址都为anywhere,看来,iptables默认为我们进行了名称解析,如果规则非常多进行解析,效率就会比较低,所以我们可以使用-n选项,表示不对ip地址进行名称反解,直接显示ip地址。如下:
[root@bogon]# iptables -nvL
Chain INPUT (policy DROP 9972K packets, 3853M bytes)
pkts bytes target prot opt in out source destination
4626 199K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
25726 2136K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8787
5309K 659M ACCEPT all -- * * 172.20.38.0/24 0.0.0.0/0
439M 159G ACCEPT all -- * * 172.20.68.0/24 0.0.0.0/0
6332K 1167M ACCEPT all -- * * 103.17.42.0/24 0.0.0.0/0
--line-number:显示规则的编号
[root@bogon]# iptables -nvL --line-number
Chain INPUT (policy DROP 9972K packets, 3854M bytes)
num pkts bytes target prot opt in out source destination
1 4626 199K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
2 25726 2136K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8787
3 5309K 659M ACCEPT all -- * * 172.20.38.0/24 0.0.0.0/0
4 439M 159G ACCEPT all -- * * 172.20.68.0/24 0.0.0.0/0
5 6332K 1167M ACCEPT all -- * * 103.17.42.0/24 0.0.0.0/0
四、规则管理
iptables(选项)(参数)
-t<表>:指定要操纵的表;
-A: 向规则链中添加条目;
-D: 从规则链中删除条目;
-i: 向规则链中插入条目;
-R: 替换规则链中的条目;
-L: 显示规则链中已有的条目;
-F: 清除规则链中已有的条目;
-Z: 清空规则链中的数据包计算器和字节计数器;
-N: 创建新的用户自定义规则链;
-P: 定义规则链中的默认目标;
-h: 显示帮助信息;
-p: 指定要匹配的数据包协议类型;
-s: 指定要匹配的数据包源ip地址;
-j<目标>: 指定要跳转的目标;
-i<网络接口>:指定数据包进入本机的网络接口;
-o<网络接口>:指定数据包要离开本机所使用的网络接口。
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
表名包括:
raw: 高级功能,如:网址过滤。
mangle: 数据包修改(QOS),用于实现服务质量。
nat: 地址转换,用于网关路由器。
filter: 包过滤,用于防火墙规则。
规则链名包括:
INPUT链: 处理输入数据包。
OUTPUT链: 处理输出数据包。
PORWARD链: 处理转发数据包。
PREROUTING链:用于目标地址转换(DNAT)。
POSTOUTING链:用于源地址转换(SNAT)。
动作包括:
accept: 接收数据包。
DROP: 丢弃数据包。
REDIRECT: 重定向、映射、透明代理。
SNAT: 源地址转换。
DNAT: 目标地址转换。
MASQUERADE:IP伪装(NAT),用于ADSL。
LOG: 日志记录。
清除已有iptables规则
iptables -F
iptables -X
iptables -Z
开放指定的端口
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT #允许本地回环接口(即运行本机访问本机)
iptables -A INPUT -i lo -j ACCEPT #允许本地回环访问
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #允许已建立的或相关连的通行
iptables -A OUTPUT -j ACCEPT #允许所有本机向外的访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT #允许访问22端口
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT #允许所有来自外部的SSH连接eth0
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT #允许指定网段的SSH连接eth0
iptables -A INPUT -p tcp --dport 80 -j ACCEPT #允许访问80端口
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT #允许所有来自外部的http连接eth0
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT #允许所有来自外部的https连接eth0
iptables -A INPUT -p tcp --dport 21 -j ACCEPT #允许ftp服务的21端口
iptables -A INPUT -p tcp --dport 20 -j ACCEPT #允许FTP服务的20端口
iptables -A INPUT -j reject #禁止其他未允许的规则访问
iptables -A FORWARD -j REJECT #禁止其他未允许的规则访问
屏蔽ip:
iptables -A INPUT -s x.x.x.x -j DROP
iptables -A INPUT -i eth0 -s x.x.x.x -j DROP
iptables -A INPUT -i eth0 -p tcp -s x.x.x.x -j DROP
iptables -I INPUT -s 123.45.6.7 -j DROP #屏蔽单个IP的命令
iptables -I INPUT -s 123.0.0.0/8 -j DROP #封整个段即从123.0.0.1到123.255.255.254的命令
iptables -I INPUT -s 124.45.0.0/16 -j DROP #封IP段即从123.45.0.1到123.45.255.254的命令
iptables -I INPUT -s 123.45.6.0/24 -j DROP #封IP段即从123.45.6.1到123.45.6.254的命令是
链的默认策略为ACCEPT接收,设置成DROP拒绝:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
防止Ddos攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
上述例子中:
-m limit: 启用limit扩展
–limit 25/minute: 允许最多每分钟25个连接(根据需求更改)。
–limit-burst 100: 只有当连接达到limit-burst水平(此例为100)时才启用上述limit/minute限制。
端口转发
# 打开转发功能
sysctl -w net.ipv4.ip_forward=1
#将来自422端口的流量全部转到22端口。 这意味着我们既能通过422端口又能通过22端口进行ssh连接。启用DNAT转发。
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
#除此之外,还需要允许连接到422端口的请求
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
#当内网服务器要访问外网时,需要做源地址转换;
# 把 192.168.1.0 网段流出的数据的 source ip address 修改成为 10.0.0.11:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 10.0.0.11
#当外网主机要访问内网服务器服务时,需要做目标地址转换;
# 把访问 10.0.0.11:2222 的访问转发到 192.168.1.11:22 上::
iptables -t nat -A PREROUTING -d 10.0.0.11 -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.11:22
#单纯的将访问本机80端口的请求转发到8080上
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
修改规则
命令语法:iptables -t 表名 -R 链名 规则序号 规则原本的匹配条件 -j 动作
示例:iptables -t filter -R INPUT 3 -s 192.168.1.146 -j ACCEPT
保存规则
service iptables save #将规则保存至/etc/sysconfig/iptables
iptables-save > /etc/sysconfig/iptables #centos7中firewalld命令
五、匹配条件的更多用法
iptables -t filter -I INPUT -s 192.168.0.111,192.168.0.112 -j DROP #多个ip用逗号相连,逗号两侧不能包含空格
iptables -t filter -I INPUT -s 192.168.0.0/16 -j DROP #对网段限制
iptables -t filter -I INPUT !-s 192.168.1.1 -j ACCEPT #用“!”取反
-p 协议名 -m 扩展模块 --dport 端口号 (1:22表示 1到22的所有端口)
iptables -t filter -I INPUT -s 192.168.0.1 -p tcp -m tcp --dport 1:22 -j REJECT
multiport模块同时指定多个端口
iptables -t filter -I INPUT -s 192.168.0.1 -p tcp -m multiport --dport 22,36,80 -j DROP
iprange扩展模块指定一段连续的ip地址范围
iptables -t filter -I INPUT -m iprange --src-range 192.168.1.100-192.168.1.123 -j DROP
iptables -t filter -I INPUT -m iprange --dst-range 192.168.1.100-192.168.1.123 -j DROP
time扩展模块根据时间段匹配报文,如果报文达到的时间在指定时间范围内,则符合匹配条件。
-m time 表示time扩展模块, --timestart制定起始时间 --timestop指定结束时间
--weekday指定每个星期的具体哪一天,可以同时指定多个,用逗号隔开
--monthdays指定每个月的具体哪一天,可以同时指定多个,用逗号隔开
--datestart指定开始日期 --datestop指定结束日期
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays 6,7 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --monthdays 21,23 -j REJECT
iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --datestart 2018-05-01 --datestop 2018-05-07 -j REJECT
connlimit限制每个ip地址同时连接到服务端的数量,注 不用指定具体ip,默认为每个客户端ip
-m connlimit 指定connlimit扩展 --connlimit-above 数字 设置上限数量 --connlimit-mask 数字 设置某类网段连接数量
如 限制每个ip地址最多只能占用两个ssh连接
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 --connlimit-mask 20 -j REJECT
limit模块对报文到达速率进行限制。
如 限制外部主机对本机进行ping操作,最多每6秒放行一个ping包(每分钟放行10个包)
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
-m limit表示limite模块 ping包测试如下图:
上图中ping速率没有变化,回顾命令每分钟10个包动作为ACCEPT,而INPUT链的默认策略为ACCEPT,所以相当于所有icmp报文全部放行。更改命令:
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT
iptables -t filter -I INPUT -p icmp -j REJECT
ping包再次测试:
如上图,前5个包没有受到限制,之后开始受到规则限制。这涉及到limit模块使用的 令牌桶算法
令牌桶算法 : 可以这样想象,一个木桶里面放5块令牌且最多只能放下5块令牌,所有报文想要传输必须持有令牌。木桶每隔6秒会产生一个新令牌,如此时,木桶中不足5块,那么新令牌就存放木桶,如已存在5块,新令牌将被丢弃。如此时有5个报文需要传输,那么正好1个报文1块令牌传输。再有报文传输已经没有令牌将被丢弃。但6秒后新的令牌生成,这时的报文将有令牌将被传输,如此循环。如果很长一段时间没有新报文,这时木桶中令牌又会慢慢积攒,直到5块这个最大限度,如有报文将循环整个过程。
--limit指定多长时间生成一个新令牌(单位有 /second /minute /hour /day ) --limit-burst指定木桶中最多存放几个令牌
iptables -t filter -I INPUT -p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT
iptables -t filter -I INPUT -p icmp -j REJECT
--sport 用于匹配tcp协议报文的源端口; --dport用于匹配tcp协议报文的目标端口
iptables -t filter -I OUTPUT -d 192.168.1.100 -p tcp -m tcp ! --sport 22 -j REJECT
iptables -t filter -I OUTPUT -d 192.168.1.100 -p tcp -m tcp --sport 23:30 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.100 -p tcp -m tcp --sport :22 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.100 -p tcp -m tcp --sport 31: -j REJECT
--tcp-flags匹配报文的tcp头的标志位; --syn匹配tcp新建连接的请求报文,相当于--tcp-flags SYN,RST,ACK,FIN SYN
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECT
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN,ACK -J REJECT
iptables -t filter -I INPUT -p tcp -m tcp --dport 22 --SYN -j REJECT
六、iptables 的黑白名单机制
报文在经过iptables的链时,会匹配其中的规则,匹配则执行对应动作,不匹配则执行链的默认动作,链的默认策略通常设置为ACCEPT或DROP
那么,当链的默认策略设置为ACCEPT时,如果对应链中没有匹配任何规则,就表示接收所有的报文,如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被接受。
同理,当链的默认策略设置为DROP时,如果对应的链中没有配置规则,表示拒绝所有报文,如对应链存在规则,但这些规则没有匹配到报文,报文还是会被拒绝。
所以,当链的默认策略设置为ACCEPT时,我们设置规则时,动作应为DROP或REJECT。因为默认为ACCEPT,如规则动作仍是ACCEPT,那么所有报文全部放行了。所有,当链的默认策略为ACCEPT时,链中的规则对应的动作应该为DROP或者REJECT,表示只有匹配到规则的报文才会被拒绝,没有被规则匹配的报文会被默认接收,这就是黑名单机制。
同理,当链的默认策略为DROP时,链中的规则对应的动作应该为ACCEPT,表示只有匹配到规则的报文才会被放行,没有被规则匹配到的报文会被默认拒绝,这就是 白名单机制。
七、自定义链
iptables -t filter -N IN_WEB #在filter表中创建IN_WEB自定义链
iptables -t filter -I INPUT -p tcp --dport 80 -j IN_WEB #在INPUT链中引用刚才创建的自定义链
iptables -E IN_WEB WEB #将IN_WEB自定义链重命名为WEB
iptables -X WEB #删除引用计数为0并且不包含任何规则的自定义链WEB
八、iptables做软防火墙
#如果想要iptables作为网络防火墙,iptables所在主机开启核心转发功能,以便能够转发报文。
#使用如下命令查看当前主机是否已经开启了核心转发,0表示为开启,1表示已开启
cat /proc/sys/net/ipv4/ip_forward
#使用如下两种方法均可临时开启核心转发,立即生效,但是重启网络配置后会失效。
方法一:echo 1 > /proc/sys/net/ipv4/ip_forward
方法二:sysctl -w net.ipv4.ip_forward=1
#使用如下方法开启核心转发功能,重启网络服务后永久生效。
配置/etc/sysctl.conf文件(centos7中配置/usr/lib/sysctl.d/00-system.conf文件),在配置文件中将 net.ipv4.ip_forward设置为1
#由于iptables此时的角色为"网络防火墙",所以需要在filter表中的FORWARD链中设置规则。
#可以使用"白名单机制",先添加一条默认拒绝的规则,然后再为需要放行的报文设置规则。
#配置规则时需要考虑"方向问题",针对请求报文与回应报文,考虑报文的源地址与目标地址,源端口与目标端口等。
#示例为允许网络内主机访问网络外主机的web服务与sshd服务。
iptables -A FORWARD -j REJECT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -d 10.1.0.0/16 -p tcp --sport 80 -j ACCEPT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -d 10.1.0.0/16 -p tcp --sport 22 -j ACCEPT
#可以使用state扩展模块,对上述规则进行优化,使用如下配置可以省略许多"回应报文放行规则"。
iptables -A FORWARD -j REJECT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s 10.1.0.0/16 -p tcp --dport 22 -j ACCEPT
iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT