Ubuntu 防火墙迁移指南:从 UFW 到 firewalld 的完整实践
结论先行
将 Ubuntu 的防火墙从 UFW 换成 firewalld 是可行的。核心操作分三步:停用 UFW → 安装并启用 firewalld → 按区域模型重新配置规则。两者管理逻辑不同,规则无法自动迁移,需要手动重建。本文提供完整的迁移步骤、firewalld 的核心使用方法,以及 Ubuntu 环境下需要特别注意的要点。
一、为什么要在 Ubuntu 上用 firewalld?
UFW 是 Ubuntu 的默认防火墙工具,简单直接,适合单机场景。但如果你管理着混合 Linux 环境——既有 Ubuntu 又有 RHEL、CentOS 或 Fedora——使用统一的防火墙工具可以减少认知负担。firewalld 正是 Red Hat 系发行版的默认防火墙,支持区域隔离、运行时与永久配置分离、富规则等高级特性。
对于 Ubuntu 用户而言,换用 firewalld 主要有两个理由:跨平台一致性,以及需要更精细的流量控制能力(如按来源 IP 限制服务访问)。
二、迁移前的准备
在动手之前,有几件事必须确认:
备份现有 UFW 规则。 虽然规则无法直接转换,但记录下当前开放的端口和服务,作为后续在 firewalld 中重建规则的依据:
sudo ufw status verbose > ~/ufw-rules-backup.txt
确保 SSH 可达。 如果你是通过 SSH 连接服务器,务必先确认新防火墙会放行 SSH,否则一旦 UFW 停用、firewalld 尚未配好 SSH 规则,你会被锁在门外。
了解两者逻辑的根本差异。 UFW 是“规则列表”模型:你逐条添加允许或拒绝的规则,按顺序执行。firewalld 是“区域”模型:网络接口或来源被分配到某个信任级别的区域,区域内的规则决定流量放行与否。
三、迁移操作步骤
3.1 停用 UFW
sudo systemctl stop ufw
sudo systemctl disable ufw
两个命令缺一不可:stop 立即停止服务,disable 取消开机自启。只 stop 不 disable,重启后 UFW 会重新启动,与 firewalld 冲突。
3.2 安装并启动 firewalld
sudo apt update
sudo apt install -y firewalld
sudo systemctl enable --now firewalld
Ubuntu 的 apt 源中 firewalld 版本通常较新,安装过程不会有依赖问题。
3.3 验证运行状态
sudo systemctl status firewalld
sudo firewall-cmd --state
看到 running 即表示 firewalld 已接管防火墙管理。
3.4 立即放行 SSH(关键步骤)
在停用 UFW 之前就应该先做这一步,或者在启用 firewalld 后立刻执行:
sudo firewall-cmd --permanent --zone=public --add-service=ssh
sudo firewall-cmd --reload
如果你的 SSH 监听的不是默认 22 端口,需要改为放行实际端口:
sudo firewall-cmd --permanent --zone=public --add-port=<你的端口>/tcp
sudo firewall-cmd --reload
3.5 按需重建其他规则
参考你备份的 UFW 规则,将每条规则转换为 firewalld 的对应写法(详见第五节)。
四、firewalld 核心概念
理解 firewalld,关键是理解 区域 和 运行时/永久配置的分离。
区域(Zone)
区域是对网络“信任级别”的抽象。每个区域自带一组默认规则,你可以在此基础上增删服务或端口。常用的预定义区域:
| 区域 | 信任级别 | 典型用途 |
|---|---|---|
drop | 最低(最安全) | 静默丢弃所有入站流量,不返回任何响应 |
block | 极低 | 拒绝入站,但返回 ICMP 不可达响应 |
public | 默认 | 公共网络,仅放行明确指定的服务 |
work | 较高 | 工作网络,信任同网段主机 |
home | 高 | 家庭网络,信任更多服务 |
trusted | 最高(最宽松) | 允许所有流量,谨慎使用 |
Ubuntu 上 firewalld 的默认区域通常也是 public。未显式绑定到其他区域的网络接口,自动归入默认区域。
运行时配置 vs 永久配置
firewalld 将配置分为两层:
- 运行时配置:立即生效,但重启服务或系统后丢失。适合测试和临时调整。
- 永久配置:写入磁盘,重启后依然存在。使用
--permanent标志添加。
优先级上,运行时配置高于永久配置。执行 firewall-cmd --reload 后,永久配置会覆盖运行时中未保存为永久的修改。
一个实用的技巧:如果在运行时测试了一条规则且运行正常,可以用以下命令将其保存为永久配置:
sudo firewall-cmd --runtime-to-permanent
五、firewalld 常用操作速查
查看状态
# 查看默认区域
sudo firewall-cmd --get-default-zone
# 查看当前活跃区域及绑定的接口
sudo firewall-cmd --get-active-zones
# 查看某区域的完整配置
sudo firewall-cmd --zone=public --list-all
放行服务(推荐方式)
优先使用“服务”而非“端口”。firewalld 内置了常见服务的定义,用服务名更不易出错。
# 永久放行 HTTP 和 HTTPS
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
查看所有预定义服务:sudo firewall-cmd --get-services
放行端口
当服务未预定义或使用了自定义端口时,直接操作端口:
# 放行 TCP 8080 端口
sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
# 放行端口范围
sudo firewall-cmd --permanent --zone=public --add-port=8080-8090/tcp
# 放行 UDP 端口
sudo firewall-cmd --permanent --zone=public --add-port=51820/udp
sudo firewall-cmd --reload
注意:端口必须带协议类型(/tcp、/udp、/sctp),这是 firewalld 的强制格式。
限制来源地址
UFW 中用 ufw allow from 10.0.0.0/8 实现的限制,在 firewalld 中有两种做法:
方法一:将来源绑定到 trusted 区域(适合完全信任的网段)
sudo firewall-cmd --permanent --zone=trusted --add-source=10.0.0.0/8
sudo firewall-cmd --reload
方法二:使用富规则(适合更精细的控制)
# 仅允许 10.0.0.0/8 访问 22 端口
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
rule family="ipv4"
source address="10.0.0.0/8"
port protocol="tcp" port="22" accept'
sudo firewall-cmd --reload
移除规则
sudo firewall-cmd --permanent --zone=public --remove-service=http
sudo firewall-cmd --permanent --zone=public --remove-port=8080/tcp
sudo firewall-cmd --reload
重新加载配置
每次修改 --permanent 规则后,都必须执行 reload 才能生效:
sudo firewall-cmd --reload
reload 不会中断现有连接;如果需要完全重置(会断开连接),用 --complete-reload。
六、UFW 与 firewalld 规则对照
| 操作 | UFW 命令 | firewalld 命令 |
|---|---|---|
| 允许 SSH | ufw allow ssh | firewall-cmd --permanent --add-service=ssh |
| 允许端口 | ufw allow 8080 | firewall-cmd --permanent --add-port=8080/tcp |
| 允许来自某网段 | ufw allow from 10.0.0.0/8 | 见上方“限制来源地址” |
| 拒绝某端口 | ufw deny 3306 | firewall-cmd --permanent --remove-port=3306/tcp |
| 查看规则 | ufw status verbose | firewall-cmd --zone=public --list-all |
| 重新加载 | ufw reload | firewall-cmd --reload |
| 启用/停用 | ufw enable/disable | systemctl start/stop firewalld |
七、Ubuntu 上的特别注意事项
不要同时运行两个防火墙。 UFW 底层通过 iptables 规则实现,firewalld 同样会操作底层防火墙规则。两者同时运行会产生不可预测的冲突,轻则规则混乱,重则网络中断。
--permanent 是高频陷阱。 firewalld 的默认行为是“临时生效”。如果你添加规则后忘记加 --permanent,重启后规则全部消失。建议养成习惯:先加 --permanent,再 --reload。
Ubuntu 上的 firewalld 日志。 firewalld 的日志通过 systemd journal 输出,查看方式:
sudo journalctl -u firewalld -f
被拒绝的数据包日志级别可以通过 /etc/firewalld/firewalld.conf 中的 LogDenied 调整。
Docker 与 firewalld 的配合。 如果你在 Ubuntu 上运行 Docker,docker 会自行操作 iptables 规则,可能绕过 firewalld 的控制。firewalld 从较新版本开始支持与 Docker/Podman 的集成,但在严格场景下需要额外配置。这是 Ubuntu 用户从 UFW 迁移时容易忽视的问题。
八、回退方案
如果迁移后发现 firewalld 不适合你的使用场景,回退到 UFW 同样简单:
# 停用并禁用 firewalld
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# 重新启用 UFW(规则仍在,因为 ufw disable 不会删除规则)
sudo systemctl enable --now ufw
UFW 的规则在 disable 时不会丢失,重新启用即可恢复。