适用场景
Firewalld 防火墙配置适用于使用 CentOS 7/8/9、RHEL、Fedora、Rocky Linux 等发行版的服务器运维场景。相比传统 iptables 直接操作规则链,Firewalld 提供 zone(区域)化管理,规则修改即时生效且支持持久化,适合 Web 服务器、数据库服务器、堡垒机等需要精细化端口控制的场景,也适合应急封禁攻击源 IP 的日常安全运维。
前置条件
- 系统已安装 firewalld(
yum install firewalld或dnf install firewalld) - root 或 sudo 权限
- 网络环境可远程登录(配置防火墙前确认 SSH 端口已放行,避免把自己锁在门外)
原理说明
Firewalld 基于 zone 概念管理规则:每个网络接口属于一个区域(默认 public),区域定义该接口上允许与拒绝的流量。规则区分为 runtime(临时生效) 与 permanent(持久化) 两种状态,前者立即生效、重启丢失,后者写入配置文件、重启保留,两条命令需分别执行。规则类型包括 service(预定义服务)、port(端口/端口范围)、rich rule(条件丰富的细粒度规则)与 ipset(IP 集合批量管理)。
操作步骤
1. 启动并查看基本状态
systemctl enable --now firewalld
systemctl status firewalld --no-pager
# 查看默认区域与当前规则
firewall-cmd --get-default-zone
firewall-cmd --list-all
2. 放行服务与端口
# 放行预定义服务(HTTP/HTTPS/SSH)
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ssh
# 放行指定端口与端口范围
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --permanent --add-port=10000-20000/udp
# 应用永久规则(runtime 立即生效,无需 reload)
firewall-cmd --reload
firewall-cmd --list-all
3. 移除规则与临时放行
# 移除端口(临时+永久均需操作)
firewall-cmd --remove-port=8080/tcp
firewall-cmd --permanent --remove-port=8080/tcp
# 仅临时放行(重启失效),适合短时调试
firewall-cmd --add-port=9000/tcp
4. 封禁攻击 IP 与网段
# 应急封禁单个 IP(立即生效)
firewall-cmd --add-rich-rule='rule family="ipv4" source address="203.0.113.66" drop'
# 持久化封禁并添加日志
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" log prefix="BLOCKED: " level=info drop'
firewall-cmd --reload
# 查看与移除 rich rule
firewall-cmd --list-rich-rules
firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="203.0.113.0/24" log prefix="BLOCKED: " level=info drop'
5. 使用 ipset 批量管理攻击 IP 列表
# 创建 ipset 集合(maxelem 为容量上限)
firewall-cmd --permanent --new-ipset=attackips --type=hash:ip --option=maxelem=100000
# 集合初始条目写入 /etc/firewalld/ipsets/attackips.xml
# 添加攻击 IP 到集合
firewall-cmd --ipset=attackips --add-entry=198.51.100.23
firewall-cmd --permanent --ipset=attackips --add-entry=198.51.100.23
# 将集合引用为丢弃源
firewall-cmd --permanent --add-rich-rule='rule source ipset="attackips" drop'
firewall-cmd --reload
# 查看集合与规则
firewall-cmd --ipset=attackips --get-entries
6. 配置区域与端口转发
# 将网卡绑定到 dmz 区域
firewall-cmd --permanent --zone=dmz --add-interface=eth0
firewall-cmd --reload
# 端口转发:本机 8443 转发到内网 10.0.0.5 的 443
firewall-cmd --permanent --zone=public --add-forward-port=port=8443:proto=tcp:toport=443:toaddr=10.0.0.5
# 开启内核转发
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf && sysctl -p
firewall-cmd --reload
配置验证
# 查看所有区域的完整规则
firewall-cmd --list-all-zones
# 本地验证端口放行
ss -lntup | grep 8080
# 外部验证:本机执行
nc -vz 服务器IP 8080
# 验证 IP 封禁生效(用被封 IP 访问应超时/拒绝)
firewall-cmd --list-rich-rules | grep 203.0.113.66
# 验证持久化配置
grep -r "8080" /etc/firewalld/zones/public.xml
常见问题
FAQ 1:永久规则不生效?
原因通常是只执行了 --permanent 参数而未执行 firewall-cmd --reload 或未加 --permanent 的临时规则没被持久化。Firewalld 的临时与永久规则相互独立,两条命令必须分别执行,改完永久规则后统一 reload。
FAQ 2:封禁了 IP 但攻击仍能访问?
先检查是否存在 CDN/负载均衡,攻击源实际是 CDN 回源节点 IP 而非真实客户端 IP。其次确认 rich rule 添加到了 正确的 zone(网卡实际绑定的 zone)。最后用 firewall-cmd --list-rich-rules 核对规则未被后续规则覆盖。
FAQ 3:firewalld 与 iptables 服务冲突怎么办?
两者不能同时启用。CentOS 7+ 默认使用 firewalld,若系统残留 iptables 服务需先停用:systemctl stop iptables && systemctl disable iptables。firewalld 底层仍是 nftables/iptables,规则可互相转换,但管理入口只能二选一。
总结
Firewalld 防火墙配置的核心是掌握 zone、runtime/permanent 双模式与 rich rule 三种语法:日常放行用 --add-service/--add-port,应急封禁用 --add-rich-rule,批量管理用 ipset。配合”先临时后永久、改完必 reload”的操作习惯,可快速构建安全、可审计的服务器边界防护。若需要更复杂的 NAT、流量标记能力,可在此基础上补充 nftables 规则实现。