iptables是一个在Linux操作系统上使用的防火墙工具,它可以用于配置和管理网络数据包的过滤、转发和修改等操作。
Netfilter是Linux内核中的一个网络数据包过滤框架,它可以在数据包进入和离开网络接口时进行拦截和处理。iptables就是基于Netfilter框架实现的一个用户空间工具,它可以通过调用Netfilter提供的API来实现网络数据包的过滤、转发和修改等操作。
netfilter的架构就是在整个网络流程的若干位置放置一些钩子,并在每个钩子上挂载一些处理函数进行处理。
IP层的5个钩子点的位置,分别是PREROUTING、POSTROUTING、INPUT、OUTPUT和FORWARD。原理图如下:
当网卡上收到一个包送达协议栈时,最先经过的netfilter钩子是PREROUTING,如果确实有用户埋了这个钩子函数,那么内核将在这里对数据包进行目的地址转换(DNAT)。不管在PREROUTING有没有做过DNAT,内核都会通过查本地路由表决定这个数据包是发送给本地进程还是发送给其他机器。如果是发送给其他机器(或其他network namespace),就相当于把本地当作路由器,就会经过netfilter的FORWARD钩子,用户可以在此处设置包过滤钩子函数,例如iptables的reject函数。所有马上要发到协议栈外的包都会经过POSTROUTING钩子,用户可以在这里埋下源地址转换(SNAT)或源地址伪装(Masquerade,简称Masq)的钩子函数。如果经过上面的路由决策,内核决定把包发给本地进程,就会经过INPUT钩子。本地进程收到数据包后,回程报文会先经过OUTPUT钩子,然后经过一次路由决策(例如,决定从机器的哪块网卡出去,下一跳地址是多少等),最后出协议栈的网络包同样会经过POSTROUTING钩子。
iptables的底层实现是通过Linux内核中的Netfilter框架来实现的。iptables是用户空间的一个程序,通过netlink和内核的netfilter框架打交道,负责往钩子上配置回调函数。
iptables有5条内置链分别对应着netfilter的5个钩子:
除了5条内置链之外,还可以在表中定义自己的链:
这5张表的优先级从高到低是:raw、mangle、nat、filter、security。
iptables表与链的对应关系图如下:
不同的表挂不同的链,这是为了分类管理iptables规则(rule)的,系统所有的iptables规则都被划分到不同的表集合中。
iptables的规则就是挂载netfilter钩子上的函数,用来修改数据包的内容或者过滤数据包等操作,iptables的表就是所有规则的5个逻辑集合。
iptables规则如何编写?
一条iptables规则包含两部分信息:匹配条件和动作。
匹配条件即为匹配数据包被这条iptables规则“捕获”的条件,例如协议类型、源IP、目的IP、源端口、目的端口、连接状态等。每条iptables规则允许多个匹配条件任意组合,从而实现多条件的匹配,多条件之间是逻辑与(&&)关系。
常见动作如下:
iptables -L -n
iptables -A INPUT -s 10.20.30.40/24 -p tcp --dport 22 -j ACCECT
-A INPUT
是以追加的方式增加该规则在INPUT链上,-s 10.20.30.40/24 -p tcp --dport 22
是匹配上源地址为10.20.30.40/24网段,tcp协议和目的端口22的数据包,-j ACCET
表示允许该数据包进行连接。这里没有指定表默认是filter表。
iptables -A INPUT -s 10.10.10.10 -j DROP
-j DROP
会发送给源地址为10.10.10.10一个连接拒绝的回程报文。
iptables -A OUTPUT -p tcp --dport 1234 -j DROP
禁止本地进程访问外部1234端口。因为是在挂载OUTPUT链上该条规则,所以是屏蔽本地进程对外的连接。如果想要禁止外部连接访问本地1234端口,则需要在INPUT链上新增规则。
iptables -A INPUT -p tcp --dport 1234 -j DROP
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
该条规则添加到PREROUTING链下的nat表中,匹配上eth0网卡上所有目的端口为80的tcp数据包,匹配上则将转发到8080端口上。因为将目的端口改变了,则需要写到nat表中。
iptables -A INPUT -p icmp -j DROP
在INPUT链filter表中新增禁止icmp协议数据包的规则。
iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to-destination 10.20.30.40:8080
和端口转发原理差不多,区别在于,端口转发不修改IP地址,而这里修改了目的IP地址。在nat表PREROUTING中新增目的地址为1.2.3.4,目的端口80的tcp数据包的DNAT动作,将目的地址改为了10.20.30.40:8080。
DNAT仅发生在nat表的PREROUTING链中,并且该操作需要确保开启ipforward功能。
iptables -t nat -A POSTROUTING -s 192.168.1.2 -j SNAT --to-source 10.172.16.1
在nat表POSTROUTING链中新增将源地址192.168.1.2的数据包进行SNAT操作,改为源地址10.172.16.1.
SNAT操作仅可发生在nat表的POSTROUTING链中。
iptables规则修改仅是临时的,重启则丢失,执行以下命令永久保存。
iptables-save
也可将规则保存在文件中
iptables-save > iptables.bak
后续可以通过以下命令进行恢复
iptables-restore < iptables.bak