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 组合控制入站。关键点:
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
-
--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-save > /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 流程。










