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

iptables 规则匹配是顺序执行的,不匹配就跳下一条
iptables 不会“智能选择”最合适的规则,而是从链(如 INPUT、FORWARD)的第一条规则开始逐条比对,一旦某条规则的条件全部满足,就立即执行其 -j 目标动作(比如 ACCEPT、DROP),后续规则不再检查。这意味着规则顺序直接决定行为结果。
常见错误现象: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。
-
PREROUTING和POSTROUTING属于raw、mangle、nat表,filter表没有它们 - DNAT 后的包在
INPUT链中匹配的是“转换后的目的地址”,不是原始地址 - 本地进程发往 127.0.0.1 的包不经过
FORWARD或PREROUTING,只走OUTPUT和INPUT(环回)
规则不生效?先查 conntrack 状态和 raw 表干扰
很多看似“写了规则却没效果”的问题,根源不在 filter 表本身,而在连接跟踪或早期表(raw)提前截断了流程。例如 raw 表中的 -j NOTRACK 会让包跳过连接状态判断,导致 -m conntrack 规则永远不匹配。
性能影响:开启 nf_conntrack 会带来一定开销,高并发短连接场景下可能成为瓶颈;而关闭它又会让状态类规则失效。
- 检查是否启用了
raw表规则:iptables -t raw -L -n - 查看当前连接跟踪条目:
conntrack -L | head -20,确认状态是否符合预期(如ESTABLISHED、INVALID) - 临时清空连接跟踪表:
conntrack -F(慎用,会中断现有连接)
filter,先跑一遍 iptables -t raw -L -n 和 conntrack -L,往往比重写十遍 -A INPUT 更快定位问题。










