iptables规则未生效最常见原因是插入位置错误,因规则按序匹配且遇accept/drop即终止;需用iptables -l --line-numbers查看序号,优先用iptables -i input 1插入链首,并确保在兜底reject/drop规则之前。

iptables 规则为什么加了却没生效?
最常见原因是规则插入位置不对,iptables 是按链内规则顺序逐条匹配的,一旦某条规则匹配成功(比如 ACCEPT 或 DROP),后续规则就不再检查。
- 用
iptables -L --line-numbers查看当前规则序号,确认新规则是否插在了“拦路”规则之前 - 默认
iptables -A INPUT是追加到末尾,但多数情况下你需要的是iptables -I INPUT 1插入到最前面 - 如果已有
REJECT或DROP的兜底规则(比如-j DROP在链尾),新规则必须插在它前面才可能生效 - 注意:不同表(
filter、nat)和链(INPUT、FORWARD、OUTPUT)作用范围不同,ssh连接异常通常只查INPUT链
怎么安全地测试 DROP 规则,避免锁死自己?
直接加 DROP 到 INPUT 链,又没留白名单,远程 SSH 就会断连——这不是故障,是设计如此。
- 先用
iptables -I INPUT 1 -s 192.168.1.100 -j ACCEPT(换成你自己的管理 IP)保底放行 - 再加目标规则,例如
iptables -I INPUT 2 -p tcp --dport 22 -j DROP,确保它排在白名单之后 - 加完立刻用另一台机器测连通性,别等 5 分钟后才发现连不上
- 设置超时自动回滚:
(sleep 30; iptables -F INPUT) &,30 秒内验证失败就自动清空规则(仅限临时调试)
iptables-save 和 /etc/iptables/rules.v4 不同步怎么办?
iptables 命令改的是运行时规则,重启就丢;持久化靠的是保存到文件 + 系统服务加载,两者脱节就会“重启后规则消失”或“启动时载入旧规则”。
- 修改后必须手动执行
iptables-save > /etc/iptables/rules.v4(Debian/Ubuntu)或iptables-save > /etc/sysconfig/iptables(RHEL/CentOS) - 确认服务已启用:
systemctl enable netfilter-persistent(Debian)或systemctl enable iptables(RHEL),否则开机不加载 - 编辑文件后不能只改文件,还要
iptables-restore 让当前运行时同步 - 注意权限:文件必须是 root 可读,且不能有 Windows 换行符(
^M),否则iptables-restore会静默失败
为什么 --dport 22 不拦住所有 SSH 连接?
--dport 只匹配目的端口,而连接建立后,返回包走的是 OUTPUT 或 RELATED,ESTABLISHED 状态,不会经过同一条 --dport 规则。
- 单纯
-p tcp --dport 22 -j DROP只能拦新建连接的 SYN 包,已建立的连接不受影响 - 要彻底阻断,得配合状态模块:
-m state --state NEW -p tcp --dport 22 -j DROP,或者更现代的写法-m conntrack --ctstate NEW -p tcp --dport 22 -j DROP - 如果还用了 NAT 或代理(如 haproxy 转发到非 22 端口),
--dport匹配的是转发后的端口,不是客户端看到的端口 - UDP 服务(如 DNS)没有连接状态概念,
--dport规则对每个 UDP 包都生效,但也不受ESTABLISHED影响










