一、数据包进入流程
iptables利用的是数据包过滤机制(Netfilter),所以它会分析数据包的包头数据。根据包头数据与定义的规则来决定该数据包是否可以进入主机或者是被丢弃。也就是说,根据数据包的分析资料比对预先定义的规则内容,若数据包数据与规则内容相同则进行动作,否则就继续下一条规则的比对。
比如有10条防火墙规则,那么当网络上来了一个数据包想要进入主机,那么防火墙是如何分析这个数据包呢,下面用图来说明一下。
下面是对上图说明:
当一个网络数据包要进入主机之前,会先经过Netfilter进行检查,那就是iptables的规则。检查通过则接受(ACCEPT)进入主机取得资源,如果检查不通过,则可能予以丢弃(DROP)。从上图可以看出规则是有顺序的,网络数据包开始先比对规则01,如果比对结果符合规则01,此时这个网络数据包就会进行Action 1的动作,而不会理会后续的规则02,规则03等规则。如果不符合规则01就会进入规则02做比对,如果比对结果符合规则02,此时这个网络数据包就会进行Action 2的动作。以此类推进行下去。
二、数据包过滤软件iptables的表格(table)与链(chain)
防火墙软件里有多个表格(table),每个表格都定义出自己默认的策略和规则即链(chain),且每个表格的用途都不相同。
默认情况下,Linux的iptables至少有3个表格,包括管理本机进出的filter、管理后端主机(防火墙内部的其他计算机)的NAT、管理特殊标志使用的mangle(较少使用)。iptables的规则表格与相关链关系如下图:
每个表格中链的作用:
- filter表格
Filter(过滤器):主要跟进入本机的数据包有关,是默认的table.
INPUT:与进入linux主机的数据包有关。
OUTPUT:与主机发送的数据包有关。
FORWARD:与主机无关,与传送到后端主机的数据包有关,与NAT的table相关性较高。
- 管理后端主机的NAT表格
NAT(地址转换):是Network Address Translation的缩写,主要用来进行来源与目的IP或port的转换,与本机无关,主要与本机后的局域网内的计算机相关。
PREROUTING:在进行路由判断之前所执行的规则(DNAT/REDIRECT)。
POSTROUTING:在进行路由判断后所执行的规则(SNAT/MASQUERADE)。
OUTPUT:与发送出去的数据包有关。
- 管理特殊标志的Mangle表格
Mangle(破坏者):这个表格主要与特殊的数据包的路由标志有关,早期仅有PREROUTING及OUTPUT链,从kernel 2.4.18之后加入了INPUT及FORWARD链。
如果linux是作为www服务,那么就要放开客户端对www请求有响应,就需要处理filter的INPUT链;如果linux是作为局域网的路由器,那么就要分析NAT的各个链以及filter的FORWARD链。也就是说各个表格与链之间有相关性。iptables内建各表格与链的相关性如下图:
由上图可以看到,iptables可以控制3种数据包的流向,分别为:
第一种:数据包进入linux主机使用资源(路径A):在路由判断后确定是向linux主机请求数据的数据包,主机就会通过Filter的INPUT链来进行控制。
第二种:数据包通过linux主机的传递,没有使用主机资源,而是向后端主机流动(路径B):在路由判断之前进行进行数据包包头的修订后,发现数据包主要是要通过防火墙而去后端,此时数据包就会通过路径B来移动,也就是说,该数据包的目标并非linux本机。主要经过的链是Filter的FORWARD以及NAT的POSTROUTING、PREROUTING。
第三种:数据包由linux本机发送出去(路径C):例如响应客户端的请求,或linux主动送出的数据包,都经过路径C来进行。现实通过路由判断,决定输出路径后,再通过Filter的OUTPUT链来传送。当然最终还会经过NAT的POSTROUTING链。
事实上如果iptables只是用来保护本机的话,根本不需要理会NAT规则,直接设置为开放即可。如果防火墙是用来管理LAN内的其它主机,就必须要对Filter的FORWARD和NAT的PREROUTING、POSTROUTING及OUTPUT进行规则定制。
三、本机的iptables语法
-
3.1本机iptables规则的查看
方法一:
[root@localhost ~]# iptables [-t tables] [-L] [-nv]
选项与参数:
-t: 后面接table,例如nat或filter,若省略此项目,则使用默认的filter
-L: 列出目前的table的规则
-n: 不进行ip与HOSTNAME的反查,现实信息的速度会快很多
-v: 列出更多的信息,包括通过该规则的数据包总位数、相关的网络接口等例如:列出filter table 3条链的规则
[root@localhost ~]# iptables -L -n Chain INPUT (policy ACCEPT) #针对INPUT链,且默认策略为可接受 target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED #第一条规则 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 #第二条规则 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 #第三条规则 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 #第四条规则 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited #第五条规则 Chain FORWARD (policy ACCEPT) #针对 FORWARD链且默认策略可接受 target prot opt source destination REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) #针对 OUTPUT 链,且默认策略为可接受 target prot opt source destination
例如列出nat table 3条链的规则
[root@localhost ~]#iptables -t nat -L -n Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
说明
第一点:在上面的输出中,每一个Chain就是链。Chain那一行括号里面的policy就是默认策略。其它的参数说明如下:
target:代表进行的操作,ACCEPT是放行,而REJECT则是拒绝,此外还有DROP(丢弃)操作
prot:代表使用的数据协议,主要有TCP、UDP及ICMP这3种数据包格式
opt:额外的选项说明
source:代表此规则是针对哪个来源ip进行限制
destination:代表此规则是针对哪个目标ip进行限制第二点:
INPUT的5条规则含义如下:
1.只要是数据包状态为 RELATED,ESTABLISHED 就予以接受
2.只要数据包协议是ICMP类型,就予以放行
3.无论任何来源(0.0.0.0/0)且要去任何目标的数据包,不论任何数据包格式(prot为all) ,一律接受
4.只要是传给port22的主动式连接TCP数据包就接受
5.全部的数据包一律拒绝
从上面五条规则中我们发现第三条和后面的规则冲突(如果第三条都接受,后面的规则就不起作用了),其实这是iptables -L -n命令命令列出的规则中并没有列出接口,很容易搞错。而iptables-save会列出完整的防火墙规则,包括接口。
方法二:
[root@localhost ~]# iptables-save [-t table]
选项与参数:
-t:可以仅针对某些表格来输出,例如仅针对NAT或Filter等[root@localhost ~]# iptables-save *filter <==星号开头的指的是表格 :INPUT ACCEPT [0:0] <==冒号开头的指的是链,3条内建的链 :FORWARD ACCEPT [0:0] <==3条内建链的策略都是ACCEPT :OUTPUT ACCEPT [34327:4310792] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT <==针对INPUT的规则 -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT <==这条很重要,针对本机内部接口开放 -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited <==针对FORWARD的规则 COMMIT
-
3.2本机iptables规则清除
[root@localhost ~]# iptables [-t tables] [-FXZ]
选项与参数:
-F:清除所有的以定制规则
-X:除掉所有用户“自定义”的chain(应该说是tables)
-Z:将所有的chain的计数与流量统计都归零范例:清除本机防火墙(filter)的所有规则
[root@localhost ~]# iptables -F [root@localhost ~]# iptables -X [root@localhost ~]# iptables -Z
以上这三条命令将会清除防火墙规则,但并不会改变默认策略,所以,在执行这三条命令时最好在本机上执行,不然很可能会将自己关在家门外(若INPUT设置为DROP)。
-
3.3定义默认策略
当数据包不再我们设置的规则之内时,该数据包的通过与否,是以Policy的设置为准,通常在本机默认策略中Filter内的INPUT的policy定义为DROP,而FORWARD与OUTPUT默认策略定义为放行(ACCEPT)。
[root@localhost ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
选项与参数:
-P:定义策略(policy)。注意,这个P为大写
ACCEPT:该数据包可接受
DROP:该数据包直接丢弃,不会让client端知道为何被丢弃例如:将本机的INPUT设置为DROP,其它设置为ACCEPT
[root@localhost ~]# iptables -P INPUT DROP [root@localhost ~]# iptables -P OUTPUT ACCEPT [root@localhost ~]# iptables -P FORWARD ACCEPT [root@localhost ~]# iptables-save *filter :INPUT DROP [0:0] #由于INPUT设置为DROP而又尚未有任何规则,所以显示0:0 :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [6:360] COMMIT
NAT table3条链的默认策略设置方法为:
iptables -t nat -P PREROUTING ACCEPT #nat表的PREROUTING链默认策略为接受
-
3.4网络、IP及接口防火墙规则比对设置
语法:
iptables [-AI 链名] [-io 网络接口] [-p 协议] [-s 来源IP/网络] [-d 目标IP/网络] -j [ACCEPT|DROP|REJECT|LOG|SNAT|DNAT|REDIRECT|MASQUERADE]
选项与参数:
-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),REDIRECT重定向、映射、透明代理,MASQUERADE用于 IP伪装(NAT)、用于ADSL,SNAT源地址转换,DNAT目标地址转换`例如:设置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
例如:主机有两张网卡,其中一张是对内部信任的的网络,该网卡的进出数据包都被接受,假设该网卡名为eth1,设置如下:
iptables -A INPUT -i eth1 -j ACCEPT
例如:只要是来自内网(192.168.100.0/24)的数据包就接受
iptables -A INPUT -i eth1 -s 192.168.100.0/24 -j ACCEPT
例如: 如果想要记录某个规则的记录,设置如下
iptables -A INPUT -s 192.168.200.2 -j LOG #这个LOG是只要有数据包来自192.168.200.2这个ip时,那么该 #数据包的相关信息就会被写入到内核日志文件,即/var/log/messages这个文件中,并不影响规则比对。
源地址转换(在nat表上)例:iptables -t nat -A POSTROUTING -s 192.168.0.102 -j SNAT --to-source 192.168.0.1
目标地址转换(在nat表上)例:iptables -t nat -A PREROUTING -d 202.202.202.2 -j DNAT --to-destination 192.168.0.102
目标端口转换(在nat表上)例:iptables -t nat -D PREROUTING -p tcp --dport 8080 -i eth2.2 -j REDIRECT --to 80
目标地址转换一般在PREROUTING链上操作
源地址转换一般在POSTROUTING链上操作
======外网访问内网 –J DNAT=DNAT解释:
only valid in PREROUTING
–to-destination ipaddr[-ipaddr][:port-port]
DNAT:目的网络地址转换,重写包的目的IP地址典型的DNAT的例子
外部接口ip:210.83.2.206
内部接口ip:192.168.1.1ftp服务器 : ip 192.168.1.3
web服务器 : ip 192.168.1.4
iptables -t nat -A PREROUTING -d 210.83.2.206 -p tcp --dport 21 -j DNAT --to 192.168.1.3
iptables -t nat -A PREROUTING -d 210.83.2.206 -p tcp --dport 80 -j DNAT --to 192.168.1.4DNAT 带端口映射(改变SERVER的端口)
一个FTP SERVER从内部192.168.100.125:21映射到216.94.87.37:2121的例子
iptables -t nat -A PREROUTING -p tcp -d 216.94.87.37 --dport 2121 -j DNAT --to-destination 192.168.100.125:21
通常外网DNAT访问内网SERVER,内网SERV ER回包的源地址是经过另一个单独的SNAT进程的。而不属于DNAT STATIC进程的一部分。
这样对于P-t-P的网络应用,就必须另设一个和DNAT相适应的SNAT。
对于穿过NAT,被NAT映射改变端口号的应用,也必须用一个单独的SNAT对回包的端口进行映射
iptables -t nat -A POSTROUTING -p tcp -s 192.168.100.125 --sport 21 -j SNAT --to-source 216.94.87.37:2121
不这样做的话,FTP SERVER会返回21到外网的客户机,外网用户发出一个to 2121的FTP request,收到一个from 21的,会不认 -
3.5 TCP、UDP(针对端口设置)的防火墙规则比对设置
语法:
iptables [-AI 链] [-io 网络接口] [-p tcp、udp] [-s 来源IP/网络] [–sport 端口范围] [-d 目标IP/网络] [–dport 端口范围] -j [ACCEPT|DROP|REJECT]
选项与参数说明:
–sport 端口范围:限制来源的端口号码,端口号码可以是连续的,例如1024:65535
–dport 端口范围:限制目标的端口号码
-P 协议:设定此规则适用于那种数据包格式。主要的数据包格式 有:tcp、udp、icmp及all。
例如:想要连接进入本机port 21 的数据包都阻挡:
iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
例如:想连到本机的网上邻居(upd port 137,138 tcp port 139,445)就放行
iptables -A INPUT -i eth0 -p udp --dport 137:138 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 139 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 445 -j ACCEPT
例如:只要来自192.168.1.0/24的1021:65535端口的数据包,且想要连接到本机的ssh port就予以阻挡
iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 --sport 1024:65535 --dport ssh -j DROP
除了端口以外,TCP数据包还有特殊的标志,例如主动连接的SYN标志。iptables支持-syn处理方式:
例如:将来自任何地方来源port 1:1023的主动连接到本机端的1:1023端口的数据丢弃
iptables -A INPUT -i eth0 -p tcp --sport 1:1023 --dport 1:1023 --syn -j DROP
-
3.6 iptables外挂模块:mac与state
因为数据是双向的,因此我们必须要针对数据包的进、出两个方向进行控制。例如想要连接到远程主机port22端口,就必须设置两条规则
第一条:本机端的1024:65535到远程的port22必须要放行(OUTPUT链)
第二条:远程port22到本机的1024:65535必须放行(INPUT链)
现在iptables可以通过一个状态模块来分析这个想要进入的数据是否为刚刚发出去的响应,如果是刚刚发出的响应那么就予以放行,不需要再设置INPUT链规则。、
语法:
iptables -A INPUT [-m state] [–state 状态]
选项与参数:
-m:一些iptables的外挂模块,主要常见的有:state:状态模块
mac:网卡硬件地址(hardware address)
–state:一些数据包的状态,主要有:
INVALID :无效的数据包,例如数据包破损的数据包状态 ESTABLISHED:已经连接成功的连接状态
NEW :想要新建立连接的数据包状态
RELATED :这个最常用、表示这个数据包是与主机发送出去的数据包有关
例如:只要已建立连接或已发送出请求相关的数据包就予以通过,不合法数据包就丢弃iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -m state --state INVALID -j DROP
iptables还有针对网卡的外挂模块
例如:针对局域网内的aa:bb:cc:dd:ee:ff主机开放其连接iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -j ACCEPT 选项与参数: --mac-source:就是来源主机的MAC
-
3.7 ICMP数据包的iptables比对规则
ICMP数据包大多是用来网络检测的。
语法:
iptables -A INPUT [-p icmp] [–icmp-type 类型] -j ACCEPT
参数:
–icmp-type:后面必须接ICMP的数据包类型,可以使用代号。例如8 代表echo request 的意思
例如:让0,3,4,11,12,14,16,18的ICMP TYPE可以进入本机vi somefile.sh #!/bin/bash icmp_type="0 3 4 11 12 14 16 18" for typeicmp in $icmp_type do iptables -A INPUT -i eth0 -p icmp --icmp-type $typeicmp -j ACCEPT done