nftables规则执行由Hook链优先级和链内规则匹配流程共同决定:优先级数字越小越早执行,链内规则自上而下匹配并受verdict、jump/goto等控制。
nftables 规则执行不是简单按行扫描,而是由两层机制共同决定:链在 Hook 点上的执行顺序(优先级),以及链内规则的匹配流程(跳转与 verdict 控制)。理解这两层,才能写出可预测、易维护的防火墙策略。
链的 Hook 优先级决定谁先“上场”
数据包进入某个 Hook 点(如 input)时,可能有多个链挂载于此。哪个链先处理?取决于它们的 priority 值——数字越小,越早执行。
- 系统预定义名称对应固定数值:raw(-300)、mangle(-150)、dstnat(-100)、filter(0)、security(50)、srcnat(100)
- 同一 Hook 下,priority -100 的链一定比 priority 0 的链先运行,无论它们属于哪个表
- 这个顺序只在 nftables 内部有效;iptables-legacy 规则走另一套注册路径,与 priority 无关,混用会导致行为不可控
链内规则严格自上而下匹配
一旦进入某条链,规则就按添加顺序逐条检查,遇到第一个完全匹配的规则即执行其动作,并根据动作类型决定是否继续:
- verdict 类动作(accept/drop/reject/return)会终止当前链的后续匹配
- jump/goto 跳转到另一条链后,仍从目标链第一条规则开始匹配
- continue 不终止匹配,继续检查本链下一条规则
- 没有匹配项时,执行链的默认 policy(如 drop 或 accept)
跳转(jump/goto)不改变执行上下文
jump 和 goto 都用于调用其他链,但行为不同:
-
jump:像函数调用,执行完目标链后返回原链的下一条规则
-
goto:直接跳入目标链,执行完后不再回到原链,而是继续当前 Hook 的后续流程(如从 input 跳 goto my_log_chain,log 完就结束 input 处理)
- 被跳转的链必须是 base chain(即带 hook 和 priority 的链),普通链不能作为 jump/goto 目标
连接跟踪状态可短路匹配
ct state established,related 这类条件能快速放行已有连接的回包,本质是利用 conntrack 子系统缓存结果。它不依赖规则位置,但受 priority 影响——若在 raw 链用 notrack 豁免了连接跟踪,后续 ct 匹配就永远不生效。
- 推荐把 ct state 相关规则放在 filter 链靠前位置,避免被更早的 drop 规则拦截
- prerouting 中的 DNAT 会影响后续 ct state 判断(目标地址已改),所以 DNAT 规则需放在 ct 匹配之前