4. firewalld日常运维
firewalld 是 RHEL 7 及以后版本默认的动态防火墙管理服务,它把防火墙规则按“区域(zone)”组织,并通过 D-Bus 接口在运行时动态增删规则,无需重启服务即可生效。日常运维中,管理员最常打交道的对象就是服务进程、区域、接口和源地址这四类。理解它们之间的绑定关系,是排查“规则明明写了却不生效”这类问题的前提。
一、服务进程的启停与开机自启
firewalld 由 systemd 托管,服务单元名为 firewalld.service。常用操作如下:
systemctl start firewalld # 启动
systemctl stop firewalld # 停止(清空运行时规则)
systemctl restart firewalld # 重启
systemctl enable firewalld # 开机自启
systemctl disable firewalld # 取消开机自启
systemctl is-active firewalld # 查看是否运行
systemctl is-enabled firewalld # 查看是否开机自启
需要特别注意的是:stop 与 disable 是两件事。stop 只停止当前进程,重启系统后若已 enable 仍会拉起;disable 只取消开机自启,当前进程仍在运行。生产环境中若临时排障需要放行全部流量,更稳妥的做法是切换到 trusted 区域或临时停止服务,并在排障结束后立即恢复,避免长期处于无防护状态。
二、状态查看:三个层次
状态查看要区分“服务层”“配置层”“运行层”三个层次,很多误判都源于把三者混为一谈。
- 服务层:
systemctl status firewalld或firewall-cmd --state,回答“防火墙进程是否在跑”。 - 配置层:
firewall-cmd --list-all-zones、firewall-cmd --get-zones、firewall-cmd --get-default-zone,回答“有哪些区域、默认区域是谁、各区域里定义了什么”。 - 运行层:
firewall-cmd --list-all,回答“当前默认区域实际生效的规则是什么”。
关键区别在于 --permanent 参数。不带该参数的操作只改运行时配置,重启服务即丢失;带该参数的操作写入 /etc/firewalld/ 下的持久化配置,但不会立即影响运行时,需要 firewall-cmd --reload 才加载。因此“加了规则却不生效”的第一反应应是:是否漏了 --permanent,或加了 --permanent 却忘了 reload。
三、zone 绑定:默认区域与接口归属
每个网络接口(网卡、子接口、bond、bridge)在任一时刻只能属于一个 zone。zone 决定了该接口上流入流量的默认处理策略。查看与设置方式:
firewall-cmd --get-default-zone # 查看默认区域
firewall-cmd --set-default-zone=work # 设置默认区域(立即生效且持久)
firewall-cmd --get-active-zones # 查看当前活跃区域及其接口/源
firewall-cmd --zone=internal --change-interface=ens224 # 把接口改绑到 internal
firewall-cmd --zone=internal --list-interfaces # 查看某区域绑定的接口
--change-interface 与 --add-interface 的差别在于:前者会把接口从原区域移走,后者在接口已属于其他区域时会报错。运维中更推荐用 change-interface,语义更明确。若希望重启后仍保持绑定,需追加 --permanent 并 reload。
四、源地址管理:比接口更细的匹配维度
当一台主机有多个网段流量从同一接口进入,或需要按来源 IP 段区分策略时,仅靠接口绑定就不够了。此时用源地址(source)把特定网段“拉”进指定 zone:
firewall-cmd --zone=trusted --add-source=192.168.30.0/24
firewall-cmd --zone=trusted --list-sources
firewall-cmd --zone=trusted --remove-source=192.168.30.0/24
匹配优先级需要牢记:源地址匹配优先于接口绑定。也就是说,一个包先看源地址是否命中某个 zone 的 source 列表,命中则按该 zone 处理;未命中才回退到入口接口所属的 zone。这正是“接口在 public,但来自 192.168.30.0/24 的流量却按 trusted 放行”的原因。若同一网段被加入多个 zone,firewalld 会按区域名称字母序取第一个匹配,因此应避免重复定义。
五、一次完整的日常变更示例
假设需求是:把 ens224 划入 internal 区域,允许 192.168.30.0/24 访问本机数据库端口 3306,并保证重启后仍生效。可按以下顺序执行:
# 1. 查看现状,确认 ens224 当前归属
firewall-cmd --get-active-zones
# 2. 持久化地把接口改绑到 internal
firewall-cmd --permanent --zone=internal --change-interface=ens224
# 3. 持久化放行 3306/tcp
firewall-cmd --permanent --zone=internal --add-port=3306/tcp
# 4. 持久化添加源地址
firewall-cmd --permanent --zone=internal --add-source=192.168.30.0/24
# 5. 重新加载,使持久化配置进入运行时
firewall-cmd --reload
# 6. 验证
firewall-cmd --zone=internal --list-all
第 6 步的输出应能看到 interfaces 含 ens224、sources 含 192.168.30.0/24、ports 含 3306/tcp。若 interfaces 为空,说明接口绑定未生效,常见原因是接口名写错或该接口已被其他 zone 占用;若 sources 为空,则检查是否漏了 --permanent 或未 reload。验证时还可从 192.168.30.0/24 网段的一台主机执行 nc -zv 目标IP 3306,观察连接是否被拒绝,以确认策略真正落地。
--state 判断进程,再看 --get-active-zones 判断接口与源归属,最后用 --list-all 核对运行时规则;凡是“改了不生效”,优先怀疑 --permanent 与 reload 的配合。六、常用运维命令速查
| 目的 | 命令 | 是否持久 |
|---|---|---|
| 查看运行状态 | firewall-cmd --state | — |
| 查看默认区域 | firewall-cmd --get-default-zone | — |
| 查看活跃区域及绑定 | firewall-cmd --get-active-zones | — |
| 查看某区域全部规则 | firewall-cmd --zone=internal --list-all | — |
| 改绑接口 | firewall-cmd --permanent --zone=internal --change-interface=ens224 | 是(需 reload) |
| 添加源地址 | firewall-cmd --permanent --zone=internal --add-source=192.168.30.0/24 | 是(需 reload) |
| 移除源地址 | firewall-cmd --permanent --zone=internal --remove-source=192.168.30.0/24 | 是(需 reload) |
| 重载配置 | firewall-cmd --reload | — |
掌握以上内容后,日常运维中绝大多数 firewalld 问题都能定位到具体层次:进程没起、区域选错、接口没绑、源地址优先级被忽略,或是持久化与运行时不一致。把这四类对象的关系理清,规则管理就会从“试出来”变成“算出来”。