iptables#
正常来讲,当数据包到达Linux系统时,都会经过一个防火墙进行基于规则的匹配过滤,决定该数据包继续进行转发还是直接丢弃等。iptables
则负责担任这个防火墙的角色。自顶向下讲,iptables包含了若干个表(如raw
、mangle
、nat
表等等)和若干个chain
(如PREROUTING
、INPUT
等),组成一个2维的关系表:
表/Chain | PREROUTING |
INPUT |
FORWARD |
OUTPUT |
POSTROUTING |
---|---|---|---|---|---|
(路由决策) | ✓ | ||||
raw |
✓ | ✓ | |||
(连接跟踪) | ✓ | ✓ | |||
mangle |
✓ | ✓ | ✓ | ✓ | ✓ |
nat (DNAT) |
✓ | ✓ | |||
(路由决策) | ✓ | ✓ | |||
filter |
✓ | ✓ | ✓ | ||
security |
✓ | ✓ | ✓ | ||
nat (SNAT) |
✓ | ✓ |
不同的chain根据数据包的来源或者去向分别进行匹配过滤,内置的chain包含:
PREROUTING
:传入流量到达本地网络栈时触发(此时还没进行任何路由决策)INPUT
:传入数据包经过路由决策后,目的地址为本机时触发FORWARD
:传入数据包经过路由决策后,目的地址为其他主机时触发OUTPUT
:本地流量进入本地网络栈时触发POSTROUTING
:路由决策后的传出流量或转发流量将数据放置到网线前触发
每个chain则包含若干个表对数据包进行过滤/修改,iptables的表大致可以分为以下几类:
filter
:是否允许数据包继续转发到目的地址(还是丢弃)的表nat
:进行源/目的地址转换(即网络地址转换,NAT)的表,源/目的地址转换分别对应上表的SNAT/DNATmangle
:更改数据包的IP头字段或者标记数据包的表raw
:将每个连接的数据流视为一个个独立数据包并对其进行标记的表(前三个表会受到iptables的连接跟踪机制影响,即只对连接的首个数据包起效)security
:跟SELinux有关,没接触过
因此,传入到本机的流量会依次经过PREROUTING
下的raw
、mangle
、nat
表,然后再经过INPUT
下的mangle
、filter
、security
和nat
表。转发到其他主机的流量则经过PREROUTING
、FORWARD
和POSTROUTING
这3个chain,本地的传出流量则是OUTPUT
再到POSTROUTING
。
每个表可以通过iptables -t <表类型> -L
进行查看,如iptables -t nat -L
,不指定的情况下是filter
表。
iptables
的规则首先进行匹配,匹配成功则执行该规则的动作。匹配的规则是非常灵活的,可以根据协议类型、源/目的地址、连接状态等进行匹配。而动作目标(target
)则是规则触发时所执行的动作,由参数-j
决定,主要有两类目标:终止目标和非终止目标。iptables
会依次执行chain
中的规则,直到遇到终止目标时返回,遇到非终止目标则会继续执行相应的规则(如跳转到某些子chain
进行匹配)。
连接跟踪:将每个packet组成一系列的连接,并对其进行状态跟踪,状态有:
NEW
:首个valid的TCP/UDP packet到达且并未关联任何已有连接ESTABLISHED
:首个valid的反向响应RELATED
:不属于已有连接但与已有连接相关的packet,如FTP协议中除了控制连接外,还有一个传输数据的连接,该连接则属于RELATEDINVALID
:不属于已有连接且不能视为建立连接的packetUNTRACKED
:见下SNAT
、DNAT
:源/目的地址经NAT改变后的虚拟状态
raw
表标记为NOTRACK
会跳过该机制(即状态设为UNTRACKED
)。
另外有一点值得一提的是POSTROUTING
的target MASQUERADE
,本质上相当于一个自动化的SNAT,不需要自己填写外部的IP地址,但相对地,该target则需要指定一个网卡。
iptables的路由决策#
上文提到了iptables的众多功能,但还有一点略过没讲的就是里面的路由决策部分。这一部分不是iptables的工作,而是ip route
的工作(注:route
命令与ip route
相似,但现在更偏向于使用ip route
)。
一般情况下,系统默认会有3个路由表,可以通过ip rule
进行查看:
local
:本机路由和广播的表,本地网络连接的路由将参考这个表main
:用于传输数据的路由表,对应网卡的网络设置default
:默认为空的路由表
每个表中通常会包含若干个路由规则,可以通过ip route [show table <表名或表ID>]
查看,不过这部分没怎么深入了解,以后有时间再看了。
iptables
可以配合路由表一起使用,如在iptables的mangle
表中执行了MARK
的动作时,ip
可以根据该mark执行不同路由表下的路由规则。举个例子:在iptables中设置了iptables -t mangle -A FORWARD -i eth1 -j MARK --set-mark 1
以及在ip中设置了ip rule add fwmark 1 table 10
时,在iptables标记为1的数据包会执行ip中路由表10下的规则。