firewalld是CentOS 7及以后版本默认的防火墙管理服务,取代了早期的iptables服务,而firewall-cmd就是操作firewalld的命令行工具。相比iptables直接操作链和表的机制,firewalld引入了区域(zone)的概念,把网络接口和规则按信任级别分组管理,同时支持运行时规则与永久规则的分离,以及不中断连接的动态更新。本文将从基本概念讲起,逐步覆盖日常运维中会用到的全部常用命令。

一、firewalld基础概念与准备工作
1. 什么是zone(区域)
firewalld将防火墙规则按不同的信任级别划分成多个区域,每个区域定义了一套预置的规则集。一块网卡只能绑定一个区域,数据包进入时按照绑定区域的规则处理。系统预置了几个常用区域:
- drop:最低信任级别,丢弃所有进入的包,不给出任何回应,只允许出站流量。
- block:拒绝所有进入的连接,但会返回icmp-host-prohibited消息。
- public:默认区域,表示网络中其他主机不可信任,只放行选定的入站连接。
- internal:用于内部网络,基本信任网络内的其他机器,放行大部分连接。
- trusted:完全信任,接受所有网络连接。
理解区域是掌握firewall-cmd的前提。比如服务器有内网和外网两块网卡,可以把外网网卡绑定到public区域严格管控,内网网卡绑定到internal区域放宽限制,这种分组管理方式比iptables按链堆规则清晰得多。
2. 启动服务与基础状态命令
使用firewall-cmd之前需要确认firewalld服务正在运行。 CentOS 7使用systemctl管理服务:
# 启动firewalld并设置开机自启 systemctl start firewalld systemctl enable firewalld # 查看服务状态 systemctl status firewalld # 查看防火墙运行状态,running表示运行中 firewall-cmd --state # 查看默认区域 firewall-cmd --get-default-zone # 查看当前激活的区域及绑定的网卡 firewall-cmd --get-active-zones # 查看public区域的所有配置 firewall-cmd --zone=public --list-all
如果服务器之前装过iptables服务,需要先停掉并禁用,否则两者会冲突。可以执行systemctl disable iptables并确认iptables服务没有开机自启。
二、运行时规则与永久规则的区别
1. --permanent参数的核心作用
firewall-cmd有一个最容易被新手忽略的机制:不加--permanent参数时,添加的规则立即生效,但只存在于内存中,firewalld重启或执行reload后规则会消失;加了--permanent参数后,规则写入配置文件(通常保存在/etc/firewalld/zones/目录下),重启后依然有效,但不会立即生效,需要手动重载。
常见的坑就是执行了firewall-cmd --add-port=8080/tcp之后发现端口通了,结果服务器一重启端口又不通了,原因就是没有加永久参数。配置永久规则的推荐流程是:
# 添加永久规则 firewall-cmd --permanent --add-port=8080/tcp # 重载防火墙使永久规则生效 firewall-cmd --reload
注意--reload会重新加载永久配置并丢弃当前的运行时规则,如果有同事临时加过运行时规则,reload之后会全部丢失。如果想保留运行时规则,可以使用--complete-reload之外的另一种方式,先用命令把运行时配置写入永久配置再重载。
2. 常用的规则管理辅助命令
# 查看运行时规则 firewall-cmd --list-all # 查看永久规则 firewall-cmd --permanent --list-all # 查看已放行的端口列表 firewall-cmd --list-ports # 把当前运行时规则保存为永久规则 firewall-cmd --runtime-to-permanent # 查询某个端口是否已放行 firewall-cmd --query-port=80/tcp
--runtime-to-permark拼错会报错,正确写法是--runtime-to-permanent,这个命令在先做临时验证、确认没问题后再固化的工作流中非常实用。
三、端口与服务管理实战
1. 开放和关闭指定端口
端口管理是最常用的操作。命令格式为--add-port=端口/协议,协议通常是tcp或udp,也可以指定端口范围:
# 开放单个端口(永久) firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload # 开放端口范围 firewall-cmd --permanent --add-port=30000-31000/tcp firewall-cmd --reload # 关闭端口 firewall-cmd --permanent --remove-port=3306/tcp firewall-cmd --reload # 针对指定区域操作 firewall-cmd --permanent --zone=internal --add-port=8080/tcp firewall-cmd --zone=internal --reload
如果不指定--zone,命令会作用于默认区域。开放端口后建议用firewall-cmd --list-ports确认规则确实写进去了,再用telnet或curl从外部测试连通性。另外要注意,云服务器(如阿里云、腾讯云)除了系统防火墙外还有安全组,两层都要放行端口才能通。
2. 按服务名放行
firewalld内置了一批常见服务的规则定义,存放在/usr/lib/firewalld/services/目录下,每个服务对应一个xml文件,比手动记端口号方便:
# 查看所有可用服务 firewall-cmd --get-services # 放行http服务(相当于开放80端口) firewall-cmd --permanent --add-service=http # 放行https firewall-cmd --permanent --add-service=https # 放行ftp、mysql等 firewall-cmd --permanent --add-service=ftp firewall-cmd --permanent --add-service=mysql # 移除服务 firewall-cmd --permanent --remove-service=http firewall-cmd --reload
服务方式和端口方式的区别在于,服务定义可能包含多个端口和协议。比如dhcpv6-client服务涉及多个UDP端口,用服务名放行一条命令就够了。如果需要自定义服务,可以复制/usr/lib/firewalld/services/下的xml模板到/etc/firewalld/services/目录修改后使用。
四、端口转发与富规则配置
1. 端口转发(伪装)
firewall-cmd支持将某个端口的流量转发到本机其他端口或远程主机,实现前需要开启masquerade:
# 开启地址伪装 firewall-cmd --permanent --add-masquerade firewall-cmd --reload # 本机转发:把8080端口的流量转发到80端口 firewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toport=80 firewall-cmd --reload # 转发到其他主机:转发到192.168.1.100的8080端口 firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080 firewall-cmd --reload # 删除转发规则 firewall-cmd --permanent --remove-forward-port=port=8080:proto=tcp:toport=80
端口转发常用于隐藏真实服务端口、内网服务对外发布的场景。配置后记得确认内核的ip_forward已开启,可用sysctl net.ipv4.ip_forward查看,为0时需要修改/etc/sysctl.conf加上net.ipv4.ip_forward = 1后执行sysctl -p。
2. 富规则(rich rules)精细控制
普通的add-port只能控制端口维度,如果需要限制来源IP、限制用户或做更复杂的逻辑,就要用富规则。富规则语法用自然语言风格描述条件:
# 只允许192.168.1.0/24网段访问ssh服务 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' # 拒绝某个IP访问80端口 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" port port="80" protocol="tcp" reject' # 允许特定IP访问3306端口 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.20" port port="3306" protocol="tcp" accept' # 查看已有的富规则 firewall-cmd --list-rich-rules # 删除富规则(把add换成remove,规则内容保持一致) firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' firewall-cmd --reload
富规则的优先级高于普通的端口和服务规则,reject会明确拒绝并回应,drop则直接丢弃不给回应。数据库端口只对应用服务器IP放行、管理后台只允许办公网段访问,这类需求用富规则实现最合适。
五、常见问题排查与注意事项
1. 规则不生效的排查思路
配置完成后端口依然不通,可以按以下顺序排查:首先用firewall-cmd --state确认服务在运行;然后检查默认区域是不是预期区域,服务器上最常见的问题是命令操作的区域和网卡实际绑定的区域不一致,用firewall-cmd --get-active-zones核实;接着确认规则是否加上了permanent并执行过reload;最后检查应用本身是否监听在0.0.0.0而不是127.0.0.1,可以用ss -tlnp查看监听地址。如果监听在127.0.0.1,防火墙放行也没用,需要修改应用配置。
2. 其他实用命令汇总
# 修改默认区域 firewall-cmd --set-default-zone=trusted # 把网卡绑定到指定区域 firewall-cmd --permanent --zone=internal --change-interface=eth1 # 查看指定端口由哪个区域处理 firewall-cmd --get-zone-of-interface=eth0 # 查看panic模式状态(开启后断所有网络) firewall-cmd --query-panic # 应急处理:紧急断网防止入侵扩散 firewall-cmd --panic-on # 恢复网络 firewall-cmd --panic-off
--panic-on是应急手段,开启后所有网络连接全部切断,包括你自己的SSH会话,只适合在物理接触机器或带外管理的情况下使用,远程操作时千万不要随便尝试。掌握以上命令后,CentOS日常防火墙管理基本就够用了,建议把常用的permanent加reload组合整理成自己的操作习惯,避免规则丢失的问题反复出现。
firewall-cmdCentOS防火墙端口开放修改时间:2026-09-03 08:57:01