ufw与firewalld深度解析:Linux防火墙规则配置、迁移与排查实战
2026/8/30 17:50:08 网站建设 项目流程

很多人第一次认真研究 Linux 防火墙,都是从ufwfirewalld这两个名字开始的。但大多数教程只告诉你“开放 22 端口”或“禁用防火墙”,却没说清楚这两套工具到底解决什么问题、底层依赖什么、什么时候该用哪一个。结果就是:在一台 Ubuntu 服务器上把规则配得好好的,换到 CentOS 上却找不到ufw命令;或者明明在firewalld里加了端口,外部测试却还是不通。

这篇文章就把 ufw 和 firewalld 放在一起讲清楚。先看它们各自的定位和底层机制,再分别用实例走一遍常用配置、批量管理、错误排查和取舍思路。看完之后,你至少能回答这五个问题:它们是什么、怎么用、规则为什么没生效、两套工具能不能混用、生产环境到底该怎么选。

1. 先搞清楚 ufw 和 firewalld 的本质,再动手配规则

很多人都把 ufw 和 firewalld 当成两个完全对立的防火墙软件,其实这个理解不够准确。它们更像是在不同发行版上默认自带的两套前端管理工具,真正干活的底层框架仍然是 Linux 内核里的网络过滤机制。

1.1 ufw 是 iptables 的简化前端,不是独立防火墙

ufw 的全称是 Uncomplicated Firewall,设计目标就是“不复杂”。它把 iptables 的链、表、匹配条件这些概念封装成更直观的规则,比如你只需要写ufw allow 22/tcp,它会在后台帮你处理 INPUT 链、协议判断和端口匹配。

但这不代表 ufw 只是个玩具。你可以手动编辑/etc/ufw/下的规则文件,也可以查看它生成的完整 iptables 规则。很多云服务器镜像默认预装的就是 ufw,尤其是 Ubuntu 和 Debian 系。它适合单机规则管理,追求的是“快速上手、少出错”。

如果你在 Ubuntu 上执行:

sudo ufw status verbose

输出会显示当前状态、默认策略和已有规则。注意这个 verbose 参数,它会连带打印默认的入站、出站和转发策略,排查问题时不至于只看到几条规则而无从判断方向。

1.2 firewalld 基于 zone 和 services,天然适合动态更新

firewalld 是 CentOS、RHEL、Fedora 等发行版的选择。它通过 D-Bus 接口实时变更规则,不需要像 iptables 那样每次重载整个规则集。它的核心概念是 zone,也就是把网络划分为不同信任区域,比如 public、internal、trusted。

比如你把一张网卡分配到 public 区域,那么这个区域里允许的端口和服务就决定外部访问能否成功。它的命令风格也很明确:

sudo firewall-cmd --list-all sudo firewall-cmd --permanent --add-port=8080/tcp

注意--permanent这个参数,它表示“永久写入配置”,但不一定立即生效到当前会话。如果你不加这个参数,规则只会加到运行时,重启服务后就会消失。这个设计既是优点也是坑点,后面会单独展开。

1.3 两套工具的共同底色:内核 Netfilter

不管是 ufw 还是 firewalld,最终都会调用内核的 Netfilter 框架。Netfilter 提供了数据包过滤、网络地址转换、连接跟踪等底层能力,iptables、nftables 都是操作它的常见接口。

从实际排查角度看,你要记住一个顺序:ufw/firewalld只是你看到的“操作面板”,真正的生效链路是规则写入、内核 Netfilter 加载、防火墙策略匹配。如果规则配了但流量不通,不要只盯着前端命令输出,还要看内核层面的规则表和数据包计数。

比如 ufw 状态下,可以用 iptables 命令看它生成的内容:

sudo iptables -L -n -v

这时你会看到 ufw 创建的链和规则。很多时候“防火墙没生效”其实是因为规则写进了不同优先级或不同链,而不是系统没加载。

2. 动手前的环境准备与执行原则

看内核、看发行版、看当前状态,这三件事应该在动手改防火墙之前做完。很多人直接打开端口,却发现根本连不上服务,最后查了半天才意识到 SSH 端口被别人改过,而防火墙放行的还是默认 22。

2.1 确认发行版和默认管理工具

先确定自己手上是哪一套工具:

cat /etc/os-release command -v ufw command -v firewall-cmd

不同发行版的默认工具不一样,但很多系统也允许手动安装另一套。比如 Debian 系可以安装 firewalld,CentOS 也可以安装 ufw。我不建议在同一台主机上同时启用两套管理工具,因为它们的策略会互相叠加,最后排查起来非常绕。

尤其是新装的容器镜像、云服务器测评环境和国产化系统镜像,底层服务管理方式可能有差异,最好先确认 systemd 服务状态,再决定用哪套工具。

2.2 先看默认策略,再决定放行规则

默认策略决定了“没有匹配到任何规则时,数据包该怎么处理”。绝大多数安全要求较高的服务器,默认入站策略是 deny,也就是一切入站连接默认拒绝,只有匹配到显式 allow 规则才放行。出站通常是 allow,方便服务器主动访问外部更新源、调用接口。

ufw 查看默认策略:

sudo ufw status verbose

firewalld 查看默认区域和策略:

sudo firewall-cmd --get-default-zone sudo firewall-cmd --list-all --zone=public

我一般会先把这个信息记下来,再开始配置。如果默认入站本来就是 deny,那我只需要确认需要对外服务的最小端口集合,比如 SSH、HTTP、HTTPS。如果默认入站是 allow,那我建议先把默认策略调整成 deny,再添加白名单式放行规则,否则开放的端口越多,安全暴露面越大。

2.3 修改防火墙前先准备一个可靠的回退通道

这句话一定要放在前面:配置防火墙时,最怕的不是规则写错,而是把当前的 SSH 连接干掉。

特别是远程服务器场景,如果你在防火墙里误删了 22 端口放行规则,或者把默认入站策略改成 deny,现有连接不会立刻断开,但一旦断开会话,很难再连回来。更危险的是,有些云平台的安全组和系统内防火墙是两层叠加关系,系统内封禁之后,控制台不一定能帮你快速解掉。

比较稳妥的操作顺序:

  1. 不要退出当前终端,另开一个 SSH 会话测试规则。
  2. 先添加白名单式放行,再收紧默认策略。
  3. 每次只改一类规则,改完立刻验证。
  4. 如果用的是云服务器,先确认云平台安全组是否放行对应端口。
  5. 保留一个 VNC 或控制台类型的备用登录入口。

这个流程看起来慢,但能避免很多生产事故。

3. 从最小规则到批量管理:ufw 精讲与实战

ufw 的语法足够简单,但简单不等于可以乱写。下面按一个标准服务器的配置流程从头走一遍,每条命令都会解释为什么这么写,以及输出长什么样才算正常。

3.1 启用和禁用要分清操作目标

很多新手执行sudo ufw enable后没看到任何提示,就以为规则没生效,然后反复执行。实际上 ufw enable 的合理输出是一句警告提示,告诉你启用后现有 SSH 连接可能受影响,然后让你输入 y 确认。

建议先看一下当前状态:

sudo ufw status

如果状态是 inactive,再启用:

sudo ufw enable

如果你只是临时调整规则,不想完全关闭防火墙,不需要执行 disable。用完删除对应规则即可。我记得有个同事为了调试端口,把 ufw 整个 disable 了,结果服务开完忘掉重新启用,服务器裸奔了几个月。所以“关闭防火墙”这种事,能不做就不做。

3.2 常用规则的写法与判断标准

ufw 的基础规则非常直观:

# 允许 SSH sudo ufw allow 22/tcp # 允许指定端口 sudo ufw allow 8080/tcp # 允许指定 IP 访问指定端口 sudo ufw allow from 192.168.1.100 to any port 3306/tcp # 拒绝某个 IP sudo ufw deny from 203.0.113.10 # 删除规则 sudo ufw delete allow 8080/tcp

写规则时要注意两点:协议要写清楚,是 tcp 还是 udp;来源范围要写明白,是任意来源还是指定 IP。有些服务虽然显示“监听端口是 8080”,但实际对外通信可能同时需要 TCP 和 UDP,比如 DNS、NTP、部分音视频服务。如果只放行 tcp,另一部分流量仍然会被丢弃。

验证方式不复杂:

sudo ufw status numbered

这个命令会输出带编号的规则列表。如果你要插入规则到某个位置,可以先看编号,再使用insert语法:

sudo ufw insert 1 allow from 192.168.1.0/24 to any port 22/tcp

编号越靠前,优先级越高。这种机制在防火墙规则多时非常有用。

3.3 修改 SSH 端口时,先把新端口放行再改 sshd_config

我见过不少案例:用户把 sshd 的监听端口从 22 改到 2222,防火墙只放行了 22,重启 SSH 后直接断线。还有反过来的情况,改了 sshd_config,却忘了 ufw 规则没加,服务端口没监听成功,连 log 都看不到。

正确步骤:

# 1. 先放行新端口 sudo ufw allow 2222/tcp # 2. 修改 sshd_config sudo sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config # 3. 检查 sshd 配置 sudo sshd -t # 4. 重启 SSH 服务 sudo systemctl restart sshd # 5. 新窗口测试连接 ssh -p 2222 user@server_ip

确认新端口能正常登录后,再删除旧的 22 端口放行规则。这个顺序看着啰嗦,但能保证你始终保留一个可用通道。

3.4 ufw 的日志、转发和默认策略调整

ufw 的日志功能经常被忽略。默认日志级别是 off,遇到“规则没生效”却不知道丢包原因时,打开日志非常关键:

sudo ufw logging on sudo ufw logging medium

日志写在/var/log/ufw.log,里面会记录被阻止的数据包信息。配合 dmesg 使用能快速判断是源 IP、目标端口还是转发问题。

如果你需要做端口转发,比如把外部访问的 8080 转到内网另一台主机的 80 端口,可以在/etc/ufw/before.rules中配置 NAT 规则。这里要提醒一句:这个文件是 ufw 在加载规则时读取的,修改后必须执行:

sudo ufw reload

如果只是用ufw allow添加普通端口规则,不需要编辑这个文件。

默认策略调整:

sudo ufw default deny incoming sudo ufw default allow outgoing

这句建议在你理解“入站默认拒绝、出站默认允许”的安全模型后再执行。如果服务器要对外提供 Web 服务、数据库服务、API 服务,记得在前面把对应端口先 allow 完。

4. 从 zone 概念到生产配置:firewalld 精讲与实战

firewalld 的学习曲线比 ufw 陡一点,因为它引入了 zone、runtime、permanent 三个概念。你只有把这三个概念彻底搞清楚,才能避免“配置了但不生效”的问题。

4.1 runtime 和 permanent 的区别是出现频率最高的问题

先看一个例子:

sudo firewall-cmd --add-port=80/tcp

执行完后,HTTP 端口立刻放行。但如果这时候执行:

sudo firewall-cmd --reload

80 端口可能就没了。原因就是上面这条命令只写入了运行时规则,没有写入永久配置文件。

要确保规则重启服务后仍然存在,必须加上 --permanent:

sudo firewall-cmd --permanent --add-port=80/tcp sudo firewall-cmd --reload

这里有一个常见的误解:加了 --permanent 之后还需要手动 reload 吗?需要。--permanent只是把规则写进配置文件,运行时的内核规则并不会自动变更。所以最稳妥的流程是:

sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --reload sudo firewall-cmd --list-all

先用 permanent 写配置,再 reload 让配置生效,最后 list-all 确认。

4.2 zone 的分配逻辑:不同网络接口可以有不同的策略

firewalld 默认有一个 default zone,通常叫 public。所有未指定区域的网络接口默认归入这个区域。你可以查看当前网卡归属:

sudo firewall-cmd --get-active-zones

输出类似:

public interfaces: eth0

在生产环境里,比较常见的做法是把内网接口放到 trusted,把外网接口放到 public 或者 dmz:

sudo firewall-cmd --permanent --zone=trusted --change-interface=eth1 sudo firewall-cmd --reload

这样 eth1 上的流量可以享受更宽松的规则,而 eth0 上的流量继续走严格策略。对于有多张网卡的服务器,这个能力非常重要。

4.3 服务、端口和 rich rule 的优先级

firewalld 支持三种规则写法,按可读性排序:

  1. --add-service=ssh,适合系统已知的标准服务。
  2. --add-port=8080/tcp,适合没有标准服务名的应用端口。
  3. --add-rich-rule,适合带来源 IP、协议、动作等复杂条件的规则。

rich rule 举例:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'

这句的含义是只允许 192.168.1.100 访问本机 3306 端口。如果你需要限制数据库只对内网开放,这个写法比单纯放行 3306 更安全。

如果你遇到“添加了 service 但连接还是失败”的情况,要检查默认区域里--list-services的输出。规则存在但不代表匹配到了当前默认区域。

4.4 firewalld 的端口转发和 NAT 配置

firewalld 同样支持端口转发。例如把本机 8080 端口的入站流量转发到 10.0.0.5 的 80 端口,需要两步:

sudo firewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=10.0.0.5 sudo firewall-cmd --reload

如果转发不生效,大概率是内核转发开关没打开:

sudo sysctl -w net.ipv4.ip_forward=1

如果想永久开启,写入/etc/sysctl.conf或者/etc/sysctl.d/下的配置文件。注意这只是让内核允许转发,真正的防火墙策略还是要通过 firewalld 管理。如果你在云环境里做 NAT 转发,还要确认云平台的安全组是否允许该流量进入本机。

4.5 临时放行与批量管理思路

调试阶段,临时放行端口不加 --permanent 是合理的。调试确认后,再补加 permanent 规则。这个过程能避免把临时端口写进永久配置。

但生产环境最好避免反复在运行时临时加端口,因为你可能忘记清理,最终出现在运行规则里存在、永久配置里不存在的“幽灵端口”。每次调试完,建议用:

sudo firewall-cmd --list-all

和:

sudo firewall-cmd --permanent --list-all

把两份规则做对比,确保临时规则和永久规则一致。

如果要批量添加端口,写循环时要小心:

for port in 8080 8081 8082; do sudo firewall-cmd --permanent --add-port=${port}/tcp done sudo firewall-cmd --reload

5. 两套工具交叉使用、迁移思路和生产选择

我做项目时经常遇到一个问题:运维脚本在 Ubuntu 上跑通,拿到 CentOS 上就报ufw: command not found。这种事不是工具本身的问题,而是没有提前确认环境。

5.1 ufw 和 firewalld 能不能同时安装

技术上可以,因为它们的底层都依赖 Netfilter,但实际不建议。

同时启用两套工具会造成规则叠加,排查逻辑会变得非常混乱。你明明关闭了 firewalld 的某个端口,却忘了 ufw 里还放行着;或者反之。生产环境里,我建议只保留一套管理工具,另一套禁用并设置开机不启动。

比如在 CentOS 上如果安装了 ufw:

sudo systemctl stop ufw sudo systemctl disable ufw

原则上系统原生的默认防火墙管理工具优先,别为了统一习惯强行替换。

5.2 从 ufw 迁移到 firewalld 的规则对照思路

迁移不是把命令逐条改一下就行,而是要重新梳理业务端口、来源 IP、默认策略这三件事。你可以画一张清单:

业务协议端口来源范围动作
SSHTCP22办公室 IPallow
HTTPTCP80全部allow
HTTPSTCP443全部allow
MySQLTCP3306内网网段allow
其他---deny

然后按这个清单分别配置 ufw 或 firewalld。迁移过程中最忌讳的是“顺手把不需要的端口也放行”,比如把 21、23、445 等旧环境里遗留的端口带过去。

5.3 生产环境中如何选择

我的经验是:

  • 如果是 Ubuntu、Debian 或者个人学习机,优先 ufw。语法简单,规则清晰,适合快速落地。
  • 如果是 CentOS、RHEL、Rocky、AlmaLinux 这类企业发行版,或要管理多网卡、多区域、需要动态更新规则的场景,优先 firewalld。
  • 如果你已经有一套成熟的 iptables 脚本,而且团队很熟悉,那不换工具也可以,但要确保新规则不会和现有工具冲突。
  • 如果服务器数量多,建议用自动化工具统一管理防火墙配置,而不是逐台手工执行命令。

选择标准不是“哪个更安全”,而是“哪个更适合你的环境维护方式”。ufw 和 firewalld 本身都只是管理工具,安全效果取决于你写进去的规则。

5.4 防火墙规则维护的日常习惯

我见过很多服务器防火墙问题,最后都不是“功能不支持”,而是“没人维护规则清单”。建议从第一天就做好三件事:

  1. 每个端口放行都备注业务用途。
  2. 批量修改前先导出或备份当前规则。
  3. 每次变更后记录时间和验证结果。

ufw 备份可以简单复制配置文件:

sudo cp -r /etc/ufw /etc/ufw.bak.$(date +%F)

firewalld 备份可以:

sudo cp -r /etc/firewalld /etc/firewalld.bak.$(date +%F)

这个动作耗时不到一分钟,但恢复时能省大量时间。

6. 规则不生效时的通用排查链路

无论你用 ufw 还是 firewalld,规则不生效的表现通常有四种:完全连不上、部分 IP 能连、连接超时、连接被拒绝。每种现象对应的排查方向不一样。

6.1 先确认现象,再动规则

完全连不上:先确认服务进程是否在监听,防火墙规则可能不是主要原因。用ss -lntp看端口是否处于 LISTEN 状态,如果服务本身没起来,改防火墙规则没有意义。

部分 IP 能连:大概率是防火墙规则里限制了来源地址,或者默认区域设置了严格策略。检查规则中是否有来源白名单。

连接超时:数据包可能被静默丢弃,要么是防火墙没有放行,要么是网络路径中被安全组拦截。

连接被拒绝:端口没有监听,或者防火墙返回了 reject 而不是 drop。reject 会主动通知客户端不可达,drop 则没有响应。

6.2 从日志和计数规则里找线索

ufw 开日志后直接看/var/log/ufw.log。firewalld 的日志通常在/var/log/firewalld,也可能落在内核日志里。你可以先看当前规则匹配计数:

sudo iptables -L -n -v

重点关注 INPUT 链里每条规则左侧的 pkts 和 bytes 数值。如果计数一直没有增长,说明数据包根本没有走到这条规则,可能是前置 reject、DROP 或网络路径问题。如果计数一直在涨但连接还是失败,那么问题可能是服务本身。

6.3 常见失败原因的优先级排序

我一般按这个顺序排查:

  1. 云平台安全组是否放行端口。
  2. 服务进程是否监听在正确 IP 和端口上。
  3. 防火墙默认策略是否拒绝入站。
  4. 规则是否写进了默认区域。
  5. 端口协议是否写错,例如服务用 TCP,但放行写成了 UDP。
  6. 是否存在 ipset、firewalld 富规则、ufw before.rules 等叠加规则。
  7. 内核 ip_forward 是否开启,涉及转发时必须检查。
  8. 规则保存后是否执行了 reload 或 restart。

这八项里,前三项是“环境问题”,后五项是“配置问题”。大多数新手卡在第四项和第五项,特别是 firewalld 的默认区域和协议写法。

6.4 如何快速回滚

如果修改后业务受损,先不要急着研究为什么,优先恢复服务。ufw 可以直接删除错误规则:

sudo ufw status numbered sudo ufw delete 3

如果不知道哪条规则错误,也可以临时允许所有流量,等确认服务恢复后再逐条收紧:

sudo ufw default allow incoming

注意这并不建议长期使用,只是应急手段。firewalld 同理,可以用--remove-port--remove-rich-rule删除问题规则,也可以把对应 zone 重新设为默认策略:

sudo firewall-cmd --permanent --zone=public --set-target=ACCEPT sudo firewall-cmd --reload

先把 target 改成 ACCEPT,业务恢复后,再回头看规则版本和前一天备份的差异。

7. 最后的落地建议

把 ufw 和 firewalld 放在一起学,重点不是背命令,而是理解“前端工具 + 内核过滤 + 区域策略”这个三层结构。前端负责让管理员少写复杂规则,内核负责真正匹配流量,区域策略决定不同网卡的可信度。理解这三层之后,不管下次遇到的是ufwfirewalld还是直接面对nftables,你都能顺着思路排查问题。

实际干活时,我建议先在一个不重要的测试环境里,把本文的规则逐条跑一遍,确认每个命令的输出长什么样,再把同样的流程迁移到生产服务器。测试环境里不值得调试“策略安全性”,但要调试“规则生效路径”。

如果你现在面临的问题是“服务器端口连不上”,别急着把所有端口都放行,先按第六节的八项清单走一遍。多数情况下,第一项和第三项就能解决大部分问题。真正需要你花时间研究的,其实是后续的批量规则、区域策略和日志监控——这些才是防火墙配置从“能用”走向“好用”的分水岭。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询