iptables
2023 年一次线上事故让我记到今天:一台公网服务器的 22 端口被爆破,同事补了一串 iptables 规则后,`iptables -L -n` 里明明白白有 DROP,扫描器却照样连进来。排查半小时才发现,那条 DROP 是用 `-A` 追加到链尾的,前面一条 `ACCEPT all` 已把它短路。iptables 是 first-match-wins,顺序即生死——坑全藏在'顺序''表''钩子''conntrack'几个词里。
从 ipfwadm 到 netfilter:Rusty Russell 的两次重写
顺序即生死:一条 DROP 为什么拦不住任何包
-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:内核替你记住的那张连接表
nf_conntrack_max=65536,每条约 300 字节;打满时新连接被静默丢弃,表现为间歇性超时。看 nf_conntrack_count/max,超 75% 预警;根因常是 TIME_WAIT/UDP 泄漏,调上限只是治标。NAT 三兄弟:SNAT、DNAT、MASQUERADE 别用混
规模天花板:kube-proxy 是怎么被规则链拖垮的
iptables-restore 原子替换独占 xtables 锁,期间单条命令排队阻塞,CNI 更新被卡到秒级;超 1000 Service 即见延迟。K8s 切 IPVS 用 hash 查找,但 AddEntry() 约 2000 Service 时拖到 14s/17s。最终轮到 nftables 和 eBPF:原子事务与 O(1) BPF map 换掉规则集规模。实战示例
ss -tan state time-wait | wc -l 返回 8300+,端口范围 ip_local_port_range 只有约 28k,除以 60s 约等于 470 个并发上限——客户端短连接把端口耗尽了。调低 TIME_WAIT 回收,问题消失。子关键词
ipfwadm 与 ipchains 的遗产 两条注定被替换的老路
DNAT 与 INPUT 的地址错觉 NAT 先于 filter 求值的后果
conntrack 状态机 INVALID 只标记不丢弃
SNAT vs MASQUERADE 动态 IP 选哪个一目了然
xtables 锁与原子替换 高并发更新被卡死的元凶
nftables 的原子事务 语法是表象,事务才是真改进
衍生角度
设计模式:钩子订阅 + 责任链
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 泄漏,别只调大上限。
下一步动手做
相关书籍
第 30/31 章是 netfilter 表/链与 conntrack、NAT 最完整的内核实现描述,钩子求值顺序与 INVALID 不自动丢都以此为准。
Service 与 kube-proxy 章节把 iptables 模式如何串规则链、以及它的规模天花板讲透,对应本文的规则集爆炸叙事。