firewalld 简介
- 内容
了解
firewalld这款用于保障 Linux 服务器和服务安全的重要工具。它是许多现代 Linux 发行套件中默认的主要网络防御机制。其基于区域的直观管理方式和动态配置功能可在不中断服务的前提下实现对网络流量的精确控制。- 原因
firewalld至关重要,因为它通过将复杂的防火墙规则抽象为直观的区域和服务,为 Linux 系统提供了现代化、动态且易用的网络安全管理方式。- 工作量
读完本文最多需要 30 分钟。
- 目标
有效管理并提升 Linux 系统的安全性。
- 要求
拥有
sudo或root权限,因为firewalld命令(尤其是对防火墙规则进行永久性更改的命令)需要高级权限。系统中需安装
firewalld,它是许多现代 Linux 发行套件的默认防火墙,如果系统中未预装,您需要安装firewalld软件包。基本了解 Linux 终端:这是操作的基础。
1 关于 firewalld #
firewalld 是一款动态防火墙管理服务,为 Linux 系统提供灵活高效的网络流量控制方式。它可在不中断现有连接的情况下修改配置。使用 firewalld 的优势如下:
动态配置:即时应用更改,而不中断现有连接。
易用界面:通过区域和服务简化复杂的防火墙规则。
抽象化:普通场景下无需直接操作
nftables规则。持久化配置:轻松管理系统重引导后仍生效的规则。
持久化配置:
firewalld默认采用deny-all策略,除非明确允许,否则会阻止所有传入流量。
1.1 firewalld 区域 #
防火墙区域是一组预定义规则,用于指定特定网络接口或来源 IP 地址的传入和传出网络流量处理方式。每个区域代表与其关联的网络的不同信任级别。可根据网络连接的来源应用不同的安全策略。
区域类似于安全配置文件。例如,对于公共 Wi-Fi 连接和安全的家庭网络,您可能需要应用不同的防火墙规则。firewalld 区域允许您定义并相应应用这些不同的规则集。一个网络连接仅受一个 firewalld 区域的规则约束,而一个 firewalld 区域可关联多个网络接口或来源 IP 地址。
预定义区域存储在 /usr/lib/firewalld/zones/ 目录中。例如:
> /usr/lib/firewalld/zones ls
block.xml dmz.xml docker.xml drop.xml external.xml home.xml internal.xml nm-shared.xml public.xml trusted.xml work.xml以下是部分预定义区域的默认设置:
-
drop 信任级别:完全不可信。
行为:所有传入网络数据包均被丢弃且不回复。仅允许系统主动发起的传出连接。这种“隐身”模式可使系统在外部攻击者眼中呈现不存在的状态。
适用场景:用于实现最高级别的隐身性和安全性,完全忽略不必要的流量。适合作为严格的服务器默认配置,此类服务器不应接受任何传入连接。
-
block 信任级别:极低。
行为:所有传入网络连接都会被拒绝,对 IPv4 发送
icmp-host-prohibited消息,对 IPv6 发送icmp6-adm-prohibited消息,以此告知发送方其连接已被明确拒绝。仅允许系统主动发起的传出连接。适用场景:希望明确告知发送方其连接尝试被阻止时使用。
-
public 信任级别:不可信或公共。
行为:代表公共、不可信的网络,在此网络中您无法信任其他系统。默认仅允许部分传入连接,例如 SSH、DHCPv6 客户端等。
适用场景:通常作为直接连接互联网的接口(如路由器的 WAN 接口)的默认区域,也适用于连接到您无法控制其他设备的网络的场景。
-
external 信任级别:具有伪装功能的外部网络。
行为:适用于防火墙作为网关或路由器时的外部网络。默认通常启用 NAT 伪装功能。仅允许部分传入连接,前提是您无法信任该网络中的其他系统。
适用场景:当 Linux 计算机作为路由器,将内部专用网络连接到公共互联网时使用。将外部接口置于此区域可隐藏内部网络拓扑,同时允许内部客户端访问互联网等外部资源。
-
dmz (Demilitarized Zone) 信任级别:有限公共访问权限。
行为:适用于隔离区中可公开访问但对内部网络的访问受限的系统。仅允许部分传入连接。默认通常包括 SSH 及您对外开放的其他服务。
适用场景:适合 Web 服务器、邮件服务器、DNS 服务器等面向公众的服务器。这些服务器有意在互联网中公开,但与内部更可信的网络隔离。当您想要托管需要能够访问互联网的服务,同时希望最大限度地降低核心内部基础架构风险时非常有用。
-
work 信任级别:基本可信(工作环境)。
行为:在工作环境中,您通常信任网络中的其他计算机。允许工作环境中常见的部分传入连接,例如 SSH、DHCPv6 客户端等。
适用场景:适合办公网络和企业 LAN 中的系统。
-
home 信任级别:基本可信(家庭环境)。
行为:在家庭环境中,您通常信任网络中的其他系统。相比 public 或 external 区域,此区域允许更多服务,除 SSH、DHCPv6 客户端外,通常还包括文件共享、媒体服务器、打印机等常见家庭网络服务。
适用场景:最适合家庭网络和小型家庭办公环境。
-
trusted 信任级别:最高。
行为:接受所有网络连接,不进行过滤。对分配到此区域的连接不实施防火墙功能。
适用场景:保留给高度可信的连接。
1.2 firewalld 策略和规则 #
与传统区域相比,firewalld 策略提供更高级、更灵活的网络流量管理方式。您可以定义丰富的规则,指定流量的来源、目的地、服务、端口以及允许、拒绝、丢弃等操作。这些策略适用于设置复杂路由、端口转发,或在单台主机内创建隔离的网段。
firewalld 策略借助区域定义规则集。规则以有状态方式单向应用 - 即您只需定义一个方向的流量流向,firewalld 会自动允许返回路径的流量。这些策略将入站区域(流量进入的区域)与出站区域(流量离开的区域)关联,以此定义策略规则适用的特定路径和方向。例如,可通过以下方式查看策略:
> /usr/lib/firewalld/policies ls
allow-host-ipv6.xml防火墙规则可精确控制网络流量,通过允许或阻止流量保护系统免受安全威胁的侵扰。防火墙规则根据来源 IP 地址、目标 IP 地址、端口、网络接口等多种属性定义特定条件。firewalld 会将防火墙规则划分到区域和策略中。firewalld 中的每个区域都有一组独特的规则,用于指定其关联网络接口的流量权限。
1.3 服务和端口 #
当存在预定义服务时,建议优先使用服务。例如,无需记住 HTTP 使用 TCP 80 端口,只需添加 http 服务即可。这种方式更不易出错,且更便于管理。当服务无预定义配置,或为服务使用自定义端口时,可直接使用端口。通过以下命令可查看默认区域的活跃服务和端口:
>sudofirewall-cmd --list-services
>sudofirewall-cmd --list-ports
2 管理防火墙规则和区域 #
您可以通过图形 Web 界面 Cockpit 或命令行实用程序 firewall-cmd 配置 firewalld 区域及其规则。
2.1 使用 firewalld-cmd 实用程序管理防火墙规则和区域 #
可通过命令行界面管理 firewalld 区域。
2.1.1 添加 firewalld 区域 #
要添加新 firewalld 区域,请执行以下步骤:
创建新区域,例如:
>sudofirewall-cmd --permanent --new-zone=test设置区域的信任级别以定义默认行为:
>sudofirewall-cmd --permanent --zone=example --set-target=trusted重新加载
firewalld服务以应用新配置:>sudofirewall-cmd --reload
2.1.2 向区域添加服务 #
要向区域添加服务,请执行以下步骤:
列出所有服务,确认您需要的服务是否已预定义:
>sudofirewall-cmd --get-services0-AD RH-Satellite-6 RH-Satellite-6-capsule afp alvr amanda-client amanda-k5-client amqp amqps anno-1602 anno-1800 apcupsd audit ausweisapp2 bacula bacula-client bareos-director bareos-filedaemon bareos-storage bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-exporter ceph-mon cfengine checkmk-agent civilization-iv civilization-v cockpit collectd condor-collector cratedb ctdb dds dds-multicast dds-unicast dhcp dhcpv6 dhcpv6-client distcc dns dns-over-quic dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server factorio finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git gpsd grafana gre http http3 https ident imap imaps ipfs ipp ipp-client ipsec irc ircs [...]可临时为运行时会话添加服务,也可永久添加服务,例如:
>sudofirewall-cmd --zone=public --add-service=http>sudofirewall-cmd --zone=public --permanent --add-service=http--permanent标志可确保无论系统重引导多少次,更改都仍然生效。重新加载
firewalld服务以应用新配置:>sudofirewall-cmd --reload查看结果:
>sudofirewall-cmd --zone=public --list-services
2.1.3 向区域添加端口 #
如果应用程序无预定义服务,可开放特定端口或端口范围。
可临时为运行时会话添加端口,也可永久添加端口,例如:
>sudofirewall-cmd --zone=public --add-port=8080/tcp>sudofirewall-cmd --zone=public --permanent --add-port=8080/tcp--permanent标志可确保无论系统重引导多少次,更改都仍然生效。重新加载
firewalld服务以应用新配置:>sudofirewall-cmd --reload查看结果:
>sudofirewall-cmd --zone=public --list-ports
2.1.4 删除 firewalld 区域 #
要删除某个区域,请执行以下操作:
确认该区域不是默认区域且未被使用:
>sudofirewall-cmd --get-default-zone如果该区域已被使用或为默认区域,需要先将其他区域设置为默认区域,例如:
>sudofirewall-cmd --set-default-zone=NEW_DEFAULT_ZONE检查是否有网络接口绑定到该区域:
>sudofirewall-cmd --zone=ZONE_TO_BE_DELETED --list-all输出结果中的
interfaces字段会列出所有绑定的接口。需要将这些接口重新分配到其他区域,例如:>sudofirewall-cmd --zone=public --permanent --change-interface=ITERFACE_NAME删除区域:
>sudofirewall-cmd --permanent --delete-zone=ZONE_TO_BE_DELETED重新加载
firewalld服务以应用新配置:>sudofirewall-cmd --reload
2.2 使用 Cockpit 管理防火墙规则和区域 #
Cockpit 允许您创建新区域或更新现有区域。在防火墙设置中,可以向区域添加服务或允许访问端口。
请不要从默认防火墙区域中去除 Cockpit 服务,因为这可能会阻止 Cockpit 服务,导致您从服务器断开连接。
2.2.1 添加防火墙区域 #
是默认的防火墙区域。要添加新区域,请执行以下步骤:
导航到页面。
单击。
单击。
选择。网络连接的每个信任级别都有一组预定义的包含服务(Cockpit 服务包含在所有信任级别中)。
定义区域内允许的地址。选择以下值之一:
,表示允许子网中的所有地址。
- 一系列包含路由前缀的 IP 地址(用逗号分隔),例如 192.0.2.0/24, 2001:db8::/32。
单击继续。
2.2.2 将允许的服务和端口添加到区域 #
可如下所述将服务添加到现有的防火墙区域:
导航到页面。
单击。
单击。
要添加服务,请选中,然后从列表中选择所需服务。
要允许自定义端口,请选中并指定 UDP 和/或 TCP 端口值。可为此端口指派标识符。
要确认更改,请相应地单击或。
3 常用 firewalld 命令 #
firewall-cmd 命令行工具用于配置和管理 firewalld 守护程序。这是一款功能强大的动态工具,支持创建、修改和删除防火墙规则,且执行这些操作时无需重启整个服务,因而可避免活跃的网络连接中断。
以下是部分常用 firewall-cmd 命令示例:
检查
firewalld运行状态。输出结果为running、not running或RUNNING_BUT_FAILED。例如:>sudofirewall-cmd --staterunning列出所有可用区域,例如:
>sudofirewall-cmd --get-zonesblock dmz docker drop external home internal nm-shared public trusted work查看默认区域,例如:
>sudofirewall-cmd --get-default-zonepublic查看活跃区域及分配的接口,例如:
>sudofirewall-cmd --get-active-zonesdocker interfaces: docker0 public (default) interfaces: lo enp1s0查看默认区域的所有规则,例如:
>sudofirewall-cmd --list-allpublic (default, active) target: default ingress-priority: 0 egress-priority: 0 icmp-block-inversion: no interfaces: enp1s0 lo sources: services: cockpit dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.1.100" service name="ssh" accept查看特定区域的所有规则,例如:
>sudofirewall-cmd --zone=public --list-allpublic (default, active) target: default ingress-priority: 0 egress-priority: 0 icmp-block-inversion: no interfaces: enp1s0 lo sources: services: cockpit dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.1.100" service name="ssh" accept列出所有可用的预定义服务,例如:
>sudofirewall-cmd --get-services0-AD RH-Satellite-6 RH-Satellite-6-capsule afp alvr amanda-client amanda-k5-client amqp amqps anno-1602 anno-1800 apcupsd audit ausweisapp2 bacula bacula-client bareos-director bareos-filedaemon bareos-storage bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-exporter ceph-mon cfengine checkmk-agent civilization-iv civilization-v cockpit collectd condor-collector cratedb ctdb dds dds-multicast dds-unicast dhcp dhcpv6 dhcpv6-client distcc dns dns-over-quic dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server factorio finger foreman foreman-proxy freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp galera ganglia-client ganglia-master git gpsd grafana gre http http3 https ident imap imaps ipfs ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell kube-api kube-apiserver kube-control-plane kube-control-plane-secure kube-controller-manager kube-controller-manager-secure kube-nodeport-services kube-scheduler kube-scheduler-secure [...]列出默认区域中当前允许的服务,例如:
>sudofirewall-cmd --list-servicescockpit dhcpv6-client ssh向默认区域永久添加服务,例如:
>sudofirewall-cmd --permanent --add-service=httpsuccess永久去除服务,例如:
>sudofirewall-cmd --permanent --remove-service=httpsuccess列出默认区域中当前开放的端口,例如:
>sudofirewall-cmd --list-ports22/tcp临时开放特定 TCP 端口,例如:
>sudofirewall-cmd --add-port=8080/tcpsuccess永久去除开放的端口,例如:
>sudofirewall-cmd --permanent --remove-port=8080/tcpsuccess临时将接口添加到特定区域,例如:
>sudofirewall-cmd --zone=trusted --add-interface=eth1success
4 firewalld 查错 #
firewalld 查错涉及检查服务状态、验证规则、重启或重新加载服务。如果遇到问题,可启用调试模式、查看日志,并根据需要调整防火墙规则。
4.1 检查 firewalld 状态 #
使用
systemctl status命令查看状态,例如:>sudosystemctl status firewalld.service● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: enabled) Active: active (running) since Thu 2025-07-17 09:47:36 CEST; 5min ago Invocation: a7ea482f16d2431fa92d6204c297ebd9 Docs: man:firewalld(1) Main PID: 921 (firewalld) Tasks: 2 CPU: 262ms CGroup: /system.slice/firewalld.service └─921 /usr/bin/python3.13 /usr/sbin/firewalld --nofork --nopid使用
firewall-cmd --state命令可快速查看状态,输出结果为running、not running或RUNNING_BUT_FAILED。例如:>sudofirewall-cmd --staterunning如果
firewalld未运行,则使用systemctl start firewalld命令将其启动。>sudosystemctl start firewalld如果
firewalld服务被屏蔽,需先解除屏蔽,然后再启用并启动服务,例如:>sudosystemctl unmask --now firewalld>sudosystemctl enable firewalld>sudosystemctl start firewalld
4.2 检查 firewalld 规则 #
firewall-cmd --list-all-zones命令可显示所有区域及其规则,例如:>sudofirewall-cmd --list-all-zonesblock target: %%REJECT%% ingress-priority: 0 egress-priority: 0 icmp-block-inversion: no interfaces: sources: services: ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: dmz target: default ingress-priority: 0 egress-priority: 0 icmp-block-inversion: no interfaces: sources: services: ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: docker (active) target: ACCEPT ingress-priority: 0 egress-priority: 0 icmp-block-inversion: no [...]firewall-cmd --list-ports命令可查看开放的端口,例如:>sudofirewall-cmd --list-ports22/tcpfirewall-cmd --zone=YOUR_ZONE --list-all.命令可查看特定区域的端口,例如:>sudofirewall-cmd --zone=dmz --list-alldmz target: default ingress-priority: 0 egress-priority: 0 icmp-block-inversion: no interfaces: sources: services: ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
4.3 调试 firewalld #
在
/etc/sysconfig/firewalld中,通过向FIREWALLD_ARGS添加‑‑debug=[level]启用调试模式,例如:>sudovi /etc/sysconfig/firewalld # firewalld command line args # possible values: --debug FIREWALLD_ARGS=--debug=[level]通过
--debug选项启动firewalld,例如:>sudofirewalld --nofork --debug2025-07-23 11:10:05 DEBUG1: start() 2025-07-23 11:10:05 DEBUG1: Loading firewalld config file '/etc/firewalld/firewalld.conf' 2025-07-23 11:10:05 DEBUG1: CleanupOnExit is set to 'True' 2025-07-23 11:10:05 DEBUG1: CleanupModulesOnExit is set to 'False' 2025-07-23 11:10:05 DEBUG1: IPv6 rpfilter is enabled 2025-07-23 11:10:05 DEBUG1: LogDenied is set to 'off' 2025-07-23 11:10:05 DEBUG1: FirewallBackend is set to 'nftables' 2025-07-23 11:10:05 DEBUG1: FlushAllOnReload is set to 'False' 2025-07-23 11:10:05 DEBUG1: RFC3964_IPv4 is set to 'True' 2025-07-23 11:10:05 DEBUG1: NftablesFlowtable is set to 'off' 2025-07-23 11:10:05 DEBUG1: NftablesCounters is set to 'False' 2025-07-23 11:10:05 DEBUG1: Loading lockdown whitelist 2025-07-23 11:10:05 ipset not usable, disabling ipset usage in firewall. Other set backends (nftables) remain usable. 2025-07-23 11:10:05 iptables-restore and iptables are missing, IPv4 direct rules won't be usable. 2025-07-23 11:10:05 ip6tables-restore and ip6tables are missing, IPv6 direct rules won't be usable. 2025-07-23 11:10:05 ebtables-restore and ebtables are missing, eb direct rules won't be usable. 2025-07-23 11:10:05 DEBUG1: Loading icmptype file '/usr/lib/firewalld/icmptypes/address-unreachable.xml' 2025-07-23 11:10:05 DEBUG1: Loading icmptype file '/usr/lib/firewalld/icmptypes/bad-header.xml' 2025-07-23 11:10:05 DEBUG1: Loading icmptype file '/usr/lib/firewalld/icmptypes/beyond-scope.xml' 2025-07-23 11:10:05 DEBUG1: Loading icmptype file '/usr/lib/firewalld/icmptypes/communication-prohibited.xml' 2025-07-23 11:10:05 DEBUG1: Loading icmptype file '/usr/lib/firewalld/icmptypes/destination-unreachable.xml' [...]所有日志文件均存储在
/var/log/firewalld中。
5 更多信息 #
有关 firewalld 的详细信息,请参考以下资源:
6 法律声明 #
版权所有© 2006–2025 SUSE LLC 和撰稿人。保留所有权利。
根据 GNU 自由文档许可证 (GNU Free Documentation License) 版本 1.2 或(根据您的选择)版本 1.3 中的条款,在此授予您复制、分发和/或修改本文档的权限;本版权声明和许可证附带不可变部分。许可版本 1.2 的副本包含在“GNU Free Documentation License”部分。
有关 SUSE 商标,请参见 https://www.suse.com/company/legal/。所有其他第三方商标分别为相应所有者的财产。商标符号(®、™ 等)代表 SUSE 及其关联公司的商标。星号 (*) 代表第三方商标。
本指南力求涵盖所有细节,但这不能确保本指南准确无误。SUSE LLC 及其关联公司、作者和译者对于可能出现的错误或由此造成的后果皆不承担责任。