怎么优化 firewalld 配置减少 CPU 占用率提升吞吐量

文章导读
对于大多数高吞吐场景,将 firewalld 后端切换为 nftables 并精简规则集是降低 CPU 占用的主要方向,但如果机器位于可信内网或前端已有硬件防火墙,直接停用服务效果最明显。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

对于大多数高吞吐场景,将 firewalld 后端切换为 nftables 并精简规则集是降低 CPU 占用的主要方向,但如果机器位于可信内网或前端已有硬件防火墙,直接停用服务效果最明显。

先说结论:优化 firewalld 性能的核心在于减少内核态规则匹配开销,而非单纯调整软件参数。

  • 先定位:确认当前后端是 iptables 还是 nftables,以及 CPU 消耗是否真的来自 firewalld 进程或其触发的内核操作。
  • 先做:移除冗余规则、关闭非必要日志、确认是否可停用服务。
  • 再验证:通过系统负载监控和网络吞吐测试确认变化,避免安全策略失效。

命令速用版

如果你需要快速检查当前状态或临时测试,可以使用以下命令:

# 查看 firewalld 使用的后端(nftables 通常性能更好)
firewall-cmd `--get-backend`

# 查看当前规则数量概览(规则越多,匹配开销越大)
firewall-cmd `--list-all`

# 临时停止服务测试性能影响(生产环境慎用,确保有其他防护)
systemctl stop firewalld

# 恢复服务
systemctl start firewalld

为什么会这样

firewalld 本身是一个管理工具,真正的包过滤工作是由内核中的 netfilter 框架完成的。CPU 占用高通常不是因为 firewalld 这个用户态进程在空转,而是因为数据包在内核中匹配规则的成本过高。

早期版本或某些配置下,firewalld 使用 iptables 作为后端。iptables 的规则匹配是线性的,数据包需要依次遍历规则链,规则越多,单个包的处理延迟和 CPU 消耗就越高。较新的系统(如 RHEL 8/CentOS 8 及后续版本)默认使用 nftables 后端,它使用内核虚拟机处理规则,在处理大量规则时效率更高。

此外,开启详细日志记录会导致每个匹配的数据包都触发写操作,这会显著增加 I/O 等待和 CPU 中断处理负担。具体提升比例取决于规则复杂度,通常可减少显著的系统调用开销,减少规则数量和日志写入是公认的优化方向。

分步处理

按照以下步骤进行调整,每一步操作后建议观察系统状态。

1. 确认后端类型

执行 firewall-cmd `--get-backend`。如果显示 iptables 且你使用的是较新的操作系统,检查是否可以升级到支持 nftables 的版本。在 RHEL 8 及以上版本中,nftables 是默认后端。如需强制指定,可编辑 /etc/firewalld/firewalld.conf,设置 FirewallBackend=nftables 后重载服务。

2. 精简规则集

审查 firewall-cmd `--list-all` 的输出。移除不再使用的服务端口或富规则(rich rules)。每一条多余的规则都是数据包必须经过的检查点。如果某些 IP 段完全可信,可以考虑将其放入 trusted 区域,该区域的包处理开销最小。

示例:将内网网段加入 trusted 区域

firewall-cmd `--zone`=trusted `--add-source`=192.168.1.0/24 `--permanent`
firewall-cmd `--reload`

3. 关闭非必要日志

检查是否有启用了日志记录的区域或规则。除非正在排查攻击或连接问题,否则生产环境建议关闭 firewall 日志。

示例:移除 public 区域的日志前缀配置

firewall-cmd `--zone`=public `--remove-log-prefix` `--permanent`
firewall-cmd `--reload`

也可直接编辑 /etc/firewalld/zones/public.xml 移除相关 log 属性。

4. 评估停用必要性

警告:直接停用 firewalld 会暴露所有监听端口。如果前端没有安全组或硬件防火墙保护,服务器将直接面临公网扫描和攻击风险。

怎么优化 firewalld 配置减少 CPU 占用率提升吞吐量

如果服务器位于云服务商的安全组之后,或者前端有硬件防火墙,且内网环境可信,可以考虑直接停用 firewalld。执行 systemctl disable `--now` firewalld。这是减少 CPU 占用最彻底的方法,但必须确保没有其他安全暴露面。

5. 批量修改后一次性重载

避免在脚本中频繁调用 firewall-cmd `--reload`。重载操作会刷新内核规则表,高频率重载会消耗大量 CPU 并可能导致瞬时连接中断。建议将所有 `--permanent` 配置修改完成后,再执行一次重载。

怎么验证是否生效

优化后,需要通过以下方式确认效果:

1. 监控 CPU 使用率

使用 tophtop 命令,观察 ksoftirqd 或相关内核进程的 CPU 占用是否下降。firewalld 导致的开销通常体现在软中断上,而不是 firewalld 用户态进程本身。

2. 检查规则统计

使用 firewall-cmd `--stats` 查看包计数和丢包统计(注意:部分旧版本可能不支持此命令)。虽然这不直接显示 CPU,但可以确认规则是否仍在按预期工作。

3. 网络吞吐测试

在内网环境使用 iperf3 等工具进行吞吐测试。对比优化前后的带宽上限和延迟波动。你可以在自己的环境中通过对比测试获得基准线。

常见坑

1. 误删管理规则导致失联

在精简规则时,务必保留 SSH 或其他远程管理端口的放行规则。建议在操作前使用 firewall-cmd `--runtime-to-permanent` 保存当前配置,或准备好控制台访问权限。

2. 混淆用户态进程与内核开销

不要只盯着 firewalld 进程的 CPU 占用。大部分开销在内核态,top 命令中可能表现为 system 占用高或软中断高。

3. 停用后无替代防护

直接停用 firewalld 会暴露所有监听端口。如果前端没有安全组或硬件防火墙保护,服务器将直接面临公网扫描和攻击风险。

参考来源

  • firewalld.org - Firewalld Documentation
  • Red Hat Enterprise Linux - Security Hardening Guide (Regarding nftables and firewalld)
  • Linux man pages - firewall-cmd, firewalld