Decentralization? We're still early!

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

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

    發布人 Brave 2026-02-24 13:53

    在 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 作为起点,逐步构建您的完整安全防护体系,才是正确的安全策略。


    📚 参考资料与延伸阅读:

    Brave 回复 1 week, 6 days ago 1 成員 · 0 回复
  • 0 回复

歡迎留言回复交流。

Log in to reply.

讨论開始
00 回复 2018 年 6 月
現在