人人都会AI编程

firewalld:区域、规则、端口 / 服务管理

更新时间:2026-07-12

firewalld 是当前主流 Linux 发行版(如 RHEL/CentOS 7+、Fedora、openSUSE)默认的动态防火墙管理器。它基于 nftablesiptables 作为后端,但提供了更人性化的抽象概念:区域(zone)服务(service) 和直接的端口/协议规则。最重要的是,它支持运行时修改而不中断已有连接,让运维变得更安全。


1. 区域(zone):根据信任级别分组规则

区域是 firewalld 最核心的组织方式。每个网络接口(如 eth0wlan0)都会被分配到一个区域,该区域决定了接口默认的准入策略。系统预定义了多个区域,信任级别从低到高依次为:

  • drop:任何进入的流量默认丢弃,不回复任何响应。
  • block:进入的流量被丢弃,但会回复 icmp-host-prohibitedicmp6-adm-prohibited
  • public最常见的服务器初始区域。适用于公共网络,只允许选定的进入连接。
  • external:适用于将本机作为 NAT 网关的外部网络,启用 IP 伪装。
  • dmz:非军事区,仅允许有限的外部访问内部服务。
  • workhomeinternal:信任度逐渐升高,internal 基本允许大部分流量。
  • trusted:所有流量被接受。

你可以用 firewall-cmd --get-zones 查看所有可用区域,用 firewall-cmd --get-default-zone 查看当前默认区域(默认通常为 public)。

实用命令:

# 查看所有区域及其配置
firewall-cmd --list-all-zones

# 查看当前活跃区域(即至少绑定了一个接口的区域)
firewall-cmd --get-active-zones

# 将接口 eth0 移到 home 区域(永久生效)
firewall-cmd --permanent --zone=home --change-interface=eth0
firewall-cmd --reload

2. 服务(service):预定义的协议/端口组合

firewalld 使用 XML 文件定义了许多常用服务的规则(位于 /usr/lib/firewalld/services/),比如 sshhttphttpsmysql。一个服务可以包含多个端口和协议,比如 http 服务默认只包含 TCP 80 端口。允许某个服务,本质上就是一次性放行该服务所需的所有端口和协议。

实用命令:

# 列出所有在默认区域允许的服务
firewall-cmd --list-services

# 在 public 区域临时放行 http 和 https
firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=https

# 永久放行并立即生效(需要 --permanent 和 --reload)
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --reload

# 查看服务的具体定义(端口/协议)
firewall-cmd --info-service=ssh

你也可以自定义服务,在 /etc/firewalld/services/ 下创建 XML 文件,然后重新加载。


3. 直接管理端口和协议

如果某个软件没有预定义的服务,或者你只想开放一个临时端口,可以直接指定端口和协议。

实用命令:

# 开放 TCP 8080 端口(临时)
firewall-cmd --add-port=8080/tcp

# 永久开放 UDP 5000-5005 端口范围
firewall-cmd --permanent --add-port=5000-5005/udp
firewall-cmd --reload

# 移除一个端口
firewall-cmd --permanent --remove-port=8080/tcp

4. 富规则(rich rules):更精细的控制

当简单的“允许服务/端口”不能满足需求时,可以用富规则实现基于源 IP、目的 IP、日志、动作的复杂过滤。

示例:

# 只允许来自 192.168.1.0/24 的 SSH 访问
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'

# 拒绝来自 203.0.113.5 的所有流量,并记录日志
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.5" log prefix="DROP_BAD" level="info" drop'

5. 运行时与永久配置

firewalld 的一个重要特性是运行时(runtime)和永久(permanent)配置分离。不带 --permanent 的修改立即生效,但重启服务或系统后丢失;带 --permanent 的修改存入配置文件,但不会立即生效,需要执行 --reload 或重启 firewalld.service。最佳实践是:先用运行时命令测试,确认无误后再写入永久配置。

安全技巧: 在进行远程防火墙修改时,永远先执行临时命令测试,并配合定时恢复计划(比如 firewall-cmd --runtime-to-permanent 或使用 at 命令计划恢复),防止把自己锁在服务器外面。


6. 完整配置步骤示例

假设你有一台新服务器,需要开放 SSH、HTTP、HTTPS,并允许自定义 TCP 8000 端口用于内部应用:

# 1. 确保默认区域是 public
firewall-cmd --set-default-zone=public

# 2. 永久添加服务
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https

# 3. 永久添加自定义端口
firewall-cmd --permanent --zone=public --add-port=8000/tcp

# 4. 重载生效
firewall-cmd --reload

# 5. 验证
firewall-cmd --list-all

通过区域、服务、端口和富规则的组合,firewalld 既能满足简单主机的快速配置,也能支撑复杂网络的安全策略,并且所有操作都可以脚本化,非常契合现代运维自动化的需求。