firewalld 是 Linux 系统中一款动态防火墙管理工具,替代了传统的 iptables 静态配置方式,支持运行时配置与永久配置分离、区域(Zone)隔离、富规则(Rich Rule)等高级特性,广泛应用于 CentOS、RHEL、Fedora 等发行版。本教程基于 firewall-cmd 命令行工具,从基础概念到实战配置,详细讲解 firewalld 的使用方法,帮助运维人员快速掌握防火墙管理技能。
一、核心概念解析
在配置 Firewalld 前,需先理解其核心概念,避免配置混乱。
- 运行时配置与永久配置
运行时配置(Runtime):临时生效的配置,仅在当前 Firewalld 服务运行期间有效,重启服务或系统后会丢失。适用于配置测试场景。
永久配置(Permanent):需通过 --permanent 选项指定,配置保存在磁盘文件中,需重启 Firewalld 服务或重新加载配置后生效。适用于生产环境固定配置。
优先级:运行时配置优先级高于永久配置,重新加载配置(--reload)后,永久配置会覆盖运行时配置(未同步到永久配置的临时修改会丢失)。
- 区域(Zone)
区域是 Firewalld 的核心特性,用于划分不同安全级别的网络环境,每个区域可配置独立的防火墙规则,接口或源地址绑定到区域后,将应用该区域的规则。
常用预定义区域(优先级从高到低)
drop(丢弃):最高安全级别,丢弃所有入站流量,不返回任何响应,仅允许出站流量。
block(阻塞):拒绝所有入站流量,返回 ICMP 端口不可达响应,允许出站流量。
public(公共):默认区域,适用于公共网络,仅允许指定的入站服务(如 SSH)。
external(外部):适用于路由器外部网络,启用地址伪装(NAT),仅允许指定入站服务。
internal(内部):适用于路由器内部网络,信任级别较高,允许多数常见服务。
dmz(非军事区):适用于 DMZ 区域服务器,仅允许指定入站服务。
work(工作):适用于工作网络,信任同网段主机,允许常见服务。
home(家庭):适用于家庭网络,信任级别高,允许更多服务。
trusted(信任):最低安全级别,允许所有入站和出站流量。
- 策略(Policy)
策略是 Firewalld 提供的扩展流量控制机制,用于实现跨区域的流量规则,替代了已废弃的 Direct 接口。策略支持入站/出站区域绑定、优先级设置,可实现更灵活的流量管控(如跨区域服务访问控制)。
- 富规则(Rich Rule)
富规则用于配置复杂的防火墙规则,支持基于源地址、目标地址、端口、协议、日志、审计等条件的精细化控制,适用于无法通过简单服务/端口配置满足的场景(如 IPv6 端口转发、流量限制)。
二、Firewalld 基础操作
- 服务管理
Firewalld 服务的启动、停止、重启、状态查询是基础操作,确保服务正常运行是配置生效的前提。
启动 Firewalld 服务
systemctl start firewalld
停止 Firewalld 服务
systemctl stop firewalld
重启 Firewalld 服务(永久配置生效)
systemctl restart firewalld
查看 Firewalld 服务状态
systemctl status firewalld
设置 Firewalld 开机自启
systemctl enable firewalld
禁止 Firewalld 开机自启
systemctl disable firewalld
检查 Firewalld 守护进程是否活跃
firewall-cmd --state
- 配置重载
修改永久配置后,需通过重载配置使修改生效,避免重启服务导致现有连接中断。
重新加载配置(保留连接状态,推荐)
firewall-cmd --reload
完全重新加载(丢失连接状态,仅用于严重故障)
firewall-cmd --complete-reload
将运行时配置保存为永久配置
firewall-cmd --runtime-to-permanent
- 区域基础配置
区域配置是 Firewalld 的核心,包括默认区域设置、区域查询、接口/源地址绑定等。
查看当前默认区域
firewall-cmd --get-default-zone
设置默认区域(同时生效于运行时和永久配置)
firewall-cmd --set-default-zone=public
firewall-cmd --permanent --set-default-zone=public # 永久生效
查看所有活跃区域及绑定的接口/源地址
firewall-cmd --get-active-zones
查看指定区域的详细配置
firewall-cmd --info-zone=public
查看所有区域的配置
firewall-cmd --list-all-zones
绑定接口到指定区域(运行时)
firewall-cmd --zone=public --add-interface=eth0
永久绑定接口到指定区域
firewall-cmd --permanent --zone=public --add-interface=eth0
解除接口与区域的绑定
firewall-cmd --permanent --zone=public --remove-interface=eth0
绑定源地址到指定区域(运行时,仅允许该源地址访问)
firewall-cmd --zone=trusted --add-source=192.168.1.0/24
永久绑定源地址到指定区域
firewall-cmd --permanent --zone=trusted --add-source=192.168.1.0/24
三、常用规则配置实战
- 服务规则配置
Firewalld 预定义了大量常见服务(如 SSH、HTTP、HTTPS),可直接通过服务名配置允许访问规则,无需手动指定端口。
查看所有预定义服务
firewall-cmd --get-services
允许 HTTP 服务访问(运行时,默认区域)
firewall-cmd --add-service=http
永久允许 HTTP 服务访问(默认区域)
firewall-cmd --permanent --add-service=http
允许 HTTPS 服务访问(指定区域,运行时+永久)
firewall-cmd --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-service=https
移除 HTTP 服务访问权限(永久)
firewall-cmd --permanent --remove-service=http
查询是否允许 HTTP 服务访问
firewall-cmd --query-service=http
- 端口规则配置
对于非预定义服务,需通过端口+协议的方式配置规则,支持单个端口或端口范围。
允许单个端口访问(TCP 8080,运行时)
firewall-cmd --add-port=8080/tcp
永久允许端口范围访问(UDP 1000-2000,指定区域)
firewall-cmd --permanent --zone=public --add-port=1000-2000/udp
移除端口访问权限(永久)
firewall-cmd --permanent --remove-port=8080/tcp
查询端口是否允许访问
firewall-cmd --query-port=8080/tcp
临时开放端口(1小时后自动关闭,仅运行时)
firewall-cmd --add-port=9090/tcp --timeout=1h
- 协议规则配置
允许指定协议(如 ICMP、UDP)的流量通过防火墙,适用于非端口类协议场景。
允许 ICMP 协议访问(运行时,默认区域,即允许 ping)
firewall-cmd --add-protocol=icmp
永久允许 UDP 协议访问(指定区域)
firewall-cmd --permanent --zone=public --add-protocol=udp
移除 ICMP 协议访问权限(永久)
firewall-cmd --permanent --remove-protocol=icmp
查询协议是否允许访问
firewall-cmd --query-protocol=icmp
- 端口转发配置
Firewalld 支持 IPv4 端口转发,可将指定端口的流量转发到目标端口或目标主机,需先确保系统启用 IP 转发。
启用 IP 转发(临时)
echo "net.ipv4.ip_forward=1" >> /proc/sys/net/ipv4/ip_forward
永久启用 IP 转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
配置端口转发(将 80 端口流量转发到 8080 端口,运行时)
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
配置跨主机端口转发(将 80 端口流量转发到 192.168.1.100 的 8080 端口,永久)
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080
移除端口转发规则(永久)
firewall-cmd --permanent --remove-forward-port=port=80:proto=tcp:toport=8080
注:IPv6 端口转发需通过富规则实现,后续会详细讲解。
- 地址伪装(NAT)配置
地址伪装用于将内网主机的私有 IP 转换为外网 IP,实现内网主机访问互联网,适用于路由器场景。
启用地址伪装(运行时,指定外部区域)
firewall-cmd --zone=external --add-masquerade
永久启用地址伪装(指定外部区域)
firewall-cmd --permanent --zone=external --add-masquerade
禁用地址伪装(永久)
firewall-cmd --permanent --zone=external --remove-masquerade
查询是否启用地址伪装
firewall-cmd --zone=external --query-masquerade
- 富规则配置
富规则支持复杂的流量控制,以下为常见场景示例,语法细节可参考 firewalld.richlanguage(5) 手册。
1. 允许特定源地址访问指定端口(允许 192.168.1.10 访问 22 端口,永久)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.10" port protocol="tcp" port="22" accept'
2. 拒绝特定源地址访问所有服务(拒绝 10.0.0.0/8 网段,永久)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" reject'
3. 配置 IPv6 端口转发(将 [::1]:80 转发到 [::1]:8080,永久)
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" forward-port port="80" protocol="tcp" to-port="8080"'
4. 启用日志记录(记录拒绝的流量,永久)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" log prefix="FIREWALL_DENY: " level="warning" reject'
5. 移除富规则(永久)
firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.10" port protocol="tcp" port="22" accept'
查看已配置的富规则
firewall-cmd --list-rich-rules
- 策略配置(替代 Direct 接口)
策略用于跨区域流量控制,需指定入站/出站区域和优先级,以下为配置示例。
1. 创建新策略(永久)
firewall-cmd --permanent --new-policy=clientConntrack
2. 为策略绑定入站/出站区域(入站为本地主机,出站为任意区域,永久)
firewall-cmd --permanent --policy=clientConntrack --add-ingress-zone=HOST
firewall-cmd --permanent --policy=clientConntrack --add-egress-zone=ANY
3. 为策略添加服务(允许 TFTP 服务,永久)
firewall-cmd --permanent --policy=clientConntrack --add-service=tftp
4. 设置策略优先级(优先级 -5,高于区域规则,永久)
firewall-cmd --permanent --policy=clientConntrack --set-priority=-5
5. 查看策略详细信息
firewall-cmd --permanent --info-policy=clientConntrack
6. 删除策略(永久)
firewall-cmd --permanent --delete-policy=clientConntrack
四、高级配置场景
- 锁定模式(Lockdown)配置
锁定模式用于限制只有白名单中的应用/用户才能修改防火墙配置,增强安全性。
启用锁定模式(运行时+永久,谨慎使用)
firewall-cmd --lockdown-on
firewall-cmd --permanent --lockdown-on
禁用锁定模式
firewall-cmd --lockdown-off
firewall-cmd --permanent --lockdown-off
添加命令到白名单(允许 firewall-cmd 命令修改配置,永久)
firewall-cmd --permanent --add-lockdown-whitelist-command=/usr/bin/firewall-cmd
添加用户到白名单(允许 root 用户修改配置,永久)
firewall-cmd --permanent --add-lockdown-whitelist-user=root
查看白名单
firewall-cmd --list-lockdown-whitelist-commands
firewall-cmd --list-lockdown-whitelist-users
注:启用锁定模式前,务必将 firewall-cmd 命令和管理员用户加入白名单,否则会无法修改配置。
- 应急模式(Panic)配置
应急模式会丢弃所有入站和出站流量,适用于网络被攻击等紧急场景。
启用应急模式(仅运行时,重启服务后失效)
firewall-cmd --panic-on
禁用应急模式
firewall-cmd --panic-off
查询是否启用应急模式
firewall-cmd --query-panic
- IP 集合(ipset)配置
ipset 用于高效管理一组 IP 地址/端口,适用于批量配置规则场景。
1. 创建新的 ipset 集合(永久,哈希类型,IPv4)
firewall-cmd --permanent --new-ipset=trusted_ips --type=hash:net --family=inet
2. 向集合添加 IP 地址(永久)
firewall-cmd --permanent --ipset=trusted_ips --add-entry=192.168.1.0/24
firewall-cmd --permanent --ipset=trusted_ips --add-entry=172.16.0.0/16
3. 批量添加 IP 地址(从文件导入,永久)
echo "192.168.2.0/24" > /tmp/ips.txt
firewall-cmd --permanent --ipset=trusted_ips --add-entries-from-file=/tmp/ips.txt
4. 允许集合中的 IP 访问 SSH 端口(永久,通过富规则)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source ipset="trusted_ips" port protocol="tcp" port="22" accept'
5. 查看 ipset 集合信息
firewall-cmd --permanent --info-ipset=trusted_ips
6. 删除 ipset 集合(永久)
firewall-cmd --permanent --delete-ipset=trusted_ips
五. 查看防火墙规则
若需验证配置的规则是否正确,可通过以下命令查看底层 iptables 规则:
查看 IPv4 防火墙规则
iptables -L -n
查看 IPv6 防火墙规则
ip6tables -L -n
查看 Firewalld 生成的规则文件
cat /etc/firewalld/zones/public.xml # 默认区域规则文件
六、参考资料
firewalld 官方文档:http://fedoraproject.org/wiki/FirewallD
firewall-cmd 手册:man firewall-cmd
富规则语法手册:man firewalld.richlanguage
策略配置手册:man firewalld.policies