iptables 和 firewalld 不能共存,因二者操作同一 netfilter 框架,同时启用会导致规则覆盖、策略失效;排查关键在于确认实际控制者——通过 systemctl 状态、firewall-cmd --state、iptables -l 输出及 input 链首条规则判断谁在生效。

iptables 和 firewalld 不能真正“共存”——它们都操作同一套内核 netfilter 框架,同时启用会导致规则互相覆盖、策略失效、连接异常。所谓“共存”,其实是运维误启两者或迁移未清理干净造成的冲突状态。排查关键不是调和二者,而是识别谁在实际控制、谁的规则已被清空、哪一层的规则实际生效。
确认当前实际生效的防火墙管理器
先停止猜测,用命令直接验证:
- 查服务状态:
systemctl is-active firewalld和systemctl is-active iptables,只应有一个为 active - 查进程与规则源头:
firewall-cmd --state成功返回表示 firewalld 活跃;iptables -L -n | head -5若输出大量非默认规则,可能 iptables 正在接管(尤其当 firewalld 被禁用但 iptables-services 仍运行) - 看命令可用性:
command -v firewall-cmd和command -v iptables都存在是正常的,但firewall-cmd调用的是 firewalld 的 dbus 接口,iptables命令直写内核,二者不可混用配置
检查规则是否被覆盖或清空
firewalld 启动或 reload 时,会重置 filter/nat 表中由它管理的部分链(如 INPUT、FORWARD),若此时 iptables 规则未经持久化保存,就会丢失。典型表现是:
- 手动用
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT加了规则,重启 firewalld 后失效 -
iptables -L INPUT -n看不到你加的规则,但firewall-cmd --list-ports也显示为空——说明两边都没配,或 firewalld 的 zone 默认策略是 drop - 执行
iptables -t nat -L -n | grep DOCKER发现 Docker 规则还在,但firewall-cmd --list-all显示 docker0 接口未放行 → 这是 firewalld 未纳管 docker0 导致的转发阻断
定位冲突根源:看规则链的实际流向
数据包进入 INPUT 链后,firewalld 默认会在最前面插入一条跳转到 IN_public(或其他 zone 对应链)的规则。你可以用以下方式验证路径:
- 运行
iptables -t filter -L INPUT -n --line-numbers,观察第 1 条是否为ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED(firewalld 插入的标准前置规则) - 若看到
jump IN_public,说明 firewalld 在控制;若看到一堆手动添加的ACCEPT/DROP规则在顶部,且没有 jump,则 iptables 在主导 - 特别注意:firewalld 的 rich rules 或 direct rules 会写入
IN_public_allow或DOCKER-USER等自定义链,这些不会出现在iptables -L主链里,需用iptables -L IN_public_allow -n单独查看
快速恢复与隔离建议
一旦确认冲突,不要边查边改,先做最小干预以恢复业务:
- 若需保留 firewalld:停用 iptables 服务:
sudo systemctl stop iptables && sudo systemctl disable iptables;再检查/etc/sysconfig/iptables是否残留旧规则文件,建议重命名备份 - 若需保留 iptables:停用 firewalld:
sudo systemctl stop firewalld && sudo systemctl disable firewalld;并确保iptables-services已安装且启用 - 无论选谁,都必须统一端口开放动作:比如开了 80 端口,就只通过
firewall-cmd --add-port=80/tcp或iptables -A INPUT -p tcp --dport 80 -j ACCEPT其中一种方式,禁止交叉操作











