Netfilter-是如何工作的五初识连接跟踪connection-track

53次阅读

共计 1653 个字符,预计需要花费 5 分钟才能阅读完成。

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

Why 使用连接跟踪

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

另一个例子是 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 为例:

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

连接跟踪信息是什么

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

  • 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 以及各协议的私有信息。
正文完
 0