CentOS 7中,firewalld与iptables虽能同时安装,但不建议共存,否则易致规则冲突、策略丢失甚至网络中断。若需明确当前生效的防火墙引擎,可使用systemctl status firewalld和systemctl status iptables命令。若firewalld已启用,应统一使用firewall-cmd管理;若要进行iptables操作,需先停用firewalld,并启用iptables-services。

CentOS 7 默认用 firewalld,不是直接改 iptables 规则;想精确控制入站/出站包过滤,得先确认你用的是哪个防火墙引擎——混用或切换不当会导致规则不生效、甚至丢连接。
怎么确认当前生效的防火墙引擎
执行这两条命令,看输出:
systemctl status firewalld —— 如果显示 active (running),说明 firewalld 正在管事;
systemctl status iptables —— 如果显示 inactive (dead) 或未安装,那 iptables 命令即使能运行,也基本不起作用(除非你手动停掉 firewalld 并启用 iptables-services)。
常见错误:以为 iptables -L 看到的规则就是当前生效的,其实 firewalld 底层可能已把规则刷进 iptables,但你直接用 iptables 增删会和 firewalld 冲突,重启后全丢。
用 firewalld 修改入站规则(最常用场景)
firewalld 不暴露原始 iptables 链,而是通过 zone + service/port/rich rule 组合控制入站。关键点:
--permanent必须加,否则重启失效- 修改后必须
firewall-cmd --reload才真正生效(不是systemctl restart firewalld) - 默认 zone 是
public,查当前 zone:firewall-cmd --get-default-zone
示例(只允许 192.168.1.50 访问 8080/tcp):
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.50" port port="8080" protocol="tcp" accept' firewall-cmd --reload
注意:rich rule 里不能写 -j ACCEPT 这类 iptables 语法,也不支持 --dport 这种参数写法。
用 iptables 直接操作包过滤规则(需停 firewalld)
只有明确要绕过 firewalld、做精细控制(比如限速、连接状态匹配、raw 表操作)时才走这条路。步骤严格:
- 停并禁用:
systemctl stop firewalld && systemctl disable firewalld - 装服务:
yum install -y iptables-services - 启动:
systemctl start iptables && systemctl enable iptables - 查当前规则:
iptables -L INPUT -n -v --line-numbers(只看入站链) - 加一条拒绝某 IP 的入站包:
iptables -I INPUT 1 -s 203.0.113.25 -j DROP - 保存:
iptables-sa ve > /etc/sysconfig/iptables(CentOS 7 必须这步,否则重启丢失)
出站规则同理,但默认 OUTPUT 链策略通常是 ACCEPT,改它风险高——比如误加 iptables -A OUTPUT -p tcp --dport 53 -j DROP 会导致 DNS 失效。
为什么改了规则却没效果
最常踩的三个坑:
- 忘了
--permanent或--reload,只执行了firewall-cmd --add-port=…(这是 runtime 规则,重启就清空) - 在
firewalld运行时直接跑iptables -A INPUT …,结果被firewalld下次 reload 覆盖掉 - 规则顺序错了:
iptables是从上到下匹配,-j DROP写在-m state --state ESTABLISHED,RELATED -j ACCEPT前面,会把回包也丢了
其复杂之处在于:firewalld 的rich rule和direct interface是可以混合使用的。然而,一旦使用了 firewall-cmd --direct …,就需要自行维护底层的 iptables 语句,并且必须确保其与zone规则不发生冲突。不过,这种组合在实际中很少会用到,多数人在此卡住,主要是因为没有意识到firewalld已经接管了整个netfilter流程。