nftables 本身不实现协议状态机,仅依赖 conntrack 提供 L4 连接状态(established/related/invalid),深层协议状态检测需协同 eBPF 或用户态工具完成。

nftables 本身不实现协议状态机(如 TCP 三次握手合法性、HTTP 请求/响应序列、TLS 握手阶段校验等),它依赖内核 conntrack 子系统提供连接级状态(established、related、invalid),但不解析应用层协议状态机逻辑。所谓“基于协议状态机的深层检测”,需在 nftables 框架下协同用户态工具或 eBPF 程序完成:nftables 负责快速分流与标记,状态识别由外部模块完成,再通过元数据反馈驱动策略执行。
利用 conntrack 状态做 L4 层可靠状态过滤
这是 nftables 原生支持、最稳定的状态感知方式。conntrack 维护每个连接的生命周期状态,nftables 可直接匹配:
- ct state established:仅放行已成功完成三次握手的 TCP 连接或已确认的 UDP 流(如 DNS 响应)
- ct state related:匹配由主连接触发的辅助连接(如 FTP 数据通道、ICMP 错误报文)
- ct state invalid:匹配无法归入任何连接的异常包,建议默认丢弃
- ct status dnat|snat:结合 NAT 场景判断地址转换状态,用于区分内外流量走向
示例:拒绝所有未建立连接的入向新连接请求,仅允许已建立连接的返回流量
nft add rule inet filter input ct state invalid dropnft add rule inet filter input ct state { new, untracked } drop
nft add rule inet filter input ct state established,related accept
用 eBPF 实现 TCP 状态机增强检测
标准 conntrack 不验证 TCP 标志位组合是否符合 RFC 规范(如 SYN+FIN 同时置位、重复 ACK 序列异常等)。可通过 eBPF 程序在 socket 或 sk_skb hook 点注入深度校验逻辑:
- 编写 eBPF 程序解析 TCP 头部标志位、序列号、窗口值,识别非法状态迁移(如 client 发送 ACK 但未收过 SYN-ACK)
- 将检测结果写入 per-CPU map 或通过 skb mark 标记数据包
- nftables 规则中使用 meta mark 或 ct mark 快速决策:nft add rule inet filter input meta mark & 0x100 == 0x100 drop
- 典型场景:拦截 TCP flag 扫描(Xmas/Nmap Null)、TCP sequence spoofing 尝试
结合 userspace helper 构建应用层状态上下文
对 HTTP、DNS、TLS 等协议,可借助 userspace helper(如 nfqnl + 自定义守护进程)捕获初始数据包,构建轻量状态机上下文:
- 监听新连接的前几个 TCP segment,提取 HTTP Method + Path、DNS QNAME、TLS ClientHello SNI
- 为该连接分配唯一 ID,并在 userspace 中维护其当前协议阶段(如 “HTTP waiting for headers”、“TLS handshake in progress”)
- 通过 netlink 或 cgroup v2 接口将状态标记回 conntrack entry(如设置 ct label)
- nftables 使用 ct label 匹配:nft add rule inet filter input ct label "http_get" tcp dport 80 accept
该方式不修改内核,灵活性高,适合需要自定义协议行为(如只允许 GET/HEAD、禁止 POST 到静态资源路径)的场景。
规避常见误区:状态 ≠ 内容,标记 ≠ 解析
务必注意以下边界:
- nftables 的 ct state 是连接跟踪状态,不是协议状态机;它不会告诉你“这个 HTTP 包是不是合法的响应”,只会告诉你“这个包属于哪个已知连接”
- 启用 nf_conntrack_helper 并不能自动识别任意协议状态,它仅对少数明文协议(FTP、SIP)有内建支持,且已逐步被弃用
- eBPF 提取 SNI 或 Host 字段属于“指纹识别”,不是“状态机检测”;真正的状态机需跨多个包维护上下文(如 TLS handshake 共 4–5 个往返)
- 不要试图在 nftables 规则中用 payload 表达式拼凑完整状态逻辑——性能差、不可靠、难调试

















