nftables 规则不匹配的 nft monitor trace 调试方法

11次阅读

根本原因是流量未经过预期hook点或规则位置不当致提前终止;需确认路径、family、链挂载及conntrack状态,并用nftrace强制全链路追踪。

nftables 规则不匹配的 nft monitor trace 调试方法

为什么 nft monitor trace 看不到你的规则匹配?

根本原因通常是流量没经过你预期的 hook 点,或者规则在链中位置不对导致提前终止。比如你在 input 链写了规则,但包实际走的是 forward(跨主机转发)或被前面某条 drop / accept 终止了,trace 就不会出现后续规则的记录。

实操建议:

  • 先确认流量路径:nft list chain inet Filter inputnft list chain inet filter forward 都要看,别只盯一个链
  • 确保你监听的是正确 family(inetipip6),IPv4 流量在 ip family 下才可能被 ip saddr 匹配到
  • nft monitor trace 默认只显示 kernel 实际执行过的规则,不显示“本该匹配但被跳过”的规则——它不是静态分析器

如何让 trace 输出更可靠?

默认 trace 可能漏掉早期 hook(如 prerouting)或被快速路径绕过(如 conntrack 已建立状态)。关键是要强制走慢路径并覆盖全链路。

实操建议:

  • 临时清空 conntrack 表:conntrack -F,避免 ESTABLISHED 流量被跳过规则直接放行
  • preroutingpostrouting 链开头加一条无条件 meta nftrace set 1,确保所有包都进 trace(注意:仅调试用,勿留在线上)
  • 用具体协议+端口触发,比如 curl -v http://localhost:8080,比泛泛 ping 更容易命中应用层规则

nft monitor trace 输出里关键字段怎么看?

每条 trace 记录是 jsON 格式,重点看 verdictrulechainhook 字段。如果某条规则没出现在 trace 中,不代表它不存在,只代表没执行到它。

常见误读点:

  • "verdict":"jump" 后跟着另一个链名,说明控制权移交了,得去对应链里找下一条匹配——别只盯着当前链
  • "rule":NULL 表示 packet 被隐式策略(如 policy drop)终结,此时要检查链的默认 policy,不是规则写错了
  • 同一包可能出现多次 trace,分别对应不同 hook(如 prerouting → input → postrouting),需按 pktid 关联

为什么加了规则还是没 trace 到?检查这三件事

最常卡在这三个地方,而不是语法错误:

  • 规则所在的链没被挂载到对应 hook:运行 nft list ruleset,确认输出里有类似 hook input priority 0; 这样的声明,没有就说明链没启用
  • 规则用了 ip6 saddr 却测试 IPv4 流量,或用了 ct state invalid 但 conntrack 模块没加载(lsmod | grep nf_conntrack
  • 规则加在 inet family,但你的 nftables 配置里混用了 ipinet,导致规则实际注册到了另一个 Namespace

真正难调的从来不是规则语法,而是流量路径和规则注册上下文是否对齐。多看 nft list ruleset -a 带句柄号的输出,再对照 trace 里的 handle 字段,才能确认“这条规则到底有没有被执行”。

text=ZqhQzanResources