CentOS 8 防火墙管理 firewalld 命令与配置详解
CentOS 8 系统 firewalld 防火墙的安装(在线 dnf 与离线 rpm)与 firewall-cmd 全部常用命令参数实测详解,含区域/服务/端口管理、规则持久化与实战演练
CentOS 8 防火墙管理 firewalld 命令与配置详解
目标:掌握 CentOS 8 系统 firewalld 防火墙的在线(dnf)与离线(rpm/dnf localinstall)安装,逐条实测 firewall-cmd 常用命令与参数,深入理解区域(zone)、服务、端口、运行时/永久双层规则机制,并能在真实环境中完成开放端口、拒绝 IP、规则持久化与排障。本文所有命令输出均为 CentOS 8 真实环境实测回显(firewalld 0.9.3)。
一、环境信息
| 项目 | 实测值 |
|---|---|
| 操作系统 | CentOS Linux 8(/etc/os-release 中 PRETTY_NAME="CentOS Linux 8") |
| 内核版本 | 6.8.0-138-generic(uname -r 实测输出) |
| firewalld 版本 | firewalld-0.9.3-7.el8.noarch(rpm 包),firewall-cmd --version 输出 0.9.3 |
| 防火墙后端 | nftables(/etc/firewalld/firewalld.conf 中 FirewallBackend=nftables) |
| 默认区域 | public |
| 主要配置文件 | /etc/firewalld/firewalld.conf、/etc/firewalld/zones/*.xml、/etc/firewalld/services/*.xml |
| 内置服务定义 | /usr/lib/firewalld/services/*.xml,共 176 个(`ls /usr/lib/firewalld/services/ |
| 测试机网络 | eth0:172.17.0.13/16,网关 172.17.0.1(ip -4 addr 实测) |
| systemd 单元 | firewalld.service(Type=dbus,ExecStart=/usr/sbin/firewalld --nofork --nopid) |
二、工具概述
firewalld(Firewall daemon)是 Red Hat 系发行版(RHEL 7/8/9、CentOS 7/8、Rocky、AlmaLinux 等)的默认动态防火墙管理工具。它以 D-Bus 接口 管理内核包过滤规则,通过 firewall-cmd 命令行与 firewall-config 图形工具对外提供操作入口。
核心概念:区域(zone)
firewalld 不再像传统 iptables 那样直接操作规则链,而是把规则组织到一组命名区域中。每个区域定义了一套允许/拒绝策略,网络接口(interface)或源地址(source)被绑定到某个区域后,就套用该区域的策略。CentOS 8 预置 9 个区域:
| 区域 | 默认 target | 特点 |
|---|---|---|
| drop | DROP | 丢弃所有入站包,无任何回应(最严格) |
| block | %%REJECT%% | 拒绝所有入站连接,以 icmp-host-prohibited 回应 |
| public | default | 公共区域,不信任其他主机,仅放行选定的入站服务(默认区域) |
| external | default | 外部网络,默认开启 masquerade(NAT 伪装),适合网关 |
| dmz | default | 隔离区,仅放行 ssh 等选定的服务 |
| work | default | 工作区,信任范围比 public 略宽 |
| home | default | 家庭区域,放行 ssh/mdns/samba-client/cockpit 等 |
| internal | default | 内部网络,同 home 策略 |
| trusted | ACCEPT | 信任区域,接受所有连接 |
工作原理:运行时(runtime)与永久(permanent)双层规则
firewalld 的规则分两层:
- 运行时规则:直接作用于内核(nftables),立即生效,但重启 firewalld 后丢失(本文实测验证,见“常见问题”)。
- 永久规则:保存在
/etc/firewalld/下的 XML 配置文件中,持久化到磁盘,--reload或重启后重新加载。
firewall-cmd 默认操作运行时层;加 --permanent 操作永久层。永久规则修改后需 --reload(或重启)才会写入运行时。
后端:nftables / iptables
CentOS 8 的 firewalld 0.9.3 默认使用 nftables 后端(FirewallBackend=nftables),规则最终下发到内核 nftables 子系统(可用 nft list ruleset 查看);也支持切换为 iptables 后端(FirewallBackend=iptables),此时规则通过 iptables 命令写入。
与 UFW 对比
- firewalld:区域化策略模型,适合多网卡、多信任级别的网关/服务器场景,动态加载、热更新,是 RHEL/CentOS 生态默认方案。
- UFW(Ubuntu):iptables 的极简前端封装,配置直观(allow/deny 一条命令),适合单机简单策略,是 Debian/Ubuntu 生态默认方案。
- 二者不可在同一系统上同时运行,否则规则互相冲突。
三、在线安装方案
CentOS 8 通过 dnf(Yum 的下一代版本)从 AppStream/BaseOS 仓库安装 firewalld。
3.1 安装前确认
rpm -q firewalld
firewalld-0.9.3-7.el8.noarch
💡 已安装时直接输出包名与版本;未安装时输出
package firewalld is not installed。
3.2 dnf 在线安装
dnf install -y firewalld
实测回显(尾部节选):
libnfnetlink-1.0.1-13.el8.x86_64
libnftnl-1.1.5-4.el8.x86_64
nftables-1:0.9.3-21.el8.x86_64
python3-decorator-4.2.1-2.el8.noarch
python3-firewall-0.9.3-7.el8.noarch
python3-gobject-base-3.28.3-2.el8.x86_64
python3-libselinux-2.9-5.el8.x86_64
python3-nftables-1:0.9.3-21.el8.x86_64
python3-slip-0.6.4-11.el8.noarch
python3-slip-dbus-0.6.4-11.el8.noarch
Complete!
💡 依赖解析:firewalld 自动拉取 nftables(内核过滤规则下发工具)、python3-firewall(Python 库)、python3-slip-dbus(D-Bus 绑定)等依赖包。
3.3 启用并开机自启
systemctl enable --now firewalld
该命令同时完成 enable(开机自启)与 start(立即启动)。验证:
systemctl is-active firewalld
systemctl is-enabled firewalld
firewall-cmd --state
firewall-cmd --version
active
enabled
running
0.9.3
⚠️ 执行
systemctl enable --now firewalld前请确认 ssh 服务已在放行列表中(public 区域默认放行 ssh),否则远程连接可能立即中断(见“注意事项”第 1 条)。
四、离线安装方案
离线场景下,先在可联网机器下载 firewalld 及其依赖 rpm 包,再拷贝到目标机器安装。
4.1 联网机器上下载 rpm 包
dnf download firewalld --resolve --destdir=/tmp/rpms
实测回显:
Module yaml error: Unexpected key in data: static_context [line 9 col 3] (重复多次,dnf 模块元数据警告,不影响下载)
firewalld-0.9.3-7.el8.noarch.rpm 170 kB/s | 502 kB 00:02
💡
--resolve自动解析并下载全部依赖;--destdir指定保存目录。Module yaml error是 dnf 读取 AppStream 模块元数据时的已知告警,不影响下载结果。
查看下载结果:
ls -lh /tmp/rpms
total 504K
-rw-r--r-- 1 root root 502K Oct 6 05:32 firewalld-0.9.3-7.el8.noarch.rpm
4.2 校验 rpm 包信息(可选)
rpm -qip /tmp/rpms/firewalld-0.9.3-7.el8.noarch.rpm
Name : firewalld
Version : 0.9.3
Release : 7.el8
Architecture: noarch
Install Date: (not installed)
Group : Unspecified
Size : 2064495
License : GPLv2+
Signature : RSA/SHA256, Mon Aug 9 23:26:51 2021, Key ID 05b555b38483c65d
Source RPM : firewalld-0.9.3-7.el8.src.rpm
Build Date : Mon Aug 9 19:10:32 2021
Build Host : x86-02.mbox.centos.org
Relocations : (not relocatable)
Packager : CentOS Buildsys <bugs@centos.org>
Vendor : CentOS
URL : http://www.firewalld.org
Summary : A firewall daemon with D-Bus interface providing a dynamic firewall
Description :
firewalld is a firewall service daemon that provides a dynamic customizable
firewall with a D-Bus interface.
查看包内文件清单(节选):
rpm -qpl /tmp/rpms/firewalld-0.9.3-7.el8.noarch.rpm | head
/etc/firewalld
/etc/firewalld/firewalld.conf
/etc/firewalld/helpers
/etc/firewalld/icmptypes
/etc/firewalld/ipsets
/etc/firewalld/lockdown-whitelist.xml
/etc/firewalld/policies
/etc/firewalld/services
/etc/firewalld/zones
/etc/logrotate.d/firewalld
4.3 目标机器安装(推荐:dnf localinstall)
把 rpm 拷贝到目标机器后,推荐使用 dnf localinstall,它会自动从已配置的仓库解析并安装缺失依赖:
systemctl stop firewalld
dnf remove -y firewalld python3-firewall
dnf localinstall -y /tmp/rpms/firewalld-0.9.3-7.el8.noarch.rpm
实测回显(尾部节选):
python3-libselinux-2.9-5.el8.x86_64
python3-nftables-1:0.9.3-21.el8.x86_64
python3-slip-0.6.4-11.el8.noarch
python3-slip-dbus-0.6.4-11.el8.noarch
Complete!
启动并验证:
systemctl enable --now firewalld
firewall-cmd --state
firewall-cmd --version
running
0.9.3
4.4 纯离线安装(rpm -ivh,无仓库可用)
若目标机器完全无法访问软件仓库,则需按依赖顺序手工安装全部 rpm:
rpm -ivh python3-firewall-0.9.3-7.el8.noarch.rpm firewalld-0.9.3-7.el8.noarch.rpm
⚠️ 预期输出(本文未实测,仅给出思路):
rpm -ivh不会自动解析依赖,若依赖包(python3-firewall、python3-slip-dbus、python3-nftables、nftables、libnftnl 等)未预先安装或顺序不对,会直接报错:error: Failed dependencies: python3-firewall is needed by firewalld-0.9.3-7.el8.noarch解决办法:先执行
rpm -ivh安装 firewalld 依赖的底层包(如 libnftnl、nftables、python3-slip-dbus、python3-firewall),最后安装 firewalld 主包;依赖包需一并从联网机器dnf download --resolve下载。依赖层级较多时更推荐dnf localinstall(见 4.3)。
五、配置详解
5.1 主配置文件 /etc/firewalld/firewalld.conf
查看所有非注释、非空的有效配置项:
grep -vE "^#|^$" /etc/firewalld/firewalld.conf
DefaultZone=public
CleanupOnExit=yes
Lockdown=no
IPv6_rpfilter=yes
IndividualCalls=no
LogDenied=off
FirewallBackend=nftables
FlushAllOnReload=yes
RFC3964_IPv4=yes
AllowZoneDrifting=yes
| 配置项 | 默认值 | 作用说明 |
|---|---|---|
DefaultZone=public | public | 新接口/新连接未指定区域时默认归入的区域。改此值可整体切换默认策略 |
CleanupOnExit=yes | yes | firewalld 退出(stop/卸载)时自动清空它下发的内核规则,避免残留 |
Lockdown=no | no | 锁定模式。开启后仅 lockdown-whitelist.xml 白名单内的程序可修改防火墙 |
IPv6_rpfilter=yes | yes | IPv6 反向路径过滤(防 IP 伪造) |
IndividualCalls=no | no | 是否对每个服务/端口单独调用后端更新;no 表示批量更新,性能更好 |
LogDenied=off | off | 记录被拒绝的报文:off / all / unicast / broadcast / multicast |
FirewallBackend=nftables | nftables | 规则后端:nftables(默认)或 iptables |
FlushAllOnReload=yes | yes | reload 时刷新全部链再重建,避免残留旧规则 |
RFC3964_IPv4=yes | yes | 6to4 隧道场景下将 IPv6 地址映射为 IPv4(RFC 3964) |
AllowZoneDrifting=yes | yes | 允许区域漂移:接口/源地址归属变化时自动重新匹配区域 |
5.2 区域定义 /etc/firewalld/zones/public.xml
public 是默认区域,其完整内容如下(含 <service> 引用,不直接写端口):
cat /etc/firewalld/zones/public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"/>
<service name="dhcpv6-client"/>
<service name="cockpit"/>
</zone>
字段说明:
<short>:区域短名称。<description>:区域用途描述。<service name="ssh"/>:放行名为 ssh 的服务(对应/usr/lib/firewalld/services/ssh.xml,即 TCP 22)。<service name="dhcpv6-client"/>:放行 DHCPv6 客户端(UDP 546)。<service name="cockpit"/>:放行 Cockpit 管理界面(TCP 9090)。- 区域文件无
<target>标签时默认default(按区域内规则匹配,未匹配则拒绝);drop区域为DROP、trusted区域为ACCEPT、block区域为%%REJECT%%。
💡
--add-service=http写入该文件后即出现<service name="http"/>,--add-port=8080/tcp写入后出现<port protocol="tcp" port="8080"/>。
查看 zones 目录:
ls /etc/firewalld/zones/
block.xml block.xml.old dmz.xml dmz.xml.old drop.xml drop.xml.old external.xml external.xml.old home.xml home.xml.old internal.xml internal.xml.old public.xml public.xml.old trusted.xml trusted.xml.old work.xml work.xml.old
💡
.xml.old是 firewalld 自动备份的旧版本文件,用于意外损坏时恢复。
内置区域默认定义位于 /usr/lib/firewalld/zones/(9 个,与 /etc 下同名):
ls /usr/lib/firewalld/zones/
block.xml
dmz.xml
drop.xml
external.xml
home.xml
internal.xml
public.xml
trusted.xml
work.xml
5.3 服务定义 /usr/lib/firewalld/services/
服务(service)把“端口+协议+可选模块”命名化,便于记忆与复用。内置 176 个服务定义:
ls /usr/lib/firewalld/services/ | wc -l
176
HTTP 服务定义(TCP 80):
cat /usr/lib/firewalld/services/http.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>WWW (HTTP)</short>
<description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
<port protocol="tcp" port="80"/>
</service>
SSH 服务定义(TCP 22):
cat /usr/lib/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>SSH</short>
<description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
<port protocol="tcp" port="22"/>
</service>
💡 自定义服务可放入
/etc/firewalld/services/并执行firewall-cmd --reload加载。
5.4 /etc/firewalld/ 目录结构
ls /etc/firewalld/
firewalld.conf firewalld.conf.old helpers icmptypes ipsets lockdown-whitelist.xml lockdown-whitelist.xml.old policies services zones
| 目录/文件 | 用途 |
|---|---|
firewalld.conf | 主配置(见 5.1) |
zones/ | 用户自定义区域(含被修改的内置区域副本) |
services/ | 用户自定义服务定义 |
icmptypes/ | 自定义 ICMP 类型定义 |
ipsets/ | 自定义 ipset 定义 |
helpers/ | 连接跟踪助手(如 FTP、TFTP 模块) |
policies/ | 策略对象定义(0.9.x 新增) |
lockdown-whitelist.xml | 锁定模式下允许操作防火墙的程序白名单 |
六、命令详解
firewall-cmd 是 firewalld 的主命令行工具。以下按功能分组逐条详解,命令与输出均为实测。
6.1 通用/帮助类
6.1.1 --version(查看版本)
- 用途:显示 firewall-cmd 版本号。
- 语法:
firewall-cmd --version或firewall-cmd -V - 参数:无。
firewall-cmd --version
0.9.3
6.1.2 --state(查看运行状态)
- 用途:查询 firewalld 服务是否在运行。
- 语法:
firewall-cmd --state - 返回:
running或not running(退出码 0/非 0)。
运行中:
firewall-cmd --state
running
停止后(实测:systemctl stop firewalld 之后):
firewall-cmd --state
not running
6.1.3 --help(帮助)
- 用途:打印所有可用选项的简短说明,用于快速查阅。
- 语法:
firewall-cmd --help或firewall-cmd -h - 实测输出(前 60 行):
firewall-cmd --help | head -60
Usage: firewall-cmd [OPTIONS...]
General Options
-h, --help Prints a short help text and exists
-V, --version Print the version string of firewalld
-q, --quiet Do not print status messages
Status Options
--state Return and print firewalld state
--reload Reload firewall and keep state information
--complete-reload Reload firewall and lose state information
--runtime-to-permanent
Create permanent from runtime configuration
--check-config Check permanent configuration for errors
Log Denied Options
--get-log-denied Print the log denied value
--set-log-denied=<value>
Set log denied value
Permanent Options
--permanent Set an option permanently
Usable for options marked with [P]
Zone Options
--get-default-zone Print default zone for connections and interfaces
--set-default-zone=<zone>
Set default zone
--get-active-zones Print currently active zones
--get-zones Print predefined zones [P]
--get-services Print predefined services [P]
--get-icmptypes Print predefined icmptypes [P]
--get-zone-of-interface=<interface>
Print name of the zone the interface is bound to [P]
--get-zone-of-source=<source>[/<mask>]|<MAC>|ipset:<ipset>
Print name of the zone the source is bound to [P]
--list-all-zones List everything added for or enabled in all zones [P]
--new-zone=<zone> Add a new zone [P only]
--new-zone-from-file=<filename> [--name=<zone>]
Add a new zone from file with optional name [P only]
--delete-zone=<zone> Delete an existing zone [P only]
--load-zone-defaults=<zone>
Load zone default settings [P only]
--zone=<zone> Use this zone to set or query options, else default zone
Usable for options marked with [Z]
--info-zone=<zone> Print information about a zone
--path-zone=<zone> Print file path of a zone [P only]
Policy Options
--get-policies Print predefined policies
--get-active-policies
Print currently active policies
--list-all-policies List everything added for or enabled in all policies
--new-policy=<policy>
Add a new empty policy
--new-policy-from-file=<filename> [--name=<policy>]
Add a new policy from file with optional name override [P only]
--delete-policy=<policy>
Delete an existing policy
💡 帮助中还包含 IPSet Options、IcmpType Options、Service Options(
--new-service、--info-service、--path-service等)、以及各操作类选项,可在需要时用firewall-cmd --help | less翻阅。帮助中标记[P]的选项须配合--permanent使用,标记[Z]的选项可配合--zone=指定目标区域。
6.2 区域(zone)查询类
6.2.1 --get-default-zone(查看默认区域)
- 用途:显示当前默认区域,新连接/新接口未指定时归入该区域。
- 语法:
firewall-cmd --get-default-zone - 参数:无。
firewall-cmd --get-default-zone
public
6.2.2 --set-default-zone(修改默认区域)
- 用途:修改默认区域。
- 语法:
firewall-cmd --set-default-zone=<zone> - 参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
<zone> | 目标区域名(9 个预置区域之一或自定义区域) | 必填 |
实测(切到 work 再切回 public):
firewall-cmd --set-default-zone=work
success
firewall-cmd --get-default-zone
work
firewall-cmd --set-default-zone=public
success
firewall-cmd --get-default-zone
public
⚠️ 修改默认区域前务必确认新区域内放行了 ssh,否则会立即断连(见“注意事项”)。
6.2.3 --get-active-zones(查看活跃区域)
- 用途:列出当前有接口/源地址绑定的区域。
- 语法:
firewall-cmd --get-active-zones - 参数:无。
无接口绑定时的实测输出(空):
firewall-cmd --get-active-zones
(空,无接口绑定)
将 eth0 绑定到 public 后(见 6.4.2):
firewall-cmd --get-active-zones
public
interfaces: eth0
6.2.4 --get-zones(列出全部区域)
- 用途:列出系统已知的全部区域名。
- 语法:
firewall-cmd --get-zones - 参数:无。
firewall-cmd --get-zones
block dmz drop external home internal public trusted work
6.2.5 --list-all-zones(列出所有区域详情)
- 用途:一次性打印全部区域的完整配置(目标、接口、服务、端口、富规则等)。
- 语法:
firewall-cmd --list-all-zones - 参数:无。
- 实测输出(完整,9 个区域):
firewall-cmd --list-all-zones
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
dmz
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
drop
target: DROP
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
external
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
forward: no
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
home
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client mdns samba-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
internal
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client mdns samba-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
trusted
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
work
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
6.2.6 --info-zone(查看单个区域详情)
- 用途:打印指定区域的完整信息。
- 语法:
firewall-cmd --info-zone=<zone> - 参数:
<zone>必填。
firewall-cmd --info-zone=public
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
6.2.7 --get-zone-of-interface(查看接口所属区域)
- 用途:查询指定接口当前绑定的区域。
- 语法:
firewall-cmd --get-zone-of-interface=<interface> - 参数:
<interface>接口名,如 eth0。
未绑定时的实测输出:
firewall-cmd --get-zone-of-interface=eth0
no zone
绑定后(见 6.4.2):
firewall-cmd --get-zone-of-interface=eth0
public
6.3 服务(service)类
6.3.1 --list-services(列出已放行服务)
- 用途:查看当前区域(默认 public)已放行的服务名。
- 语法:
firewall-cmd --list-services;指定区域用--zone=<zone> --list-services - 参数:无。
firewall-cmd --list-services
cockpit dhcpv6-client ssh
6.3.2 --add-service(放行服务)
- 用途:向区域添加一个服务(运行时生效)。
- 语法:
firewall-cmd [--zone=<zone>] --add-service=<service> [--permanent] [--timeout=<秒>] - 参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
<service> | 服务名,可用 --get-services 查询 | 必填 |
--zone=<zone> | 目标区域 | 默认区域 |
--permanent | 写入永久配置 | 否(仅运行时) |
--timeout=<秒> | 临时放行时长,到期自动移除(见 6.5.6) | 无 |
firewall-cmd --add-service=http
success
验证:
firewall-cmd --list-services
cockpit dhcpv6-client http ssh
6.3.3 --remove-service(移除服务)
- 用途:从区域移除服务放行规则。
- 语法:
firewall-cmd [--zone=<zone>] --remove-service=<service> [--permanent] - 参数:同
--add-service(无--timeout)。
firewall-cmd --remove-service=http
success
firewall-cmd --list-services
cockpit dhcpv6-client ssh
6.3.4 --query-service(查询服务是否放行)
- 用途:检查某服务是否已在区域中放行。
- 语法:
firewall-cmd [--zone=<zone>] --query-service=<service> - 返回:
yes/no(退出码 0 / 1)。
firewall-cmd --query-service=ssh
yes
firewall-cmd --query-service=http
no
firewall-cmd --add-service=http
firewall-cmd --query-service=http
success
yes
💡 脚本中常用
--query-service判断后再决定是否添加,避免重复添加告警。
6.3.5 --get-services(列出全部可用服务名)
- 用途:列出系统预置的全部服务名(含自定义)。
- 语法:
firewall-cmd --get-services - 参数:无。
- 实测输出(完整,共 176 个):
firewall-cmd --get-services
RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit collectd condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-apiserver ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nbd nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rquotad rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tftp-client tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
firewall-cmd --get-services | wc -w
176
💡 列表中常见服务:
http(TCP 80)、https(TCP 443)、ssh(TCP 22)、ftp、samba、mysql(TCP 3306)、postgresql(TCP 5432)、dns(TCP/UDP 53)、nfs、ntp、rsyncd、cockpit(TCP 9090)等。
6.4 端口(port)与接口类
6.4.1 --list-ports / --add-port / --remove-port / --query-port
- 用途:端口类规则直接按“端口/协议”放行,不依赖服务名。
- 语法:
firewall-cmd [--zone=<zone>] --list-ports
firewall-cmd [--zone=<zone>] --add-port=<port>[/<protocol>] [--permanent] [--timeout=<秒>]
firewall-cmd [--zone=<zone>] --remove-port=<port>[/<protocol>] [--permanent]
firewall-cmd [--zone=<zone>] --query-port=<port>[/<protocol>]
- 参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
<port> | 端口号(1-65535),可写区间如 8000-8010 | 必填 |
<protocol> | tcp / udp(可写 sctp、dccp) | 必填,无默认 |
--permanent | 写入永久配置 | 否 |
--timeout=<秒> | 临时放行时长 | 无 |
实测过程:
firewall-cmd --list-ports
(空)
firewall-cmd --add-port=8080/tcp
success
firewall-cmd --list-ports
8080/tcp
firewall-cmd --query-port=8080/tcp
yes
firewall-cmd --remove-port=8080/tcp
success
💡 UDP 端口写法相同:
firewall-cmd --add-port=53/udp。区间写法:firewall-cmd --add-port=8000-8010/tcp。
6.4.2 接口与区域绑定(--change-interface)
- 用途:把网络接口绑定到指定区域,使该接口流量套用区域策略。
- 语法:
firewall-cmd --change-interface=<interface> --zone=<zone>
firewall-cmd --change-interface=eth0 --zone=public
success
验证绑定结果:
firewall-cmd --get-active-zones
public
interfaces: eth0
firewall-cmd --get-zone-of-interface=eth0
public
💡
--change-interface是运行时行为(firewalld 重启后需重新绑定或写入配置文件/etc/firewalld/zones/public.xml的<interface name="eth0"/>标签)。
6.4.3 --zone=<zone>(指定区域)
- 用途:配合其他操作指定目标区域。默认操作 default zone(public)。
- 语法:
firewall-cmd --zone=<zone> --list-all - 实测(指定区域查看):
firewall-cmd --zone=public --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
6.5 持久化与重载类
6.5.1 --permanent(永久规则开关)
- 用途:配合添加/删除类命令,把规则写入磁盘永久配置。
- 语法:
firewall-cmd --permanent --add-service=<service>等;也可写作firewall-cmd --add-service=http --permanent。 - 注意:
--permanent修改后需--reload才写入运行时。
实测:
firewall-cmd --permanent --add-service=http
success
firewall-cmd --permanent --list-services
cockpit dhcpv6-client http ssh
firewall-cmd --permanent --add-port=9090/tcp
success
firewall-cmd --permanent --list-ports
9090/tcp
💡 此时仅改动了 XML 文件,运行时尚未生效——需执行
--reload。
6.5.2 --reload(重载并保留状态)
- 用途:重载防火墙,应用永久配置到运行时,同时保留已建立的连接状态和运行时规则。
- 语法:
firewall-cmd --reload - 实测(接 6.5.1):
firewall-cmd --reload
success
firewall-cmd --list-services
cockpit dhcpv6-client http ssh
firewall-cmd --list-ports
9090/tcp
💡 永久规则经
--reload后已生效。--reload不会中断现有连接(keep state)。
6.5.3 --complete-reload(完全重载)
- 用途:完全重载,丢失状态信息(现有连接可能中断),按永久配置重建全部规则。
- 语法:
firewall-cmd --complete-reload
firewall-cmd --complete-reload
success
⚠️ 生产环境慎用:会中断所有活跃连接(含 SSH)。
--reload与--complete-reload的区别即“是否保留状态信息”。
6.5.4 --runtime-to-permanent(运行时转永久)
- 用途:把当前全部运行时规则固化为永久规则(免去逐条加
--permanent)。 - 语法:
firewall-cmd --runtime-to-permanent
实测(先做两条运行时规则,再固化):
firewall-cmd --add-service=http
firewall-cmd --add-port=9090/tcp
firewall-cmd --runtime-to-permanent
success
success
success
firewall-cmd --permanent --list-services
firewall-cmd --permanent --list-ports
cockpit dhcpv6-client http ssh
9090/tcp
💡 该命令适合“先试运行、后固化”的工作流,但会把所有运行时规则(包括临时测试规则)一并固化,使用前先
--list-all检查。
6.5.5 --check-config(校验配置)
- 用途:检查永久配置是否有语法错误。
- 语法:
firewall-cmd --check-config - 返回:
success(有错误时输出具体错误并返回非 0)。
firewall-cmd --check-config
success
6.5.6 --timeout=<秒>(临时规则)
- 用途:放行规则仅在指定秒数内有效,到期自动移除,适合临时调试端口。
- 语法:
firewall-cmd --add-port=<port>/<protocol> --timeout=<秒>;--add-service=<service> --timeout=<秒>同理。 - 参数:
<秒>为正整数,表示规则存活时长;到期后规则自动消失,无需手动删除。
实测(timeout=30,等待 35 秒后自动消失):
firewall-cmd --add-port=8080/tcp --timeout=30
success
firewall-cmd --list-ports
8080/tcp
firewall-cmd --query-port=8080/tcp
yes
等待 35 秒后:
firewall-cmd --query-port=8080/tcp
no
firewall-cmd --list-ports
(空,timeout 到期规则自动移除)
实测(timeout=60,规则立即可查,可随时手动删除):
firewall-cmd --add-port=8080/tcp --timeout=60
success
firewall-cmd --list-ports
8080/tcp
firewall-cmd --remove-port=8080/tcp
success
💡
--timeout只能用于运行时规则,不能与--permanent同时使用;常用于临时开放某端口排查问题,到期自动清理,避免遗忘造成安全隐患。
6.6 富规则(rich rule)与高级管理
6.6.1 --add-rich-rule / --list-rich-rules / --remove-rich-rule
- 用途:富规则是 firewalld 的“高级规则语言”,可表达按源地址/目标地址/协议/端口的精细放行或拒绝。
- 语法:
firewall-cmd [--zone=<zone>] --add-rich-rule='rule [family="ipv4|ipv6"] [source address="<地址>"] [destination address="<地址>"] [service name="<服务>"] [port port="<端口>" protocol="<协议>"] [accept|reject|drop|mark]' [--permanent]
firewall-cmd [--zone=<zone>] --list-rich-rules
firewall-cmd [--zone=<zone>] --remove-rich-rule='<完整规则>'
实测(拒绝 192.168.1.10 的全部流量):
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.10" reject'
success
firewall-cmd --list-rich-rules
rule family="ipv4" source address="192.168.1.10" reject
firewall-cmd --remove-rich-rule='rule family="ipv4" source address="192.168.1.10" reject'
success
firewall-cmd --list-rich-rules
(空)
💡 常用富规则示例:
- 只放行某 IP 访问 22 端口:
rule family="ipv4" source address="10.0.0.5" port port="22" protocol="tcp" accept- 丢弃某网段:
rule family="ipv4" source address="192.168.2.0/24" drop- 记录并拒绝:
rule family="ipv4" source address="203.0.113.7" log prefix="BLOCKED " level="warning" reject
6.6.2 --panic-on / --panic-off / --query-panic(紧急模式)
- 用途:panic 模式会丢弃所有入站、出站、转发流量(紧急阻断,相当于物理拔线)。
- 语法:
firewall-cmd --panic-on(开启)、firewall-cmd --panic-off(关闭)、firewall-cmd --query-panic(查询)。
firewall-cmd --panic-on
success
firewall-cmd --query-panic
yes
firewall-cmd --panic-off
success
firewall-cmd --query-panic
no
⚠️
--panic-on会立刻中断所有网络连接(包括 SSH),仅在应急场景使用,使用后务必尽快--panic-off。
6.6.3 --get-log-denied / --set-log-denied(拒绝日志)
- 用途:配置/查看被拒绝报文的日志记录级别。
- 语法:
firewall-cmd --get-log-denied;firewall-cmd --set-log-denied=<value> - 参数值:
off/all/unicast/broadcast/multicast。
firewall-cmd --get-log-denied
off
firewall-cmd --set-log-denied=all
success
firewall-cmd --get-log-denied
all
firewall-cmd --set-log-denied=off
success
💡 开启后可在
/var/log/messages或journalctl中看到_DEFAULT_相关的 REJECT 日志,用于排查被拦截流量。
6.6.4 --get-icmptypes(列出 ICMP 类型)
- 用途:列出可用的 ICMP 类型(用于
--add-icmp-block等)。 - 语法:
firewall-cmd --get-icmptypes
firewall-cmd --get-icmptypes
address-unreachable bad-header beyond-scope communication-prohibited destination-unreachable echo-reply echo-request failed-policy fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable ip-header-bad neighbour-advertisement neighbour-solicitation network-prohibited network-redirect network-unknown network-unreachable no-route packet-too-big parameter-problem port-unreachable precedence-cutoff protocol-unreachable redirect reject-route required-option-missing router-advertisement router-solicitation source-quench source-route-failed time-exceeded timestamp-reply timestamp-request tos-host-redirect tos-host-unreachable tos-network-redirect tos-network-unreachable ttl-zero-during-reassembly ttl-zero-during-transit unknown-header-type unknown-option
6.6.5 firewall-offline-cmd(离线修改配置)
- 用途:firewalld 未运行时修改永久配置的命令行工具,用于误封自救等场景(见“常见问题”)。
- 语法:
firewall-offline-cmd <选项>,选项与firewall-cmd --permanent基本一致。
firewall-offline-cmd --version
0.9.3
示例(未运行状态下放行 ssh):
firewall-offline-cmd --add-service=ssh
💡 该命令直接修改
/etc/firewalld/下的 XML 永久配置,不要求 firewalld 服务在运行,适合 ssh 被封后从控制台/带外渠道自救。
6.7 综合状态查看 --list-all
- 用途:一次性查看当前区域全部规则(服务、端口、富规则、masquerade 等)。
- 语法:
firewall-cmd [--zone=<zone>] --list-all
firewall-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
字段含义:
| 字段 | 含义 |
|---|---|
target | 区域默认目标:default / ACCEPT / DROP / %%REJECT%% |
icmp-block-inversion | 是否反转 ICMP 阻止规则 |
interfaces | 绑定到该区域的接口 |
sources | 绑定到该区域的源地址/网段 |
services | 已放行服务 |
ports | 已放行端口/协议 |
protocols | 已放行协议 |
forward | 是否允许转发 |
masquerade | 是否启用 NAT 伪装 |
forward-ports | 端口转发规则 |
source-ports | 按源端口放行的规则 |
icmp-blocks | 被阻止的 ICMP 类型 |
rich rules | 富规则列表 |
七、实战演练
7.1 场景一:开放 HTTP 与自定义端口
需求:服务器运行 Web 服务(80 端口)与测试服务(8080 端口),需要放行入站访问。
# 放行 http 服务(运行时)
firewall-cmd --add-service=http
success
# 放行 8080/tcp(运行时)
firewall-cmd --add-port=8080/tcp
success
# 确认生效
firewall-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client http ssh
ports: 8080/tcp
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
确认无误后固化为永久规则:
firewall-cmd --runtime-to-permanent
success
7.2 场景二:拒绝指定 IP
需求:封禁恶意来源 192.168.1.10 的所有访问。
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.10" reject'
success
firewall-cmd --list-rich-rules
rule family="ipv4" source address="192.168.1.10" reject
💡 使用
reject(回显拒绝,客户端能立刻感知)还是drop(静默丢弃,客户端表现为超时)视需求而定;需要长期封禁时加--permanent。
7.3 场景三:验证策略真实生效(内核规则核查)
firewalld 是动态防火墙,规则最终下发到内核 nftables。核查方式:
nft list ruleset
实测节选(public 区域默认规则,INPUT 链):
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
}
...
}
添加 http 服务后,filter_IN_public 链中出现 dport 80 规则:
nft list ruleset | grep -B3 -A6 "dport 80"
tcp dport 22 ct state { new, untracked } accept
ip6 daddr fe80::/64 udp dport 546 ct state { new, untracked } accept
tcp dport 9090 ct state { new, untracked } accept
tcp dport 80 ct state { new, untracked } accept
}
chain filter_IN_public_post {
}
chain filter_FWDO_public {
💡 可以看到:TCP 22(ssh)、UDP 546(dhcpv6-client)、TCP 9090(cockpit)、TCP 80(http)的规则都在 nftables 的
filter_IN_public链中,与--list-all的 services 完全对应。
若使用 iptables 后端(FirewallBackend=iptables),则用:
iptables -L INPUT -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
💡 nftables 后端下 iptables 工具显示为空是正常的,规则实际在 nftables 中(
nft list ruleset查看)。
7.4 场景四:临时开放端口(定时自动回收)
需求:临时开放 8080 端口 60 秒排查问题,到期自动移除,不留隐患。
firewall-cmd --add-port=8080/tcp --timeout=60
success
firewall-cmd --query-port=8080/tcp
yes
60 秒后规则自动消失(无需人工清理):
firewall-cmd --query-port=8080/tcp
no
7.5 场景五:永久规则 + reload 全流程
标准操作流程(改配置 → reload → 验证 → 清理):
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-port=9090/tcp
firewall-cmd --reload
success
success
success
firewall-cmd --list-services
firewall-cmd --list-ports
cockpit dhcpv6-client http ssh
9090/tcp
清理(恢复初始状态):
firewall-cmd --permanent --remove-service=http
firewall-cmd --permanent --remove-port=9090/tcp
firewall-cmd --reload
success
success
success
firewall-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
八、systemd 服务管理
firewalld 以 firewalld.service 由 systemd 管理(Type=dbus,ExecStart=/usr/sbin/firewalld --nofork --nopid,ExecReload=/bin/kill -HUP $MAINPID)。常用操作如下,每行一个单元名:
systemctl enable firewalld
systemctl start firewalld
systemctl stop firewalld
systemctl restart firewalld
systemctl reload firewalld
systemctl status firewalld
systemctl is-active firewalld
systemctl is-enabled firewalld
实测回显:
systemctl is-active firewalld
active
systemctl is-enabled firewalld
enabled
systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-10-06 04:57:54 UTC; 30min ago
Docs: man:firewalld(1)
Main PID: 571 (firewalld)
Tasks: 2 (limit: 204581)
Memory: 26.5M
systemctl reload firewalld
(无输出,执行成功返回 0)
💡
systemctl reload firewalld向主进程发送 SIGHUP 触发重载,等价于firewall-cmd --reload的效果(保留状态信息)。
九、注意事项
⚠️ 以下为生产环境中的高频坑点:
- 先放行 SSH 再动防火墙:执行
systemctl enable --now firewalld、--set-default-zone、--panic-on前,务必确认 ssh 已在放行列表(firewall-cmd --query-service=ssh返回 yes),否则远程管理会话会立即中断。 - 运行时规则不持久:不带
--permanent添加的规则在 firewalld 重启后丢失(本文已实测验证:--add-service=http后systemctl restart firewalld,http 规则消失)。需要持久化时用--permanent+--reload,或--runtime-to-permanent。 --permanent不即时生效:只改永久配置后必须执行--reload(或重启)才会写入运行时;忘记 reload 是“改了不生效”的最常见原因。--reload与--complete-reload的区别:--reload保留状态信息与运行时规则,生产可安全使用;--complete-reload清空状态(可能中断 SSH),仅低峰期使用。CleanupOnExit=yes的双刃剑:systemctl stop firewalld会清空 firewalld 下发的全部内核规则(等于“裸奔”),不要用 stop 代替精细放行;卸载 firewalld 前也应评估网络暴露风险。- public 区域默认只放行 ssh、dhcpv6-client、cockpit:其他端口默认拒绝,新增服务请显式放行;启用 cockpit 会开放 TCP 9090。
- 注意协议写全:
--add-port=53/tcp只放行 TCP,DNS 还要--add-port=53/udp;服务方式(--add-service=dns)会自动放行 tcp+udp,更省心。 - Docker 部署冲突:docker 默认通过 iptables 管理端口映射与 NAT,与 firewalld 同机部署时可能出现 Docker 发布端口绕过防火墙、或 firewalld 重载清掉 docker 规则的问题(详见“常见问题”)。
- 多网卡/区域漂移:
AllowZoneDrifting=yes下接口与源地址归属会自动变化,多网卡网关请显式--change-interface绑定,避免流量意外套用宽松区域。
十、常见问题(FAQ)
10.1 firewalld 与 docker 冲突怎么办?
Docker 通过 iptables(或 nftables)自行管理 Docker 网络与端口映射,与 firewalld 同机时常见两类问题:
- Docker 发布端口绕过防火墙:docker-proxy 监听在宿主机
0.0.0.0,请求先被 docker 的 DNAT 规则转发,firewalld 的 INPUT 链放行规则不生效,表现为“防火墙封了端口却仍然能访问”。 - 重载导致规则被清:
firewall-cmd --reload刷新规则链时可能清掉 docker 的链/规则,导致 Docker 网络异常。
解决思路:
- 确认 docker 版本(≥20.10)并启用
iptables: true与 firewalld nftables 后端兼容; - 把 docker 网桥接口加入 trusted 区域:
firewall-cmd --permanent --zone=trusted --change-interface=docker0后--reload; - Docker 端口按“仅本机访问”设计,避免暴露到公网网卡;或用 docker 的
--publish 127.0.0.1:port:port只绑定回环地址; - 生产上如防火墙策略严格,可考虑让 docker 使用 userland-proxy 关闭(
dockerd --userland-proxy=false)并配合 direct rule 精确放行。
10.2 规则重启后丢失怎么办?
原因:添加规则时未加 --permanent,规则只在运行时层,firewalld 重启即清空(本文实测:重启后 --list-services 恢复为 cockpit dhcpv6-client ssh)。
解决:
# 方案一:重新添加并加 permanent
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
# 方案二:把当前运行时规则全部固化
firewall-cmd --runtime-to-permanent
10.3 误封 SSH,无法远程登录怎么办?
排查顺序:
- 直接放行(能通过控制台/带外登录时):
firewall-cmd --permanent --add-service=ssh && firewall-cmd --reload - firewalld 未运行/无法启动时:用
firewall-offline-cmd直接改永久配置:firewall-offline-cmd --add-service=ssh,然后启动 firewalld。 - 无法登录系统:通过云厂商控制台 VNC/IPMI 或机房带外管理进入,执行
systemctl stop firewalld或删除误加的富规则(firewall-offline-cmd --remove-rich-rule='...')。 - 误用
--panic-on:进入控制台执行firewall-cmd --panic-off。
💡 建议提前把管理网段加入 trusted 区域或单独放行 ssh 的源地址限制,降低误封风险。
10.4 --add-service 与 --add-port 有什么区别?
--add-service=http:放行名为 http 的服务,其定义(/usr/lib/firewalld/services/http.xml)里包含端口 80/tcp。服务可包含多个端口/协议(如samba含 137-139/udp、445/tcp),还可声明模块与目标。--add-port=8080/tcp:只放行单个端口+协议,无其他隐含规则。
结论:优先用服务(语义清晰、自动带多端口),内置无对应服务时用端口。
10.5 端口加了规则,外部仍然访问不通?
按以下顺序排查:
- 服务是否在监听:
ss -lntp(实测示例输出:LISTEN 0 128 0.0.0.0:22 ... users:(("sshd",pid=835,fd=3)))。端口没监听,防火墙放行也没用。 - 接口是否在正确的区域:
firewall-cmd --get-active-zones、firewall-cmd --get-zone-of-interface=eth0。 - 规则是否生效:
firewall-cmd --list-all(确认服务/端口在列)。 - 协议是否写对:tcp/udp 混淆(如
--add-port=53/tcp只放 TCP)。 - 是否被 SELinux/云安全组拦截:
getenforce查看,云环境还需检查安全组规则。 - 看日志:
journalctl -u firewalld、dmesg | grep -i drop。
10.6 --reload 与 --complete-reload 有什么区别?日常用哪个?
--reload:保留状态信息(established 连接不断),运行时规则保留,永久配置应用。日常增删规则后用这个。--complete-reload:丢弃全部状态,从永久配置完全重建,现有连接(含 SSH)可能中断。仅在需要彻底重建规则表(如规则混乱)时用。
10.7 如何查看被防火墙拦截的流量日志?
- 开启拒绝日志:
firewall-cmd --set-log-denied=all(级别可选 all/unicast/broadcast/multicast)。 - 查看日志:
journalctl -u firewalld | grep -i denied
dmesg | grep -i drop
tail -f /var/log/messages
💡
--set-log-denied=all会记录所有被拒流量,日志量较大,排障后建议恢复off。
10.8 如何清空所有规则恢复出厂?
firewall-cmd --complete-reload
--complete-reload 按永久配置重建;若永久配置也被改乱,可把 /etc/firewalld/ 下被改过的 XML 删除(保留 .xml.old 备份可用)后重启 firewalld,或重新安装 firewalld 恢复默认:
dnf reinstall -y firewalld
systemctl enable --now firewalld
十一、卸载方式
先停止并卸载(实测回显尾部节选):
systemctl stop firewalld
dnf remove -y firewalld
libnftnl-1.1.5-4.el8.x86_64
nftables-1:0.9.3-21.el8.x86_64
python3-decorator-4.2.1-2.el8.noarch
python3-firewall-0.9.3-7.el8.noarch
python3-gobject-base-3.28.3-2.el8.x86_64
python3-libselinux-2.9-5.el8.x86_64
python3-nftables-1:0.9.3-21.el8.x86_64
python3-pip-9.0.3-20.el8.noarch
python3-setuptools-39.2.0-6.el8.noarch
python3-slip-0.6.4-11.el8.noarch
python3-slip-dbus-0.6.4-11.el8.noarch
python3-systemd-234-8.el8.x86_64
python36-3.6.8-38.module_el8.5.0+895+a459eca8.x86_64
Complete!
⚠️
systemctl stop firewalld后CleanupOnExit=yes会清空其下发的内核规则,此时系统无防火墙保护;卸载后如需保留防护,请提前规划替代方案(如 nftables 原生规则或直接使用 iptables)。
如需保留配置但仅停止使用:
systemctl disable --now firewalld
十二、参考链接
- firewalld 官方文档:https://firewalld.org/
- firewall-cmd 手册:https://firewalld.org/documentation/man-pages/firewall-cmd.html
- firewalld.conf 手册:https://firewalld.org/documentation/man-pages/firewalld.conf.html
- firewalld zones 概念:https://firewalld.org/documentation/concepts.html
- firewalld rich language:https://firewalld.org/documentation/rich-language.html
- RHEL 8 安全指南(firewalld 章节):https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/using-and-configuring-firewalld
- nftables 官方 wiki:https://wiki.nftables.org/