本文参考、整理自:
《云原生服务网格Istio原理、实践、架构与源码解析》https://book.douban.com/subject/34438220/
朱双印个人日志:iptables详解系列 http://www.zsythink.net/archives/tag/iptables/
iptables的基本原理
概念
我们通常所说的iptables严格来讲应该叫做Netfilter,Netfilter是一种内核防火墙框架,可以实现很多网络安全策略,包括数据包过滤、数据包处理、地址伪装、透明代理、网络地址转换等。iptables则是一个应用层的二进制工具,可以基于Netfilter接口设置内核中的Netfilter配置表。
iptables由表及构成表的链组成,每条链又由具体的规则组成。iptables内置4张表和5条链,4张表分别是RAW、Mangle、NAT、Filter表,5条链又叫作数据包的5个挂载点(Hook Point,可以理解为回调函数点,在数据包到达这些位置时,内核回主动调用回调函数,使得数据包在路由时可以改变方向或内容),分别是PREROUTING、INPUT、OUTPUT、FORWORD和POSTROUTING。对于不同表中相同类型的规则执行顺序,iptabels定义了优先级,该优先级由高到低排序为raw、managle、nat、filter。例如,对于PREROUTING链来说,首先执行raw表的规则,然后执行mangle表的规则,最后执行nat表的规则。
iptables的表和链
Filter表表示iptables的默认表,如果在创建规则时未指定表,那么默认使用Filter表,主要用于数据包过滤,根据具体规则决定是否放行该数据包(DROP、ACCEPT、REJECT、LOG等)。
Filter表包含如下三种内建链:
- INPUT链:过滤目的地址是本机的所有数据包
- OUTPUT链:过滤本机产生的所有数据包
- FORWARD链:过滤经过本机的所有数据包(源地址和目的地址都不是本机)
NAT表主要用于修改数据包的IP地址、端口号等信息,包含以下三种内建链
- PREROUTING链:DNAT,处理刚到达本机并在路由转发前转换数据包的目的地址
- POSTROUTING链:SNAT,处理即将离开本机的数据包,转换数据包的源地址
- OUTPUT链:MASQUERADE,改变本机产生的数据包的源地址
主要用于修改数据包的TOS、TTL,以及为数据包设置Mark标记,以实现QoS调整及策略路由等。它包含所有5条内置规则链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWORD。
RAW表是iptables在1.2.9版本之后新增的表,主要用于决定数据包是否被状态跟踪机制处理。RAW表的优先级要优于其他表,包含两条规则链:OUTPUT和PREROUTING。
iptables原理图

上图展示了iptables规则链处理数据包的顺序,网卡接收的数据包会进入内核协议栈被PREROUTING规则链处理(可能发生数据包的目的地址转换),之后由内核协议栈进行路由选择,如果数据包的目的地址是本机,则内核协议栈会将其传给INPUT链处理,INPUT链在允许通过后,数据包由内核空间进入用户空间,被主机进程处理;如果PREROUTING链处理后的数据报的目的地址不是本机地址,则将其传给FORWARD链进行处理,最后交给POSTROUTING链。本机进程发出的数据包首先进行路由选择,经过OUTPUT链后,到达POSTROUTING链(可能发生数据包的源地址转换)。
iptables的基本使用
规则查询
1 | [root@localhost ~]# iptables --line-number -t filter -nvxL INPUT |
规则管理
1 | [root@localhost ~]# iptables -t filter -I INPUT -s 192.168.1.146 -j REJECT |
规则匹配条件
基本匹配条件
源IP/目的IP地址
1 | 指定单个地址 |
假设在空的INPUT链中添加如下规则:
iptables -t filter -I INPUT ! -s 192.168.4.129 -j DROP那么当IP为192.168.4.129的主机ping本机时,首先对比源IP和规则中的IP,发现不符合规则的匹配条件,会进入INPUT链的默认处理策略,即ACCEPT,因此IP为192.168.4.129的主机可以收到ICMP响应包。
协议类型
1 | iptables -t filter -I INPUT -s 192.168.4.129 -p tcp -j REJECT |
网卡接口
1 | iptables -t filter -I INPUT -i eth0 -j REJECT |
扩展匹配条件
上面讲的都是iptabls的基本匹配条件,端口号属于扩展匹配条件。对于基本匹配条件,如果需要使用扩展匹配条件,则需要一些扩展模块的支持。
tcp扩展
1 | 端口号 |
udp扩展
1 | iptables -t filter -I INPUT -p udp -m udp --dport 137 -j REJECT |
icmp扩展
1 | iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECT |
iprange扩展
1 | iptables -t filter -I INPUT -m iprange --src-range 192.168.4.127-192.168.4.131 -j REJECT |
string扩展
1 | iptables -t filter -I INPUT -m string --algo bm --string "OOXX" -j REJCET |
time扩展
1 | iptables -t filter -I INPUT -m time --timestart 09:00:00 --timestop 11:00:00 --weekdays 1,2,3,4,5 --monthdays 22,23,24 --datestart 2020-07-01 --datestop 2020-09-01 -j REJCET |
connlimit扩展
1 | iptables -t filter -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 --connlimit-mask 24 -j REJECT |
limit扩展
1 | 假设现在要设置这样一条规则:每6s响应1次(1min响应10次)icmp报文 |
令牌桶算法
有一个木桶,木桶里面放了5块令牌(–limit-burst),所有报文如果想要出关入关,都必须要持有木桶中的令牌才行,这个木桶每隔6秒钟会生成一块新的令牌。如果木桶中的令牌不足5块,新生成的令牌会被放入木桶中,否则令牌被丢弃。如果此时有5个报文想要入关,恰好这5个报文能在木桶里找到一人一个令牌,于是报文被放行;此时木桶中已经没有令牌可以使用了,因此剩余的报文被拒绝。但每6秒钟,会生成新的令牌,新的报文获取到该令牌后,再此被放行。令牌可积累,但木桶最多能存放的令牌数只有5个。
规则动作
规则动作也包括基础动作与扩展动作,与扩展匹配条件不同,扩展动作可以直接使用,而不需要指定特定模块。
基础动作
ACCEPT
DROP
扩展动作
REJECT
1 | iptables -t filter -I INPUT -p tcp --dport 22 -j REJECT --reject-with icmp-host-unreachable |
LOG
1 | iptables -t filter - I INPUT -p tcp --dport 22 -j LOG --log-level info --log-prefix "log in from port 22" |
NAT
网络地址转换
假设网络内部有10台主机,它们有各自的IP地址,当网络内部的主机与其他网络中的主机通讯时,则会暴露自己的IP地址,如果我们想要隐藏这些主机的IP地址,该怎么办呢?
当网络内部的主机向网络外部主机发送报文时,报文会经过防火墙或路由器,当报文经过防火墙或路由器时,将报文的源IP修改为防火墙或者路由器的IP地址,当其他网络中的主机收到这些报文时,显示的源IP地址则是路由器或者防火墙的,而不是那10台主机的IP地址,这样,就起到隐藏网络内部主机IP的作用,当网络内部主机的报文经过路由器时,路由器会维护一张NAT表,表中记录了报文来自于哪个内部主机的哪个进程(内部主机IP+端口),当报文经过路由器时,路由器会将报文的内部主机源IP替换为路由器的IP地址,把源端口也映射为某个端口,NAT表会把这种对应关系记录下来。
示意关系如下:
于是,外部主机收到报文时,源IP与源端口显示的都是路由的IP与端口,当外部网络中的主机进行回应时,外部主机将响应报文发送给路由器,路由器根据刚才NAT表中的映射记录,将响应报文中的目标IP与目标端口再改为内部主机的IP与端口号,然后再将响应报文发送给内部网络中的主机。整个过程中,外部主机都不知道内部主机的IP地址,内部主机还能与外部主机通讯,于是起到了隐藏网络内主机IP的作用。
内部网络的报文发送出去时,报文的源IP会被修改,也就是源地址转换:Source Network Address Translation,缩写为SNAT。
外部网络的报文响应时,响应报文的目标IP会再次被修改,也就是目标地址转换:Destinationnetwork address translation,缩写为DNAT。
1 | iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source public-IP |
MASQUERADE
1 | iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE |
REDIRECT
1 | iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 |
自定义链
当iptables链中的规则很多时,非常难以管理,比如在大量的规则中有些是针对httpd服务的,有些是针对sshd服务的,有针对私网IP的,有针对公网IP的。如果修改一条规则需要查看其他所有规则的话,将会大大降低效率,因此iptables提供了自定义链的能力。但自定义链并不能直接使用,而是需要被默认链引用才能够使用。
1 | 在filter表中创建IN_WEB自定义链 |
