木杉笔记

记录后端、运维与数据库的踩坑日常

被 iptables 咬过的几次

2026-09-18运维

iptables 的规则是有顺序的,匹配到第一条就结束。这句话我看了很多遍,但真正记住是付出过代价的。

第一次:把自己的 SSH 关在门外

当时想着「只允许特定 IP 访问 22 端口」,写了这么一条:

iptables -A INPUT -p tcp --dport 22 -j DROP
iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT

然后我就断线了。因为 DROP 在前,所有 22 端口的包在第一条就被丢掉了,第二条永远轮不到。

正确的顺序是放行在前:

iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

按 -A 是追加到末尾。如果要在中间插,得用 -I 加序号。

第二次:DROP 和 REJECT 的区别

一直以为这两个差不多,直到写了个健康检查脚本,它对超时的处理和连接被拒的处理完全不同。

DROP 是把包扔掉,不发任何回应,客户端要一直等到超时。REJECT 会回一个 ICMP 不可达或者 TCP RST,客户端立刻就知道了。

对外面来的扫描,DROP 更好 —— 让扫描器在那儿干等。对自己内部的规则,REJECT 更好调试。

第三次:规则没存下来

调了一下午,重启之后全没了。iptables 的规则默认只存在内核里,重启就清空。

apt install iptables-persistent
iptables-save > /etc/iptables/rules.v4

装完之后它会自动在开机时加载 /etc/iptables/rules.v4。但注意:之后每次改完规则,都要重新 iptables-save 一次,否则下次重启又是旧的。

现在我的习惯

改任何规则之前先 iptables-save 存一份,改完立刻 iptables -L -n --line-numbers 看一眼顺序,确认无误再保存。多花十秒钟,能省掉一次救援。