最常见原因是hook位置和priority不匹配——规则必须位于流量实际经过的hook(如input/prerouting/forward)且priority值需符合内核预定义范围(如-450、-200、0),否则被conntrack或br_netfilter等模块截断;用nft monitor trace实时追踪数据包路径可准确定位。

为什么 nft list ruleset 看到规则,但流量完全不匹配?
最常见原因是 hook 位置和 priority 不对——nftables 的规则不是全局生效的,必须落在正确的 hook(如 input、forward)且 priority 值能插入到实际数据包经过的链中。比如你加在 inet filter input,但 SSH 流量走的是 inet filter prerouting(若启用了连接跟踪或 DNAT),或者 priority 太高/太低被其他内核子系统(如 conntrack、br_netfilter)截断。
- 用
nft monitor trace实时抓包看路径:开一个终端运行它,再从另一台机器发测试包(如curl -v http://your-ip),观察输出里是否出现你的 chain 名、rule handle,以及停在哪一步 - 确认 hook 类型是否匹配流量方向:本地进程发出的包走
output,进来的包走input或prerouting,转发包走forward;桥接流量还可能走ingress或postrouting - 检查是否启用了
br_netfilter模块:它会让桥接流量“绕行”到 netfilter 链,导致本该走ingress的包实际进了prerouting,此时规则得挂到对应 hook 才生效
nft add rule 时 priority 值怎么选才不会被跳过?
priority 不是“越大越优先”,而是决定规则在 hook 内部链表里的插入顺序。内核为每个 hook 预定义了若干标准 priority 常量(如 0 对应 NF_IP_PRI_FIRST,-200 对应 NF_IP_PRI_CONNTRACK),规则必须设成这些值附近,否则可能被插到无效位置甚至被忽略。
- 常用参考值:
-450(raw 表)、-200(conntrack)、0(filter 默认)、100(mangle)、300(nat);直接写数字比写符号名更稳妥,因为不同内核版本符号定义可能不一致 - 避免用正数大值(如
999):可能插到所有内置模块之后,而某些关键处理(如 TCP 连接状态检查)已在前面完成,导致你的规则收不到原始包 - 如果想确保最早触发,优先用
-450;想在 conntrack 后、路由前执行,用-150;不确定时先试0,再配合nft monitor trace观察
如何验证某条规则是否真正在处理目标流量?
光看 nft list ruleset 显示 counters 为 0 并不能说明问题——counter 只在规则匹配且未被跳过时累加,而规则可能因 verdict 是 continue、或被更高优先级规则 drop 掉,根本没走到你这来。
- 给规则加
counter+log prefix "my-rule: ",然后tail -f /var/log/kern.log | grep "my-rule";log 比 counter 更早触发,能确认包是否抵达该规则 - 临时把规则 verdict 改成
drop或reject,看对应流量是否立刻中断;如果没反应,基本确定包根本没路过这条规则 - 注意 log 的 rate-limit:默认每分钟最多 5 条,高频测试时加
limit rate 10/second避免丢日志
bridge + nftables 混合场景下 hook 错位的典型表现
当服务器同时启用网桥(如 docker0、virbr0)和 nftables 时,br_netfilter 模块会强制把桥接帧送入 IPv4/IPv6 netfilter 链,导致原本该走 ingress 或 forward 的包,实际进了 prerouting → input 或 forward → postrouting,而你的规则若只挂在 filter input,就会漏掉大量桥接入口流量。
- 查是否加载:运行
lsmod | grep br_netfilter;若存在,且你有桥接接口,就必须在inet filter prerouting和inet filter forward中补全规则 - 临时禁用验证:运行
sysctl -w net.bridge.bridge-nf-call-iptables=0,再测规则是否突然生效;若是,说明问题根源在此 - 生产环境别长期关它——关了会影响 Docker、KVM 等依赖 iptables/nftables 控制桥接流量的功能
hook 和 priority 不是配置项,是数据包穿越内核协议栈时的真实坐标。调错一个数,整条链就脱节。最省时间的做法永远是先 nft monitor trace 看一眼包到底走了哪几步,而不是反复改 priority 猜。










