conntrack是netfilter框架中由nf_conntrack内核模块实现的连接跟踪机制,负责为tcp/udp/icmp等协议维护会话快照,状态包括new、established、related、invalid和untracked,所有跟踪在prerouting和output链完成,表满会导致静默丢包。

iptables 的连接跟踪能力不是它自己实现的,而是依赖内核模块 nf_conntrack(旧称 ip_conntrack)来完成。理解 conntrack,就是理解 Linux 防火墙“有状态”的底层逻辑。
conntrack 是什么?它跟踪什么?
conntrack 是 Netfilter 框架中的核心机制,负责为每个经过的网络连接维护一个“会话快照”。它不区分 TCP 连接或 UDP 会话,而是抽象地跟踪“通信双方之间的一次数据交换过程”。只要协议被支持(TCP、UDP、ICMP、SCTP、DCCP、GRE),conntrack 就能为其创建并管理一条连接记录。
每条记录包含源/目的 IP、端口、协议号、状态、超时时间、NAT 映射信息等。这些数据存于内存中一张哈希表(conntrack table),可通过 /proc/net/nf_conntrack(新版)或 /proc/net/ip_conntrack(旧版)查看。
五种连接状态的真实含义
iptables 的 -m state --state 规则匹配的,正是 conntrack 给出的状态标签。它们不是 TCP 状态机的直接映射,而是 conntrack 基于包特征和已有上下文推断出的语义:
- NEW:该包是 conntrack 见到的、属于某连接的第一个包(如 SYN、首个 UDP 查询、ICMP 请求);不要求一定是 TCP 握手起点
- ESTABLISHED:已有连接已双向通信过(收到过应答),后续所有属于该连接的包都属此状态
- RELATED:该包不属于主连接,但由某个 ESTABLISHED 连接“触发”产生(如 FTP 数据连接、ICMP 错误报文、SIP 的 RTP 流)
- INVALID:包无法归属任何现有连接,或违反协议规范(如乱序 FIN、无对应连接的 ACK)
- UNTRACKED:人为绕过跟踪的包(通过 raw 表的 NOTRACK 目标),常用于性能敏感服务(如高并发 Web)
conntrack 在 Netfilter 中的执行位置
连接跟踪不是在所有链上重复做,而是在数据流关键入口点集中处理:
- 所有入站包(包括转发流量)在 PREROUTING 链触发跟踪,决定是否新建条目或更新状态
- 本地生成的出站包在 OUTPUT 链触发跟踪(同样可能新建 NEW 条目)
- raw 表优先级最高,可用于提前标记 NOTRACK,避免不必要的跟踪开销
- 一旦跟踪建立,后续规则(如 filter 表 INPUT)就能基于状态做高效决策,无需重新解析连接关系
常见问题与调优要点
conntrack 表满(kernel: nf_conntrack: table full, dropping packet)是典型瓶颈,尤其在短连接或 NAT 场景下:
- 查看当前最大容量:
cat /proc/sys/net/netfilter/nf_conntrack_max - 查看实时条目数:
cat /proc/net/nf_conntrack | wc -l - 扩容需同步调整两个参数:内核最大值(
nf_conntrack_max)和哈希桶数量(nf_conntrack_hashsize,通常为 max/8) - 对 HTTP、DNS 等高频短连接服务,建议用 raw 表跳过跟踪:
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK - 注意:NOTRACK 后,filter 表无法再使用
--state ESTABLISHED匹配,需改用传统四元组规则











