Netfilter是Linux内核提供的一套完善的数据包处理框架,通过一整套的钩子(hook)管理机制,可以实现数据包过滤、网络地址转换以及基于协议类型的连接跟踪等功能,Iptables是基于Netfilter的数据包过滤系统,通过自己设定的规则以及处理动作对数据报文进行检测和处理。

Iptables分为内核模块和用户态两部分,用户空间的Iptables位于/sbin/目录下,是用于设置规则的命令行工具,通过命令行制定相应的规则,指定内核模块进行相应的数据访问控制。链、表和规则是Iptables内核处理中非常重要的几个概念。

链也可以称为钩子,是指Iptables过滤的时机。Iptables当前有PREROUTING、INPUT、FORWARD、OUTPUT和POSTROUTE 5种链,其中PREROUTING用于在路由选择前处理数据包,POSTROUTE用于在路由选择后处理数据包,INPUT用于处理发送到本机的数据包,OUTPUT负责处理本机发送出去的数据包,FORWARD负责对转发数据包进行处理。

针对不同的数据流,有如下3种典型的链处理时机。

1)发送给本机的数据包:当数据包从物理层和数据链路层传输过来,如果数据包是访问Linux主机本身,则经过PREROUTING和INPUT钩子函数,到达传输层和应用层。

2)转发数据包:数据包从物理层和数据链路层传输过来,如果数据包需要转发,则经过PREROUTING、FORWARD和POSTROUTE 3个钩子函数。

3)发送数据包:当数据包从Linux主机本身向外发送数据包,要经过OUTPUT和POSTROUTE两个钩子函数。

表是负责完成某个过滤功能的模块,Iptables当前有Filter表、NAT表、mangle表和raw表4个,它们在内核中对应4个不同的模块,这几个模块对应的功能和包含的钩子函数如下。

1)Filter表:Filter表是Iptables默认的过滤功能,确定是否放行数据包,包含INPUT、FORWAD和OUTPUT 3个钩子函数。

2)NAT表:NAT表负责修改数据包的源IPPORT和目的IPPORT,包含PREROUTING、OUTPUT和POSTROUTE这几个钩子函数。

3)mangle表:mangle表用于对连接进行跟踪,包含PREROUTING、INPUT、FORWARD、OUTPUT和POSTROUTE 5个钩子函数。

4)raw表:raw表用于关闭NAT表上开启的连接跟踪功能,包含PREROUTING、OUTPUT 2个钩子函数。

综合来说,Iptables、表、链和规则之间是层层包含的关系,Iptables可以包含多个表,每个表包含多个链,每个链包含多个用于过滤的规则。

  1. Iptables在Istio中的使用

Iptables负责对Envoy的入口和出口流量进行拦截。针对入口流量拦截,假设所有的流量均需要定向到Envoy代理,8090是Envoy的监听端口,Iptables规则如下:

iptables -t nat -A PREROUTING -p tcp -j REDIRECT -to-port 8090

针对出口流量拦截,也是类似的思路,Iptables规则如下:

iptables -t nat -A OUTPUT -p tcp -j REDIRECT -to-port 8090

通过Iptables拦截转发后,目标端口被改写了,可以通过SO_ORIGINAL_DST TCP套接字获取原始的ipport。