4

logo

报文过滤连接跟踪可以说是Netfilter提供的两大基本功能。前者被大多数人熟知,因为我们对防火墙的第一印象就是可以阻止有害的报文伤害计算机;而后者就没这么有名了,很多人甚至不知道Netfilter有这项功能。

Why 使用连接跟踪

顾名思义,连接跟踪是保存连接状态的一种机制。为什么要保存连接状态呢? 举个例子,当你通过浏览器访问一个网站(连接网站的80端口)时,预期会收到服务器发送的源端口为80的报文回应,防火墙自然应该放行这些回应报文。那是不是所有源端口为80端口的报文都应该放行呢?显然不是,我们只应该放行源IP为服务器地址,源端口为80的报文,而应该阻止源地址不符的报文,即使它的源端口也是80。总结一下这种情况就是,我们只应该让主动发起的连接产生的双向报文通过

NAT

另一个例子是NAT。我们可以使用iptables配置nat表进行地址或者端口转换的规则。如果每一个报文都去查询规则,这样效率太低了,因为同一个连接的转换方式是不变的!连接跟踪提供了一种缓存解决方案:当一条连接的第一个数据包通过时查询nat表时,连接跟踪将转换方法保存下来,后续的报文只需要根据连接跟踪里保存的转换方法就可以了。

连接跟踪发生在哪里

Connection tracking hooks into high-priority NF_IP_LOCAL_OUT and NF_IP_PRE_ROUTING hooks, in order to see packets before they enter the system.

连接跟踪需要拿到报文的第一手资料,因此它们的入口是以高优先级存在于LOCAL_OUT(本机发送)和PRE_ROUTING(报文接收)这两个链。

既然有入口,自然就有出口。连接跟踪采用的方案是在入口记录,在出口确认(confirm)。以IPv4为例:

arch

当连接的第一个skb通过入口时,连接跟踪会将连接跟踪信息保存在skb->nfctinfo,而在出口处,连接跟踪会从skb上取下连接跟踪信息,保存在自己的hash表中。当然,如果这个数据包在中途其他HOOK点被丢弃了,也就不存在最后的confirm过程了。

连接跟踪信息是什么

连接跟踪信息会在入口处进行计算,保存在skb上,信息具体包括tuple信息(地址、端口、协议号等)、扩展信息以及各协议的私有信息。

struct

  • tuple信息包括发送和接收两个方向,对TCPUDP来说,是IPPort;对ICMP来说是IPTypeCode,等等;
  • 扩展信息比较复杂,本文暂时略过;
  • 各协议的私有信息,比如对TCP就是序号、重传次数、缩放因子等。

报文的连接跟踪状态

途径Netfilter框架的每一个报文总是会在入口处(PRE ROUTING或者LOCAL OUT)被赋予一个连接跟踪状态。这个状态存储在skb->nfctinfo,有以下常见的取值:

  • IP_CT_ESTABLISHED:这是一个属于已经建立连接的报文,Netfilter目击过两个方向都互通过报文了
  • IP_CT_RELATED:这个状态的报文所处的连接与另一个IP_CT_ESTABLISHED状态的连接是有联系的。比如典型的ftpftp-data的连接就是ftp-control派生出来的,它就是RELATED状态
  • IP_CT_NEW:这是连接的第一个包,常见的就是TCP中的SYN包,UDPICMP中第一个包,
  • IP_CT_ESTABLISHED + IP_CT_IS_REPLY:与IP_CT_ESTABLISHED类似,但是是在回复方向
  • IP_CT_RELATED + IP_CT_IS_REPLY:与IP_CT_RELATED类似,但是是在回复方向

总结

  • 连接跟踪Netfilter提供的一项基本功能,它可以保存连接的状态。用户可以为不同状态的连接的报文制定不同的策略;
  • 连接跟踪在报文进入Netfilter入口将信息记录在报文上,在出口进行confirm.确认后的连接信息可以影响之后的报文;
  • 连接跟踪的信息主要包括基本的描述连接的tuple以及各协议的私有信息。

187J3X1
1.9k 声望1.2k 粉丝

主页 switch-router.gitee.io 欢迎:)