← 返回 Atlas
网络

iptables

2023 年一次线上事故让我记到今天:一台公网服务器的 22 端口被爆破,同事补了一串 iptables 规则后,`iptables -L -n` 里明明白白有 DROP,扫描器却照样连进来。排查半小时才发现,那条 DROP 是用 `-A` 追加到链尾的,前面一条 `ACCEPT all` 已把它短路。iptables 是 first-match-wins,顺序即生死——坑全藏在'顺序''表''钩子''conntrack'几个词里。

防火墙 · netfilter · NAT

从 ipfwadm 到 netfilter:Rusty Russell 的两次重写

Linux 2.0 时代(1995-1996)防火墙叫 ipfwadm,Jos Vos 维护,源头是 BSD 的 ipfw:直接改内核代码,把过滤逻辑焊死在网络路径上。1998 年 Rusty Russell 为 2.2 写 ipchains,加了链式规则,仍是'改内核代码'模式,过滤/NAT 耦合。同年他启动 netfilter:教训是直接塞过滤逻辑不可维护。解法是在网络代码里留一排通用钩子(netfilter hooks),让过滤/NAT/跟踪各以模块挂上。2001 年 2.4 交付,拆出 filter/nat/mangle 三表与五条内置链;conntrack 让状态化防火墙成为可能;2.4 之前只有 MASQUERADE 一个特例。

顺序即生死:一条 DROP 为什么拦不住任何包

iptables 是 first-match-wins:包从链头走到链尾,第一条匹配就执行,后面规则看都不看。-A 追加到链尾,-I 插到链头。典型翻车:开头 ACCEPT all,后面 -A 加禁 25 端口的 DROP——永远轮不到,计数恒为 0。所以状态化规则放最前:先放 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT,已建立连接尽早放行,只剩 NEW 包。INVALID 要显式写 DROP;conntrack 只标记不丢。排查第一动作是 iptables -L -n -v --line-numbers,带行号看顺序,对着计数器判断谁在生效。

conntrack:内核替你记住的那张连接表

状态化防火墙的秘密全在 conntrack 表:prerouting 首次查表记为 NEW,握手后 input/postrouting 做 confirm 标成 ESTABLISHED;RELATED 覆盖 FTP 这类衍生流。被丢弃的包不留条目——'规则拦了但表里没有'的注脚。四态 NEW/ESTABLISHED/RELATED/INVALID,INVALID 只标记不丢。表有硬上限,默认 nf_conntrack_max=65536,每条约 300 字节;打满时新连接被静默丢弃,表现为间歇性超时。看 nf_conntrack_count/max,超 75% 预警;根因常是 TIME_WAIT/UDP 泄漏,调上限只是治标。

NAT 三兄弟:SNAT、DNAT、MASQUERADE 别用混

NAT 在 nat 表的 PREROUTING 与 POSTROUTING 两条链工作。DNAT 在 PREROUTING 改写目的地址,经典用法是公网 80 转内网 10.0.0.5:8080;SNAT 与 MASQUERADE 都在 POSTROUTING 改写源地址,差别在 MASQUERADE 面向动态 IP,每次转发重查现算出口,SNAT 写死源地址、少查一次。固定 IP 用 SNAT,拨号出网用 MASQUERADE。两个典型事故:SNAT 写死成旧公网 IP,运营商换 IP 忘同步,出网全断;只写 DNAT 漏了 POSTROUTING 回程,应答包找不到回家的路,表现'能连上但请求挂起'。

规模天花板:kube-proxy 是怎么被规则链拖垮的

kube-proxy 把每个 Service 的每条 endpoint 展开成规则,线性匹配。Service 数×endpoint 数,规则 O(services×endpoints) 涨,上千 Service 数万条,每包经过整条扫。更致命是更新:iptables-restore 原子替换独占 xtables 锁,期间单条命令排队阻塞,CNI 更新被卡到秒级;超 1000 Service 即见延迟。K8s 切 IPVS 用 hash 查找,但 AddEntry() 约 2000 Service 时拖到 14s/17s。最终轮到 nftables 和 eBPF:原子事务与 O(1) BPF map 换掉规则集规模。

实战示例

报警:服务偶发连不上。先数 TIME_WAIT:ss -tan state time-wait | wc -l 返回 8300+,端口范围 ip_local_port_range 只有约 28k,除以 60s 约等于 470 个并发上限——客户端短连接把端口耗尽了。调低 TIME_WAIT 回收,问题消失。

子关键词

ipfwadm 与 ipchains 的遗产 两条注定被替换的老路
2.0 时代防火墙是 ipfwadm,源自 BSD ipfw,靠改内核代码做过滤与 NAT;1998 年 Rusty 为 2.2 写 ipchains,仍是改内核模式,过滤/NAT 耦合。netfilter 同年启动,用统一钩子框架重来。
DNAT 与 INPUT 的地址错觉 NAT 先于 filter 求值的后果
入站 DNAT 在 nat/PREROUTING 改写目的地址后才做路由,filter/INPUT 链看到的已是转换后的地址。按原始目的地址写 INPUT 匹配永远匹配不上——这是'端口转发规则看起来没生效'的头号根源,比规则顺序还隐蔽。
conntrack 状态机 INVALID 只标记不丢弃
conntrack 在 prerouting 查表、input/postrouting confirm,被丢弃的包不留条目。INVALID 不会自动丢,须显式 DROP;RELATED 覆盖 FTP 等关联会话,状态化因此少写一半规则。
SNAT vs MASQUERADE 动态 IP 选哪个一目了然
两者都只在 POSTROUTING 工作,但 MASQUERADE 每次转发重查 conntrack 现算出口 IP,适合动态公网;固定 IP 用 SNAT 写死源地址、少一次查表。把 SNAT 写死成旧 IP,换了公网地址直接翻车。
xtables 锁与原子替换 高并发更新被卡死的元凶
iptables-restore 原子替换独占内核 xtables 锁,期间单条 iptables 命令排队阻塞。kube-proxy 每轮规则同步加 CNI 并发更新,锁争用把同步拖到秒级——K8s iptables 模式事故的主要来源。
nftables 的原子事务 语法是表象,事务才是真改进
nftables 在内核里是一个小型通用虚拟机,规则集以字节码提交,更新走原子事务:要么整条规则集一起生效,要么全部失败,没有 iptables 逐条更新的中间态。这才是它替代 iptables 的硬理由,而不只是更简洁的 nft 语法。

衍生角度

设计模式:钩子订阅 + 责任链

netfilter 是'内核代码里预留钩子、各模块按需订阅'的框架,iptables/nftables 只是写规则的订阅者;规则链是责任链,first-match-wins 命中即短路,顺序即优先级。

概念拆解:表与链是职责分区,不是数据结构

filter 管放行丢弃,nat 管地址改写,mangle 管 TTL/MSS/TOS 改动,raw 关 conntrack——同一批钩子上不同表挂不同职责,想改 TTL 就必须进 mangle。

风格架构:用户态工具 ≠ 内核框架

iptables 只是用户态命令,内核里是 netfilter 钩子+模块;ip6tables/arptables/ebtables 分属 L2/L3,用一套工具管 IPv6/ARP 是错的。

原理分析:为什么 NAT 先于 filter 求值

入站 DNAT 在 prerouting 改写地址之后才做路由,所以 filter/INPUT 看到的是转换后的地址,按原始目的地址写匹配必然落空。先背下求值顺序,再排'规则没生效'类事故。

实际用法与坑

  • 规则集开头三条:ESTABLISHED,RELATED 放行、INVALID DROP,放业务规则。
  • 排查先看 iptables -L -n -v --line-numbers 的行号与计数。
  • 端口转发别漏 POSTROUTING 回程,否则连接挂起。
  • 固定 IP 用 SNAT,动态出网用 MASQUERADE,都在 POSTROUTING。
  • conntrack 超 75% 先查 TIME_WAIT/UDP 泄漏,别只调大上限。

下一步动手做

测试机先 iptables-save > backup.rules,再 iptables -F 清空,重建 ssh+conntrack 三连最小规则集;再用 nft 重写,试 nft -f 原子提交与 restore 锁差异。

相关书籍

深入理解 Linux 网络技术内幕

第 30/31 章是 netfilter 表/链与 conntrack、NAT 最完整的内核实现描述,钩子求值顺序与 INVALID 不自动丢都以此为准。

Kubernetes in Action

Service 与 kube-proxy 章节把 iptables 模式如何串规则链、以及它的规模天花板讲透,对应本文的规则集爆炸叙事。

关联关键词