Brave
@47c132035ed7a1105a867946b99d67af 网络安全与大数据研究小组 公开
讨论 为 Linux 系统构建安全屏障:UFW 防火墙配置指南

为 Linux 系统构建安全屏障:UFW 防火墙配置指南

在 Linux 安全体系中,防火墙是抵御外部攻击的第一道防线。对于大多数用户而言,直接操作复杂的 iptables 往往令人望而生畏,而 UFW (Uncomplicated Firewall) 正是为了简化这一过程而设计的。本文将探讨如何高效使用 UFW 来保护您的系统。

UFW 最初由 Ubuntu 团队开发,目前已被众多基于 Debian 的发行版采用,并可在 Arch Linux、Fedora 等发行版上手动安装。它的设计哲学是:将底层 netfilter 框架的复杂性抽象为接近自然语言的命令行语法,让管理员无需记忆冗长的 iptables 规则,就能快速搭建起可靠的网络防护。


一、核心逻辑:从"拒绝所有"开始

安全界的核心原则是最小权限原则 (Principle of Least Privilege)。一个健壮的防火墙配置通常遵循以下基准策略:

  • 🚫 默认拒绝所有入站流量:阻止外部主动发起的连接。
  • 默认允许所有出站流量:确保本地应用能正常访问互联网。

通过 DigitalOcean 的安全实践 建议,在启用防火墙前,请务必先允许 SSH 连接(sudo ufw allow ssh),否则您可能会被锁在服务器之外。

这一策略可以用一个形象的比喻来理解:

把您的服务器想象成一座只有一扇门的堡垒。"默认拒绝"策略意味着这扇门默认是锁死的,只有您明确持有钥匙(即主动放行的规则)的访客才能进入。相反,如果采用"默认允许"策略,等于大门敞开,您需要逐一辨认并拦截每一个不受欢迎的人——这在面对互联网上海量的自动化扫描和攻击时,几乎是不可能完成的任务。

具体设置默认策略的命令如下:

# 设置默认拒绝所有入站连接
sudo ufw default deny incoming

# 设置默认允许所有出站连接
sudo ufw default allow outgoing

⚠️ 关键提醒:执行上述命令后,UFW 尚未激活。在执行 sudo ufw enable 之前,请务必先添加 SSH 放行规则。如果您是通过远程 SSH 连接到服务器进行操作的,忘记这一步将立即导致您与服务器断开连接,且无法重新登录(除非您拥有物理控制台或带外管理访问权限,如 IPMI/iLO/iDRAC)。


二、理解 UFW 的技术底层

在深入命令操作之前,有必要理解 UFW 在 Linux 网络栈中的位置。这将帮助您在遇到高级问题时不至于束手无策。

📐 UFW 与 iptables / nftables 的关系

UFW 本身并不是一个独立的防火墙引擎,而是一个"前端"(frontend)。它的工作原理是将您输入的简洁命令翻译成底层的 netfilter 规则:

组件角色说明
netfilter内核框架Linux 内核中真正执行数据包过滤的模块
iptables传统用户态工具直接与 netfilter 交互的经典命令行工具(正在被淘汰)
nftables现代用户态工具iptables 的继任者,性能更优,语法统一,已成为 2025-2026 年主流发行版的默认后端
UFW高级前端将用户命令翻译为 iptables 或 nftables 规则

在较新的系统中(如 Ubuntu 22.04+、Debian 11+),UFW 实际上已经在后台使用 nftables 作为其翻译目标。这意味着当您使用 UFW 时,您间接地享受了 nftables 带来的性能提升(例如在处理大量规则时更高效的查找速度和原子化规则更新)。作为用户,您通常不需要关心底层使用的是哪一个——UFW 会自动处理兼容性问题。

📊 三者的选择建议(参考 BaeldungBetter Stack 的对比分析):

场景推荐工具
🖥️ 个人桌面 / 中小型 VPSUFW
🏢 需要精细 NAT / 端口转发的复杂网络nftables(直接使用)
🏗️ 维护遗留系统iptables(仅限必要时)

三、常用操作指令

UFW 的强大之处在于其接近自然语言的命令行语法:

🔌 启用与状态查询

使用 sudo ufw enable 激活防火墙,并通过 sudo ufw status verbose 查看详细的运行状态和已生效规则。

verbose 参数会额外显示默认策略、日志级别以及每条规则的协议方向等详细信息。不加 verbose 则只会显示精简的规则列表。

# 激活防火墙
sudo ufw enable

# 查看详细状态(推荐日常使用)
sudo ufw status verbose

# 查看带编号的规则列表(用于后续删除规则)
sudo ufw status numbered

示例输出解读:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
443/tcp (v6)               ALLOW IN    Anywhere (v6)

在这个输出中:

  • Default: deny (incoming), allow (outgoing) 表明入站默认拒绝、出站默认允许
  • Logging: on (low) 表示日志记录已开启,级别为 low
  • 每条规则都同时显示了 IPv4 和 IPv6(带 (v6) 后缀)的版本,说明 IPv6 保护已生效
  • disabled (routed) 表示路由/转发流量的过滤默认是关闭的

🌐 精准开放端口

若要运行 Web 服务器,需开放 80 (HTTP) 和 443 (HTTPS) 端口:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

更多端口操作示例:

# 开放 UDP 端口(例如 DNS 服务)
sudo ufw allow 53/udp

# 开放端口范围(必须指定协议)
sudo ufw allow 8000:8100/tcp

# 拒绝特定端口的入站流量
sudo ufw deny 3306/tcp   # 拒绝外部直接访问 MySQL

💡 注意:指定端口范围时,必须同时指定协议(tcpudp),否则 UFW 将拒绝该命令。这是因为端口范围语法需要明确的协议上下文来正确生成底层规则。

🔒 限制特定来源

如果您只想让特定的办公 IP 访问服务器,可以使用:

sudo ufw allow from 192.168.1.100

更精细的来源控制示例:

# 允许整个子网访问 SSH(例如公司内网 10.0.0.0/24)
sudo ufw allow from 10.0.0.0/24 to any port 22 proto tcp

# 仅允许特定 IP 访问特定端口(例如数据库管理)
sudo ufw allow from 203.0.113.50 to any port 5432 proto tcp

# 拒绝来自特定 IP 的所有流量
sudo ufw deny from 198.51.100.0/24

# 允许特定 IP 访问特定网络接口(多网卡场景)
sudo ufw allow in on eth0 from 192.168.1.0/24

⚡ 规则顺序非常重要:UFW 的规则是按顺序从上到下依次匹配的,一旦某条规则匹配成功,后续规则将不再被检查。因此,更具体的规则应该放在更宽泛的规则之前。例如,如果您先添加了 allow from 10.0.0.0/24,再添加 deny from 10.0.0.5,那么来自 10.0.0.5 的流量仍然会被第一条规则放行。正确的做法是先添加 deny 规则。

如果需要在特定位置插入规则,可以使用编号插入:

# 在规则列表的第 1 条位置插入新规则
sudo ufw insert 1 deny from 10.0.0.5

🗑️ 删除规则

防火墙规则并非一劳永逸。随着业务变化,及时清理过时的规则是安全维护的重要环节。UFW 提供两种删除方式:

方法一:按编号删除(推荐)

# 先查看带编号的规则列表
sudo ufw status numbered

# 删除指定编号的规则(例如删除第 3 条)
sudo ufw delete 3

⚠️ 注意:每删除一条规则后,后续规则的编号会自动重新排列。因此,如果需要连续删除多条规则,请每次删除后重新运行 status numbered 确认编号,或从最大编号开始倒序删除。

方法二:按规则内容删除

# 直接引用原始规则来删除
sudo ufw delete allow 80/tcp
sudo ufw delete deny from 198.51.100.0/24

如果需要完全重置所有规则恢复到初始状态:

# 重置 UFW(会禁用防火墙并删除所有规则)
sudo ufw reset

四、进阶安全技巧

📦 应用配置(Application Profiles)

UFW 能识别常见服务。通过 sudo ufw app list 查看系统预设,例如可以直接使用 sudo ufw allow 'Nginx Full' 来代替手动输入端口号。

应用配置文件存储在 /etc/ufw/applications.d/ 目录下,当您安装支持 UFW 的软件包(如 Nginx、Apache、OpenSSH)时,对应的配置文件会自动创建。

常见的应用配置示例:

配置名称开放的端口说明
OpenSSH22/tcpSSH 服务
Nginx HTTP80/tcp仅 HTTP
Nginx HTTPS443/tcp仅 HTTPS
Nginx Full80/tcp + 443/tcpHTTP + HTTPS
Apache Full80/tcp + 443/tcpHTTP + HTTPS
# 查看系统中所有可用的应用配置
sudo ufw app list

# 查看某个应用配置的详细信息
sudo ufw app info 'Nginx Full'

# 使用应用配置名称添加规则
sudo ufw allow 'Nginx Full'

💡 使用应用配置的好处不仅是省去记忆端口号的麻烦,更重要的是当服务的端口发生变化时(虽然罕见),包维护者会更新配置文件,您的规则会自动适配新端口。

🛡️ 防御暴力破解

使用 sudo ufw limit ssh。该规则会自动监测 SSH 连接频率,如果同一 IP 在 30 秒内尝试连接超过 6 次,防火墙将暂时封锁该地址。

深入理解 ufw limit 的工作原理:

当您执行 sudo ufw limit ssh 时,UFW 在底层会生成使用 iptables recent 模块(或 nftables 等效机制)的规则。该模块通过 conntrack --ctstate NEW 追踪每个源 IP 的新连接,并使用 --seconds 30 --hitcount 6 参数来判定阈值。一旦触发,该 IP 将被临时封锁(参考 nixCraftsimplificandoredes 的详细分析)。

# 启用 SSH 速率限制
sudo ufw limit ssh/tcp comment 'Rate limit for openssh server'

# 验证规则已生效
sudo ufw status
# 输出中应显示:22/tcp   LIMIT   Anywhere

⚠️ 需要注意的限制:

  • 速率阈值(6 次/30 秒)是硬编码在 UFW 中的,无法通过 ufw limit 命令调整。如果需要自定义阈值,需要直接编辑底层 iptables/nftables 规则
  • 对于使用 CI/CD 管道或自动化脚本的场景,短时间内频繁建立 SSH 连接可能会误触速率限制。在这种情况下,建议将 CI/CD 服务器的 IP 单独设置为 allow 而非 limit
  • ufw limit 对 HTTP/HTTPS 端口要谨慎使用——因为许多合法用户可能在 NAT 或代理服务器后面共享同一个公网 IP,速率限制可能会影响正常访问

🔗 UFW + Fail2Ban:构建更强的纵深防御

ufw limit 提供了基础的速率限制,但对于需要更精细控制的生产环境,推荐搭配 Fail2Ban 使用。两者的分工如下:

工具防护机制特点
ufw limit基于连接频率的即时封锁简单高效,阈值固定(6 次/30 秒)
Fail2Ban基于日志分析的智能封锁阈值可自定义,封禁时长可调,支持递进式惩罚

Fail2Ban 的基本工作流程:

📋 监控日志文件(如 /var/log/auth.log)→ 🔍 检测失败的登录尝试 → 📊 统计同一 IP 的失败次数 → 🚫 超过阈值时通过 UFW 自动添加 deny 规则 → ⏰ 封禁时间到期后自动解除

快速部署示例(参考 DigitalOceanDEV Community 的教程):

# 安装 Fail2Ban
sudo apt update && sudo apt install fail2ban -y

# 创建本地配置文件(不要直接修改 jail.conf)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

/etc/fail2ban/jail.local 中配置 SSH 监控:

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 5          # 允许的最大失败次数
findtime = 600        # 检测时间窗口(秒):10 分钟内
bantime  = 3600       # 封禁时长(秒):1 小时
action   = ufw        # 使用 UFW 作为封禁动作的执行者
# 启动并设置开机自启
sudo systemctl enable fail2ban && sudo systemctl start fail2ban

# 查看 SSH 监控状态
sudo fail2ban-client status sshd

💡 最佳实践:ufw limit 和 Fail2Ban 可以同时启用,它们工作在不同的层面,不会冲突。ufw limit 提供即时的连接频率防护,而 Fail2Ban 则提供基于认证失败日志的更智能防护。两者叠加使用可以构建更强的纵深防御。

🌍 IPv6 支持

现代网络多采用双栈协议。请确保 /etc/default/ufw 文件中的 IPV6=yes,以同步保护 IPv6 流量。

在 2025-2026 年,IPv6 的普及率持续上升,许多云服务提供商默认为新实例分配 IPv6 地址。如果您的 UFW 没有启用 IPv6 支持,攻击者可能会通过 IPv6 地址绕过您精心配置的 IPv4 防火墙规则——这相当于您锁好了前门,却留下了后门敞开。

# 检查当前 IPv6 支持状态
grep IPV6 /etc/default/ufw
# 应输出:IPV6=yes

# 如果显示 IPV6=no,则需要编辑该文件
sudo nano /etc/default/ufw
# 将 IPV6=no 改为 IPV6=yes,保存后重新加载 UFW

sudo ufw disable && sudo ufw enable

IPV6=yes 启用后,您通过 ufw allow 添加的每条规则都会自动生成对应的 IPv4 和 IPv6 版本(在 ufw status 输出中可以看到带 (v6) 后缀的规则),无需手动维护两套规则。

📝 日志管理

日志是安全审计和故障排查的基石。UFW 提供了多个日志级别,可根据实际需求灵活调整(参考 Ubuntu ManpageLinux Handbook 的说明):

# 开启日志(默认 low 级别)
sudo ufw logging on

# 设置特定日志级别
sudo ufw logging medium

各日志级别详解:

级别记录内容速率限制适用场景
off不记录任何日志不推荐用于生产环境
low被拒绝的数据包(不匹配默认策略的)+ 匹配已记录规则的✅ 有日常运维(默认推荐)
mediumlow 的内容 + 无效数据包、新连接、速率受限的数据包✅ 有需要更多可见性时
highmedium 的内容(取消速率限制)+ 所有数据包✅ 部分有短期故障排查
full记录所有数据包❌ 无仅用于临时调试

⚠️ 磁盘空间警告:medium 级别以上的日志在繁忙系统上会快速填满磁盘。建议日常使用 low 级别,仅在需要排查问题时临时提升到 mediumhigh,排查完毕后立即恢复。同时,请确保系统的日志轮转(logrotate)配置正常工作。

日志文件位置:/var/log/ufw.log(也可能同步出现在 /var/log/syslog/var/log/kern.log 中)。

查看日志的常用命令:

# 实时追踪防火墙日志
sudo tail -f /var/log/ufw.log

# 查看最近被拦截的连接
sudo grep 'BLOCK' /var/log/ufw.log | tail -20

五、真实场景实战配置

理论知识需要与实践结合。以下是几个常见的服务器角色对应的 UFW 配置方案,您可以根据实际需求调整。

🖥️ 场景一:Web 服务器(Nginx/Apache)

# 基础策略
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH 访问(带速率限制)
sudo ufw limit ssh/tcp

# Web 服务
sudo ufw allow 'Nginx Full'    # 或 sudo ufw allow 80/tcp && sudo ufw allow 443/tcp

# 启用防火墙
sudo ufw enable

🗄️ 场景二:数据库服务器(仅内网访问)

sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH 仅允许跳板机访问
sudo ufw allow from 10.0.1.10 to any port 22 proto tcp

# MySQL 仅允许应用服务器子网访问
sudo ufw allow from 10.0.2.0/24 to any port 3306 proto tcp

# PostgreSQL 仅允许特定应用服务器
sudo ufw allow from 10.0.2.20 to any port 5432 proto tcp

sudo ufw enable

🎮 场景三:个人开发机

sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH
sudo ufw limit ssh/tcp

# 本地开发服务器(仅允许本地网络)
sudo ufw allow from 192.168.0.0/16 to any port 3000 proto tcp
sudo ufw allow from 192.168.0.0/16 to any port 8080 proto tcp

sudo ufw enable

六、常见陷阱与排错

在实际使用 UFW 的过程中,有一些高频问题和陷阱需要特别注意。提前了解它们可以帮助您避免很多不必要的麻烦。

🐳 陷阱一:Docker 绕过 UFW(高危)

这是 UFW 用户最容易踩的坑之一,也是最危险的安全隐患。Docker 为了实现容器的网络通信,会直接操作 iptables 规则,完全绕过 UFW 的管控。这意味着即使您的 UFW 配置了 deny incoming,Docker 发布的容器端口仍然对外界完全开放(参考 GitHub ufw-docker 项目nimidam.com 的分析)。

举例说明:您配置了 UFW 拒绝所有入站,然后在 Docker Compose 中使用 ports: "8080:80"。此时外部网络仍然可以通过 8080 端口直接访问容器,UFW 的规则形同虚设。

推荐解决方案:

方案难度说明
🥇 绑定到 localhost⭐ 简单将 Docker 端口映射改为 127.0.0.1:8080:80,然后通过 Nginx/Caddy 反向代理对外提供服务
🥈 配置 DOCKER-USER 链⭐⭐ 中等修改 /etc/ufw/after.rules,将 UFW 规则整合到 Docker 的 DOCKER-USER iptables 链中
🥉 使用 ufw-docker 工具⭐⭐ 中等社区维护的自动化工具,简化 DOCKER-USER 链的配置
# Docker Compose 示例:安全的端口绑定
services:
  webapp:
    image: nginx
    ports:
      - "127.0.0.1:8080:80"   # ✅ 仅监听 localhost
      # - "8080:80"            # ❌ 危险!监听所有接口,绕过 UFW

🔐 陷阱二:SSH 锁定

如果不小心删除了 SSH 放行规则或错误地设置了默认策略,您可能会被永久锁在服务器外面。预防措施:

  • 在修改规则前,确认有物理控制台或带外管理通道(如云服务商的 VNC/Web 控制台)
  • 使用 sudo ufw allow from 您的IP to any port 22 而不仅仅是 sudo ufw allow ssh,这样更精确
  • 如果使用了非标准 SSH 端口(例如 2222),确保放行的是实际使用的端口

🔄 陷阱三:规则持久化与重启

UFW 的规则在重启后会自动保持生效(前提是 UFW 服务处于启用状态)。但需要注意以下几点:

  • 使用 sudo ufw enable 后,UFW 会在系统启动时自动加载。可通过 sudo systemctl status ufw 确认
  • 直接编辑 /etc/ufw/ 目录下的配置文件(如 before.rulesafter.rules)后,需要执行 sudo ufw reload 使更改生效
  • sudo ufw reset 会删除所有规则并禁用 UFW,请谨慎使用

七、安全加固清单

以下是一份综合的服务器安全加固清单,UFW 只是其中的一环。真正的安全需要多层次的纵深防御(参考 DigitalOcean 硬化指南LinuxSecurity 的建议):

🔥 防火墙层

🔑 SSH 层

🤖 自动化防护层


八、快速参考卡片

将以下命令表保存为速查手册,方便日常运维时快速查阅:

操作命令
启用防火墙sudo ufw enable
禁用防火墙sudo ufw disable
查看状态(详细)sudo ufw status verbose
查看状态(带编号)sudo ufw status numbered
设置默认拒绝入站sudo ufw default deny incoming
设置默认允许出站sudo ufw default allow outgoing
允许端口sudo ufw allow 端口号/协议
拒绝端口sudo ufw deny 端口号/协议
速率限制sudo ufw limit 端口号/协议
允许特定 IPsudo ufw allow from IP地址
允许子网访问端口sudo ufw allow from IP/掩码 to any port 端口号
使用应用配置sudo ufw allow '应用名'
查看应用列表sudo ufw app list
删除规则(编号)sudo ufw delete 编号
删除规则(内容)sudo ufw delete allow 端口号/协议
插入规则sudo ufw insert 位置 规则
开启日志sudo ufw logging on
设置日志级别sudo ufw logging 级别
重新加载规则sudo ufw reload
完全重置sudo ufw reset

九、小结

UFW 将底层的复杂逻辑封装成了易用的命令,是桌面用户和中小型服务器管理员的首选。正如 Ubuntu 官方文档 所强调的,定期审查规则列表(status numbered)并及时删除过时规则,是保持系统长期安全的关键。

但请始终牢记:防火墙只是安全体系的一环,而非全部。真正的安全需要纵深防御——防火墙规则 + SSH 加固 + 自动化入侵检测 + 及时的安全补丁更新,这些层面缺一不可。在 2026 年的威胁环境下,仅依赖单一工具是远远不够的。将 UFW 作为起点,逐步构建您的完整安全防护体系,才是正确的安全策略。


📚 参考资料与延伸阅读: