数据包进入流程:规则顺序的重要性
iptables利用的是数据包过滤机制,所以它会分析数据包的包头数据。根据包头数据与定义的规则来决定该数据包是否可以进入主机或者是被丢弃。也就是说,根据数据包的分析资料“比对”预先定义的规则内容,若数据包数据与规则内容相同则进行动作,否则就继续下一条规则的比对。重点在比对与分析顺序。
例子:假设预先定义了10条防火墙规则,当internet来了一个数据包想要进入主机时,防火墙如下图所示对这个数据包进行分析。
数据包过滤的规则操作及分析流程
当一个网络数据包要进入到主机之前,会先经过Netfilter进行检查,就是iptables的规则。检查通过则接受(ACCEPT)进入本机取得资源,不通过则丢弃(DROOP)。从上图就可看出:规则是有顺序的。例如,当网络数据包开始Rule 1的比对时,如果比对结果符合Rule 1,此时这个网络数据包就会进行Action 1的动作,而不会理会后续的Rult 2、Rule 3 等规则了。而如果这个数据包并不符合Rule 1的比对,那就会进入Rule 2的比对了。如此一个一个规则比对下去。那如果所有的规则都不符合就会通过默认操作(数据包策略,policy)来决定这个数据包的去向。所以,当规则顺序排列错误时,就会产生很严重的错误。
iptables的表格(table)与链(chain)
在iptables中至少有三个表格,管理后端主机(防火墙内部的其他计算机)的NAT、管理特殊标志使用的Mangle(较少使用)、管理本机数据包进出的Filter。
iptables的表格与相关链示意图
每个表格中链的作用:
Filter(过滤器):主要跟进入本机的数据包有关,是默认的table.
INPUT:与进入linux主机的数据包有关。
OUTPUT:与主机发送的数据包有关。
FORWARD:与主机无关,与传送到后端主机的数据包有关,与NAT的table相关性较高。
NAT(地址转换):是Network Address Translation的缩写,主要用来进行来源与目的IP或port的转换,与本机无关,主要与本机后的局域网内的计算机相关。
PREROUTING:在进行路由判断之前所执行的规则(DNAT/REDIRECT)。
POSTROUTING:在进行路由判断后所执行的规则(SNAT/MASQUERADE)。
OUTPUT:与发送出去的数据包有关。
Mangle(破坏者):这个表格主要与特殊的数据包的路由标志有关,早期仅有PREROUTING及OUTPUT链,从kernel 2.4.18之后加入了INPUT及FORWARD链。
iptables内建各表格与链的相关性
iptables可以控制三种数据包的流向:
数据包进入linux主机使用资源(路径A):在路由判断后确定是向linux主机请求数据的数据包,主机就会通过Filter的INPUT链来进行控制。
数据包通过linux主机的传递,没有使用主机资源,而是向后端主机流动(路径B):在路由判断之前进行进行数据包包头的修订后,发现数据包主要是要通过防火墙而去后端,此时数据包就会通过路径B来移动,也就是说,该数据包的目标并非linux本机。主要经过的链是Filter的FORWARD以及NAT的POSTROUTING、PREROUTING。
数据包由linux本机发送出去(路径C):例如响应客户端的请求,或linux主动送出的数据包,都经过路径C来进行。现实通过路由判断,决定输出路径后,再通过Filter的OUTPUT链来传送。当然最终还会经过NAT的POSTROUTING链。
iptables内建各表格与链的相关性(简图)
如果iptables只是用来保护本机的话,根本不需要理会NAT规则,直接设置为开放即可。如果防火墙是用来管理LAN内的其他主机,就必须要对Filter的FORWARD和NAT的PREROUTING、POSTROUTING及OUTPUT进行规则定制。
本机的iptables语法
规则的查看与清除
防火墙的设置主要是iptables命令,以下是iptables命令的介绍:
1 [root@localhost ~]# iptables [-t tables] [-L] [-nv] 2 选项与参数: 3 -t: 后面接table,例如nat或filter,若省略此项目,则使用默认的filter 4 -L: 列出目前的table的规则 5 -n: 不进行ip与HOSTNAME的反查,现实信息的速度会快很多 6 -v: 列出更多的信息,包括通过该规则的数据包总位数、相关的网络接口等 7 8 范例:列出filter table 3条链的规则 9 [root@localhost ~]# iptables -L -n 10 Chain INPUT (policy ACCEPT) 11 target prot opt source destination 12 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 13 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 14 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 15 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 16 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited 17 18 Chain FORWARD (policy ACCEPT) 19 target prot opt source destination 20 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited 21 22 Chain OUTPUT (policy ACCEPT) 23 target prot opt source destination
在上面的输出中,每个Chain就是每条链,后面括号中的policy指的是这条链默认的策略,下面的target、prot、opt、source、destination分别代表:
target:代表进行的操作,ACCEPT是放行,REJECT则是拒绝,DROP丢弃。
prot:代表使用的数据包协议,主要有TCP、UDP、ICMP 3中数据包格式。
opt:额外的选项说明。
source:代表此规则是针对哪个来源IP进行限制。
destination:代表此规则是针对哪个目标IP进行限制。
在上面使用iptables -L命令列出的规则中并没有列出接口,很容易搞错。所以,可以使用iptables-save命令来查看防火墙的规则。iptables-save会列出完整的防火墙规则,但并没有格式化输出:
1 [root@localhost ~]# iptables-save [-t table] 2 选项与参数: 3 -t:可以仅针对某些表格来输出,例如仅针对NAT或Filter等 4 5 [root@localhost ~]# iptables-save 6 # Generated by iptables-save v1.4.21 on Tue Dec 30 20:42:29 2014 7 *filter <==星号开头的指的是表格 9 :INPUT ACCEPT [0:0] <==冒号开头的指的是链,3条内建的链 11 :FORWARD ACCEPT [0:0] <==3条内建链的策略都是ACCEPT 13 :OUTPUT ACCEPT [34327:4310792] 14 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT <==针对INPUT的规则 15 -A INPUT -p icmp -j ACCEPT 16 -A INPUT -i lo -j ACCEPT <==针对本机内部接口开放 18 -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT 19 -A INPUT -j REJECT --reject-with icmp-host-prohibited 20 -A FORWARD -j REJECT --reject-with icmp-host-prohibited <==针对FORWARD的规则 21 COMMIT 22 # Completed on Tue Dec 30 20:42:29 2014
清除规则
1 [root@localhost ~]# iptables [-t tables] [-FXZ] 3 选项与参数: 5 -F:清除所有的以定制规则 7 -X:除掉所有用户“自定义”的chain(应该说是tables) 9 -Z:将所有的chain的计数与流量统计都归零 10 11 范例:清除本机防火墙(filter)的所有规则 13 [root@localhost ~]# iptables -F 15 [root@localhost ~]# iptables -X 17 [root@localhost ~]# iptables -Z
以上这三条命令将会清除防火墙规则,但并不会改变默认策略,所以,在执行这三条命令时最好在本机上执行,不然很可能会将自己关在家门外(若INPUT设置为DROP)。
定义默认策略(policy)
当数据包不再我们设置的规则之内时,该数据包的通过与否,是以Policy的设置为准,在本机的默认策略中,假设对内部的用户有信心,那么Filter内的INPUT链方面可以定义的比较严格一点,而FORWARD与OUTPUT则可以制定的松一些。通常都是将INPUT的policy定义为DROP,其他两个则定义为ACCEPT。至于NAT table则暂时不理会。
1 [root@localhost ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP] 2 选项与参数: 4 -P:定义策略(policy)。注意,这个P为大写 6 ACCEPT:该数据包可接受 8 DROP:该数据包直接丢弃,不会让client端知道为何被丢弃 10 11 范例:将本机的INPUT设置为DROP,其它设置为ACCEPT 12 [root@localhost ~]# iptables -P INPUT DROP 14 [root@localhost ~]# iptables -P OUTPUT ACCEPT 16 [root@localhost ~]# iptables -P FORWARD ACCEPT 18 [root@localhost ~]# iptables-save 20 # Generated by iptables-save v1.4.21 on Tue Dec 30 21:19:48 2014 22 *filter 24 :INPUT DROP [6:851] 26 :FORWARD ACCEPT [0:0] 28 :OUTPUT ACCEPT [6:360] 30 COMMIT 33 # Completed on Tue Dec 30 21:19:48 2014
数据包的基础对比:IP、网络及接口设备
[root@localhost ~]# iptables [-AI 链名] [-io 网络接口] [-p 协议] [-s 来源IP/网络] [-d 目标IP/网络] -j [ACCEPT|DROP|REJECT|LOG]
选项与参数: -AI 链名: 这对某条链进行规则的“插入”或“累加“ -A:新增加一条规则,该规则增加在元规则的最后面。例如原来已经有四条规则,使用-A就可以加上第五条规则 -I:插入一条规则。如果没有指定此规则的顺序,默认是插入变成第一条规则。例如原本有四条规则,使用-I则该规则变成第一条,而原本4条变成第2~5条 链:有INPUT、OUTPUT、FORWARD等,此链名称又与-io有关,请看下面 -io 网络接口:设置数据包进出的接口规范 -i:数据包所进入的哪个网络接口,例如eth0、lo等接口。需与INPUT链配合 -o:数据包所传出的那个网络接口,需与OUTPUT链配合 -P 协议:设定此规则适用于那种数据包格式。主要的数据包格式有:tcp、udp、icmp及all。 -s 来源IP/网络:设置此规则之数据包的来源地,可指定单纯的IP或网络,例如:IP : 192.168.0.100,网络: 192.168.0.0/24 、192.168.0.0/255.255.255.0均可。
若规范为”不许“加上”!“即可,例如:-s ! 192.168.100.0/24 表示不接受192.168.100.0/24发来的数据包; -d 目标IP/网络:同-s,只不过这里指的是目标IP或网络。 -j 后面接操作,主要的操作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG)。 范例:设置lo成为受信任的设备,亦即出进lo的数据包都予以接受 [root@localhost ~]# iptables -A INPUT -i lo -j ACCEPT 范例:只要是来自192.168.100.10就接受, [root@localhost ~]# iptables -A INPUT -i eth1 -s 192.168.100.10 -j ACCEPT
TCP、UDP的规则比对:针对端口设置
[root@localhost ~]# iptables [-AI 链] [-io 网络接口] [-p tcp、udp] [-s 来源IP/网络] [--sport 端口范围] [-d 目标IP/网络] [--dport 端口范围] \
-j [ACCEPT|DROP|REJECT] 选项与参数: --sport 端口范围:限制来源的端口号码,端口号码可以是连续的,例如1024:65535 --dport 端口范围:限制目标的端口号码 范例:想要连接进入本机port 21 的数据包都阻挡: [root@localhost ~]# iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
范例:想连到本机的网上邻居(upd port 137,138 tcp port 139,445)就放行
[root@localhost ~]# iptables -A INPUT -i eth0 -p udp --dport 137:138 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -i eth0 -p udp --dport 139 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -i eth0 -p udp --dport 445 -j ACCEPT
iptables外挂模块:mac与state
[root@localhost ~]# iptables -A INPUT [-m state] [--state 状态]
选项与参数:
-m:一些iptables的外挂模块,主要常见的有:
state:状态模块
mac:网卡硬件地址(hardware address)
--state:一些数据包的状态,主要有:
INVALID :无效的数据包,例如数据包破损的数据包状态
ESTABLISHED:已经连接成功的连接状态
NEW :想要新建立连接的数据包状态 RELATED :这个最常用、表示这个数据包是与主机发送出去的数据包有关
范例:只要已建立连接或已发送出请求相关的数据包就予以通过,不合法数据包就丢弃
[root@localhost ~]# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
[root@localhost ~]# iptables -A INPUT -m state --state INVALID -j DROP
范例:针对局域网内的aa:bb:cc:dd:ee:ff主机开放其连接 [root@localhost ~]# iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -j ACCEPT 选项与参数: --mac-source:就是来源主机的MAC
注意:设置完后要执行service iptables save命令保存,并重启iptables后生效。