Linux iptables 防火墙规则匹配机制解析

9次阅读

iptables规则按顺序逐条匹配,满足即执行动作且不再检查后续规则;顺序错误、模块依赖、网络路径差异及连接跟踪状态是四大常见问题根源。

Linux iptables 防火墙规则匹配机制解析

iptables 规则匹配是顺序执行的,不匹配就跳下一条

iptables 不会“智能选择”最合适的规则,而是从链(如 input、FORWARD)的第一条规则开始逐条比对,一旦某条规则的条件全部满足,就立即执行其 -j 目标动作(比如 ACCEPTDROP),后续规则不再检查。这意味着规则顺序直接决定行为结果。

常见错误现象:iptables -A INPUT -p tcp --dport 22 -j ACCEPT 加在最后,但前面已有 -j DROP,导致 ssh 连接被拦。

  • 新增规则用 iptables -I 插入开头,比 -A 追加更可控
  • 调试时用 iptables -L -n --line-numbers 查看编号和匹配计数,确认哪条规则生效了
  • 默认策略(POLICY)是兜底逻辑,它只在所有规则都不匹配时才触发

匹配条件是“与”关系,多个 -m 模块可叠加但需注意加载顺序

一条规则里的所有匹配项(如 -s--dport-m state --state ESTABLISHED)必须同时成立,才算匹配成功。但不同扩展模块(-m)之间有隐含依赖:比如 -m conntrack 需要连接跟踪子系统已启用,-m iprange 不能和 -s 同时用于源地址限定。

使用场景:封禁某 IP 段的非 ESTABLISHED 连接,但放行已建立的回包。

  • -m state --state NEW 已被弃用,应改用 -m conntrack --ctstate NEW
  • -m multiport 只支持单个 --dports--sports,不能混用
  • 内核未加载对应模块(如 xt_conntrack)时,含 -m conntrack 的规则会报错或静默忽略

内置链的触发时机由内核网络路径决定,不是所有包都走同一链

一个 TCP SYN 包进入本机,走的是 INPUT 链;但若该机器开启转发且目标是另一台主机,则走 FORWARD 链;而本机发出的包走 OUTPUT 链。很多人误以为“所有进来的包都进 INPUT”,忽略了 DNAT 或转发场景。

典型陷阱:做了 DNAT(PREROUTING-j DNAT)后,目的 IP 已改变,后续匹配基于新地址,但 INPUT 链看到的是修改后的地址 —— 这容易导致规则写错目标端口或 IP。

  • PREROUTINGPOSTROUTING 属于 rawmanglenat 表,Filter 表没有它们
  • DNAT 后的包在 INPUT 链中匹配的是“转换后的目的地址”,不是原始地址
  • 本地进程发往 127.0.0.1 的包不经过 FORWARDPREROUTING,只走 OUTPUTINPUT(环回)

规则不生效?先查 conntrack 状态和 raw 表干扰

很多看似“写了规则却没效果”的问题,根源不在 filter 表本身,而在连接跟踪或早期表(raw)提前截断了流程。例如 raw 表中的 -j NOTRACK 会让包跳过连接状态判断,导致 -m conntrack 规则永远不匹配。

性能影响:开启 nf_conntrack 会带来一定开销,高并发短连接场景下可能成为瓶颈;而关闭它又会让状态类规则失效。

  • 检查是否启用了 raw 表规则:iptables -t raw -L -n
  • 查看当前连接跟踪条目:conntrack -L | head -20,确认状态是否符合预期(如 ESTABLISHEDINVALID
  • 临时清空连接跟踪表:conntrack -F(慎用,会中断现有连接)

规则顺序、模块依赖、网络路径、连接跟踪 —— 这四个点串起来,基本覆盖了 iptables 匹配机制里最容易卡住人的地方。实际调规则时,别急着改 filter,先跑一遍 iptables -t raw -L -nconntrack -L,往往比重写十遍 -A INPUT 更快定位问题。

text=ZqhQzanResources