新买的 Linux VPS 刚装好系统,公网 IP 立刻暴露在扫描器视野里。我们监控过一台刚开机的 Ubuntu 22.04:上线不到四小时,/var/log/auth.log 里就出现了上千条来自全球的 SSH 暴力破解尝试。云厂商的安全组能挡一部分,但系统内的防火墙才是你真正可控的第二道门。
对 Ubuntu / Debian 系服务器来说,UFW(Uncomplicated Firewall) 几乎是默认答案:语法简单、和 iptables 无缝衔接、文档齐全。本文不讲 iptables 的几十条链式规则,而是把我们在生产环境里反复验证过的一套 UFW 配置流程整理成清单——从安装、放行 SSH,到网站端口、Docker 共存、与云安全组协同,以及最重要的:怎样配置防火墙而不把自己锁在门外。
前提:你已通过 SSH 或云控制台 VNC 登录服务器,且有 sudo 权限。若 SSH 已经连不上,请先参考我们的 Linux 服务器 SSH 连接被拒排查指南,确认是网络问题还是防火墙问题,再回来继续读。
为什么云服务器必须配防火墙?
很多人以为「买了云就有安全组,系统里不用再管」。实际上两层职责不同:云安全组在虚拟网卡外侧过滤流量,由控制台管理;UFW在操作系统内核的 netfilter 层过滤,由你通过命令行管理。只开一层,等于只锁了大门没锁卧室门——内网横向移动、误暴露的服务、被入侵后的反弹 shell,都需要系统级规则兜底。
UFW 底层仍是 Ubuntu 官方 UFW 文档 所描述的 iptables 前端:你写 ufw allow 22,它翻译成对应的 ACCEPT 规则。好处是语法接近自然语言,ufw status numbered 能一眼看清当前策略,改规则也不容易把自己绕晕。
| 层级 | 工具 | 管理入口 | 典型用途 |
|---|---|---|---|
| 云厂商(外侧) | 安全组 / Network ACL | Web 控制台 | 粗粒度入站:只放 22/80/443 |
| 操作系统(内侧) | UFW / firewalld | SSH 命令行 | 细粒度:按 IP、端口、速率限制 |
| 应用层 | fail2ban / CrowdSec | 配置文件 | 动态封禁暴力破解来源 IP |
第一步:安装与检查 UFW
Ubuntu 桌面版和多数 Server 镜像已预装 UFW,但最小化镜像可能没有。先确认:
sudo apt update sudo apt install ufw -y # 查看当前状态(inactive 表示尚未启用) sudo ufw status verbose # 开机自启(建议在 enable 之前先配好规则) sudo systemctl enable ufw
若输出 Status: inactive,说明规则可以安全地一条条加,还不会生效——这是最好的配置窗口。千万不要在还没放行 SSH 的情况下直接 ufw enable,否则你会立刻失去远程连接。
第二步:放行 SSH(最重要的一条规则)
SSH 是管理通道,必须第一个放行。如果你已把 sshd 改到非标准端口(比如 2222),规则里的端口要与 sshd_config 一致,安全组也要同步改。
# 默认 22 端口 sudo ufw allow 22/tcp comment 'SSH' # 自定义端口 sudo ufw allow 2222/tcp comment 'SSH custom' # 只允许办公室出口 IP(推荐生产环境) sudo ufw allow from 203.0.113.50 to any port 22 proto tcp # 按服务名(/etc/services 里有定义时可用) sudo ufw allow OpenSSH
验证 sshd 确实在监听:sudo ss -tlnp | grep ssh。若看到 0.0.0.0:22 或 [::]:22,说明服务正常。若 ListenAddress 被设成 127.0.0.1,UFW 放行也没用——那是 sshd 配置问题,不是防火墙问题。
关于 SSH 端口与安全组如何配合,可参考 Linux 云主机最小暴露面防火墙决策 FAQ,里面有一张 SSH/HTTPS 取舍矩阵,适合规划长期策略。
第三步:设置默认策略
UFW 的推荐基线是:拒绝所有入站,允许所有出站。出站放开,服务器才能拉 apt 包、访问 API、做 DNS 查询;入站收紧,只开你明确需要的服务端口。
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 查看当前规则(带编号,方便删除)
sudo ufw status numbered
有人想把出站也收紧(比如合规要求),可以 ufw default deny outgoing 再逐条 allow out DNS(53)、HTTPS(443)等。但对大多数 Web / API 服务器来说,出站全放、入站按需开,是性价比最高的方案。
第四步:开放业务端口
按你实际跑的服务加规则。常见组合如下:
# HTTP / HTTPS(Nginx、Caddy、Apache) sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 或用服务名简写 sudo ufw allow 'Nginx Full' # 开发环境临时开放 Node / 其他端口 sudo ufw allow 3000/tcp comment 'dev API' # 指定来源 IP 访问管理面板 sudo ufw allow from 198.51.100.0/24 to any port 8080 proto tcp
生产环境建议:能走 443 反代的,就不要直接暴露 3000/8080。UFW 里只开 22 + 80 + 443 三端口,应用监听 127.0.0.1,由 Nginx 或 Caddy 做 TLS 终结——攻击面立刻小一圈。
第五步:启用并验证
规则加完后,正式启用:
sudo ufw enable
# 会提示可能中断现有 SSH,输入 y 确认
sudo ufw status verbose
sudo ufw status numbered
在另一台机器上测试:nc -zv your.server.ip 22 应返回 open;未放行的端口(比如 3306)应超时或被拒绝。若 SSH 断了,立刻通过云控制台 VNC 执行 sudo ufw disable 回滚,查清缺了哪条规则再重来。
进阶:限速、删除与规则排序
UFW 支持比 allow 更细的操作,几个高频场景:
# 限速:防 SSH 暴力破解(6 次/30 秒) sudo ufw limit 22/tcp # 按编号删除规则(先 status numbered 看序号) sudo ufw delete 3 # 拒绝特定 IP sudo ufw deny from 192.0.2.100 # 重置所有规则(慎用) sudo ufw reset
ufw limit 底层用 iptables 的 recent 模块做连接频率限制,对 SSH 很有效,但不能替代密钥登录和关闭密码认证。规则是按添加顺序匹配的,更具体的规则应放在更前面——若你发现某条 allow 不生效,检查是否被后面的 deny 覆盖。
与 Docker / Kubernetes 共存时要注意什么
这是 UFW 最容易「配了等于没配」的场景。Docker 默认会往 iptables 里插入自己的链,可能绕过 UFW 的规则,导致你以为 3306 没开,实际上容器端口仍对公网可见。
应对方案(按推荐程度排序):
- 容器只绑定 127.0.0.1——
-p 127.0.0.1:3000:3000,由宿主机反代对外 - 在 docker-compose 里不写 ports,走内部网络 + 反代
- 修改 Docker 配置
"iptables": false(需自行维护转发规则,进阶用户) - 用云安全组做最终兜底,即使 Docker 绕过 UFW,外侧仍有过滤
跑 K8s 的节点更复杂,通常用 Calico/Cilium 自己的 NetworkPolicy,UFW 只作为节点级补充。单机 VPS 跑 Docker Compose 的场景,第一条(绑定 loopback)就够用。
云安全组与 UFW 如何协同
两层都要配,而且策略应一致:安全组放了 22,UFW 也要 allow 22;安全组没放 3306,UFW 就算 allow 了,外网也进不来——但内网其他被攻破的机器可能扫得到,所以 UFW 仍要 deny。
推荐分工:
- 安全组:粗粒度,只放 22/80/443,来源 IP 可收紧到办公室或 CDN
- UFW:细粒度,按服务注释、limit SSH、封恶意 IP
- fail2ban:动态层,读日志自动封禁
改完任一层后,用外部探测验证:nmap -p 22,80,443,3306 your.server.ip(请只扫自己的机器)。看到 3306 open 而你没有主动暴露数据库,立刻排查 Docker 绑定或应用监听地址。
排障:UFW 启用后服务访问不了
按这个顺序查,十分钟内能定位大多数问题:
sudo ufw status verbose——规则是否真的在?端口和协议(tcp/udp)对不对?sudo ss -tlnp——应用是否监听0.0.0.0而非127.0.0.1?- 云安全组入站规则是否同步?
- Docker 是否绕过了 UFW?
- 临时
sudo ufw disable做对比测试(测完记得 enable 回来)
若只有某个来源 IP 连不上,查是否有 deny from 或 fail2ban 封禁。UFW 日志默认不详细,需要时可在 /etc/ufw/ufw.conf 里设 LOGLEVEL=medium,然后 sudo ufw reload,再到 /var/log/ufw.log 里看被拒的包。
上线检查清单(可直接复制执行)
新机或重装系统后,按顺序跑一遍:
sudo apt install ufw -y sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp comment 'SSH' # 或你的自定义端口 sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw limit 22/tcp # 可选:SSH 限速 sudo ufw enable sudo ufw status verbose
最后别忘了系统侧加固:SSH 密钥登录、关闭 root 密码登录、定期更新 unattended-upgrades。防火墙是边界,不是万能药——但它能把 90% 的自动化扫描挡在门外,让你有时间做更深的安全配置。
稳定运维节点:让防火墙配置少一层焦虑
管理多台 Linux VPS 时,很多人会备一台固定出口 IP 的跳板机做 SSH 中转——安全组与 UFW 只放行跳板 IP,本机用密钥串连。Mac mini 在这类场景里很合适:macOS 原生 Unix 环境,Terminal 与 OpenSSH 开箱即用;M4 芯片待机功耗仅约 4W,适合 7×24 挂在桌上当中转节点,比再开一台 x86 小主机更省电、更安静。
同价位 Windows 机器长期开着当跳板,功耗和风扇噪音都更高;macOS 崩溃率极低,配合 FileVault 与 Gatekeeper,私钥存放也更安心。若你还需要在 Mac 上跑 Xcode 或 Docker 做发布,云端 Mac mini 可以把「跳板 + 构建」合并到同一节点,减少来回切换。
如果你正在规划一套稳定的远程运维环境, VPSSPark 云端 Mac mini M4 是低功耗跳板与开发节点的务实选择—— 立即了解套餐方案 ,让服务器安全加固不再是深夜独角戏。