iptable 的 conntrack 模块什么时候跟踪数据包的状态?

cav*_*man 3 linux iptables conntrack

它首先需要存储状态。我使用的一些旧的BSD防火墙,我猜是命名为IPFW,我曾经放置了一个满足“跟踪离开数据包的状态”的规则,并将其放置在接口的出站方向上。然后,入站方向上的另一个规则根据出站方向上的规则创建的那些状态检查它们。所以过去有 2 个规则:(1) 填充状态表,这是在出站方向,以及 (2) 查找状态表,这是在入站方向。

但是使用connntrack,我看到它应用在INPUT链上,比如这个规则:

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

这让我想知道,该声明实际上在做什么?

  • 是说它将通过将信息放入状态表来开始跟踪匹配该规则的数据包吗?
  • 还是说它已经拥有状态信息,并且将根据它对入站消息采取行动?(例如,如果它们属于以前接受的连接,则接受?)。但是,在这种情况下,states 表在哪里填充?哪个规则?或者它是无规则和隐含的?

A.B*_*A.B 7

Netfilter 和 conntrack 的介绍性介绍

首先是关于 Netfilter 和通用网络中的数据包流的强制性示意图:

Netfilter 和通用网络中的数据包流

Netfilter 是包过滤框架,将自身插入网络堆栈的其余部分(由“路由决策”和其他白色圆边框部分表示)。Netfilter 为其他子系统和“客户端”提供钩子和 API。其中包括conntrack(连接跟踪器)和iptables(或nftables)。Netfilter 和conntrack之间的分离非常模糊。您可以将conntrack视为 Netfilter 的一个集成部分。

在描述数据包遍历的各个步骤的示意图中,您可以看到在某个点(在 raw/PREROUTING 和 mangle/PREROUTING 之间,或在 raw/OUTPUT 和 mangle/OUTPUT 之间)数据包遍历conntrack

此时,conntrack将在自己的查找表(保存在内核内存中的小型查找数据库)中进行搜索:

  • 如果未找到此数据包的特征(并且未在原始表中声明为 UNTRACKED),则新的 conntrack 双向元组条目(协议,然后是特定的族和协议信息:初始源和端口、初始目标和端口、回复源和端口,回复目的地和端口(最后这两个通常是相反的,除非涉及 NAT 或一些奇怪的协议,如回声回复匹配 ICMP 的回声请求))描述流的创建状态为 NEW。
  • 如果它匹配(在任何方向)前一个条目并且与此流的状态兼容,则流状态可能会改变(例如:如果以前不是这种情况,则从 NEW 更改为 ESTABLISHED)。
  • 如果由于某些特定原因,尽管数据包具有其特征,但仍无法匹配现有流(例如:重传后收到的延迟 TCP 数据包已成功启动,因此在序列和 SACK 值方面超出窗口)数据包将被标记为无效。
  • 还有一些其他情况,例如 RELATED:这是关于数据包不是流本身的一部分,而是与可以与其他现有(即:在数据库中)流相关联的新流相关的数据包。两个示例是由于接收数据包(例如:UDP 端口不可达)或当内核模块nf_conntrack_ftp(它是conntrack子系统的插件)等特殊协议助手检测到数据包是相关联的单独数据流的一部分时创建的 ICMP 错误。使用 FTP 命令 PASV/EPSV 或 PORT/EPRT 在命令流(在端口 21)上完成。

解决问题

说了这么多,这里是你的两个子弹的答案:

  • 在主网络命名空间中,conntrack在其模块(包括可能的相关协议特定子模块)加载后立即开始跟踪连接。对于非初始网络命名空间(容器...),这还需要一些其他子系统引用它(例如 OP 的iptables的 conntrack 模块或使用一次conntrack稍后描述的命令)。这是默认设置,并且必须在conntrack之前将数据包特别标记为 UNTRACKED子系统看到它不跟踪此数据包。在 Linux 上,只有少数情况不需要跟踪,但当然有状态防火墙和有状态/动态 NAT 将不再可用(无钢 NAT 甚至可能首先需要使用 UNTRACKED,仍然可以做,但不能与iptables的TCnftables可以)。为了避免conntrack处理某些数据包,可以使用这种iptables规则(例如:端口 80/tcp):

    iptables -t raw -A PREROUTING -p tcp --dport 80 -j CT --notrack
    iptables -t raw -A OUTPUT -p tcp --sport 80 -j CT --notrack
    
    Run Code Online (Sandbox Code Playgroud)
  • 当数据包通过 filter/INPUT 并到达此规则时:

     iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    
    Run Code Online (Sandbox Code Playgroud)

    所述的iptables的特定的内核模块xt_conntrack查询跟踪连接子系统(由各种相关的内核模块处理nf_conntrack*),并询问该分组在其查找数据库的状态。如果答案是RELATEDESTABLISHED数据包匹配并继续接受判决。实际上,第一次完成查找(通常通过conntrack)时,结果已经缓存在数据包中,所以这是一个廉价的“查找”。因此,这是处理之前已经接受的流的通用规则。这些流程最初可以在明确提及的规则中接受,或者只是没有提及但放在之后的规则中接受-m conntrack --ctstate NEW这个通用规则(但请记住 INVALID 状态,通常应该在执行此操作之前将其删除)。

  • 添加一个子弹:传入数据包和传出数据包的处理在 PREROUTING 和 OUTPUT 之间是非常对称的(即使那些看起来不对称):PREROUTING 和 OUTPUT 中的conntrack接口(以及在其他一些地方,考虑到NAT是与conntrack一起工作,除了它的第一个数据包处于 NEW 状态,遍历iptables的 nat 表)。这可能与您写的有关 IPFW 的描述略有不同。如果运行应用程序的服务器也限制传出流量,那么它很可能需要在 filter/OUTPUT 和 filter/INPUT 中使用相同的通用iptables规则,以允许已经接受的传入流量的传出回复数据包通过。


附加信息

有专用工具可以与conntrack-tools 中conntrack子系统的查找表进行交互。

  • conntrack: 查询、删除或更新由conntrack处理的查找表的内容。

    一些例子。

    您可以列出所有跟踪的条目(无需额外过滤器即可很大):

    conntrack -L
    
    Run Code Online (Sandbox Code Playgroud)

    如果您的系统正在执行 NAT(例如,私有 LAN 前的路由器,或运行虚拟机和容器),您可以使用--any-nat,--src-nat--dst-nat仅显示响应。所有 NAT、所有源 NAT(伪装)或所有目标 NAT(通常用于转发端口):

    实时监控conntrack事件:

    conntrack -E
    
    Run Code Online (Sandbox Code Playgroud)
  • conntrackd:一个守护进程,其两个主要目的是(conntrack)流量统计和统计,或者高可用性有状态防火墙集群状态同步。