确认当前生效规则链和默认策略需依次执行:sudo iptables -l input -n --line-numbers 查规则顺序,sudo iptables -s input 看精确语法,sudo iptables -p input 显示默认策略(accept/drop)。

怎么确认当前生效的规则链和默认策略
不先看清楚现状就加规则,极容易把 SSH 连接自己断掉。关键不是“有没有规则”,而是 INPUT 链的默认策略(POLICY)是 ACCEPT 还是 DROP,以及已有规则是否已覆盖合法流量。
执行这三条命令按顺序看:
-
sudo iptables -L INPUT -n --line-numbers:列出 INPUT 链所有规则,带编号,能看清匹配顺序 -
sudo iptables -S INPUT:显示原始规则语法,比-L更准,尤其对状态模块(如conntrack)的写法 -
sudo iptables -P INPUT:直接输出当前默认策略,比如返回DROP就说明没匹配上的包全被拒了
注意:iptables -L 默认不显示规则编号,也不显示 conntrack 模块的完整参数,容易误判;-S 输出的是可复用的命令格式,调试时更可靠。
怎么添加一条只允许某网段访问 SSH 的规则
追加(-A)和插入(-I)效果完全不同:追加到链尾,插入到链首。SSH 规则必须在 DROP 或 REJECT 规则之前生效,否则白写。
正确做法是插入到 INPUT 链最前面:
sudo iptables -I INPUT -p tcp --dport 22 -s 10.0.2.0/24 -m conntrack --ctstate NEW -j ACCEPT- 必须加
--ctstate NEW,否则会放行所有状态的 TCP 包(包括伪造的 FIN/RST),实际中几乎没人这么干 -
-s后面不能写主机名(如host.example.com),DNS 解析发生在用户态,iptables 在内核态运行,只认 IP 或 CIDR - 如果网卡不是默认的
eth0,而用了ens33或enp0s3,建议显式加-i ens33,避免规则在多网卡机器上误匹配
验证:用另一台 10.0.2.x 机器 ssh 测试连通性,再换非该网段 IP 尝试,应被拒绝。
为什么加了规则却没生效
最常见三个原因:表选错、链选错、模块未加载。
- 想控制进来的流量,却写了
iptables -t nat -A PREROUTING——这是做 DNAT 的,不是过滤,filter表的INPUT链才管入站包 - 规则写了
-p icmp却没加--icmp-type echo-request,现代系统默认禁 ping,仅写协议不指定类型,echo-reply可能被后续规则拦掉 - 用了
state模块(老写法),但内核已弃用,应改用conntrack;sudo modprobe nf_conntrack可手动加载,但最好检查lsmod | grep conntrack是否已载入 - 规则加完没保存:CentOS 7 以前用
service iptables save,新版用iptables-save > /etc/sysconfig/iptables;Ubuntu 系需安装iptables-persistent并执行netfilter-persistent save
临时规则重启即丢,且 systemd 服务名因发行版而异(iptables、netfilter-persistent、iptables-restore),不能假设统一。
怎么安全地删错的规则
别用 iptables -F 清空整条链——除非你有控制台直连或带外管理,否则大概率锁死自己。
- 按编号删最稳:
sudo iptables -D INPUT 3删除 INPUT 链第 3 条规则(编号来自--line-numbers输出) - 按内容删要完全一致:
sudo iptables -D INPUT -p tcp --dport 8080 -j DROP,哪怕少个空格或大小写不同(如drop)都会报错 “No chain/target/match by that name” - 删之前先备份:
sudo iptables-save > /tmp/iptables.before,恢复只需sudo iptables-restore - 如果已失联,物理机/VM 控制台里执行
sudo iptables -P INPUT ACCEPT先放行,再修规则
规则顺序就是执行顺序,删中间某条后,后续编号自动前移;替换规则用 -R 要指定编号,且新规则长度不能超过原规则(内核限制),不如删了重加。











