VPS 买回来默认是全端口开放的。厂商给你的镜像里通常没有任何防火墙规则,SSH、HTTP 以外还躺着数据库、Redis、Docker API 这些你根本没打算暴露的东西。
Ubuntu 默认装了 UFW(Uncomplicated Firewall,iptables 的前端),但默认是关闭的。这篇讲怎么把它配好,重点在怎么开才不会把自己关在门外 —— 这是 UFW 唯一真正危险的地方。
第一件事永远不是敲 enable,而是看清楚现在有什么。
sudo ufw status verbose
新机器大概率会看到:
Status: inactive
默认策略是这么设计的:
- 入站(incoming):deny —— 拒绝所有
- 出站(outgoing):allow —— 放行所有
所以一旦启用,所有没显式放行的入站端口会被立刻切断。这就是为什么必须先放行 SSH。
出站默认全放行是对的,不用改 —— 服务器要能主动访问外部(更新软件、调用 API、同步数据)。限制出站属于高安全场景的进阶做法,个人 VPS 不需要。
第一,确认 SSH 端口是多少。
sudo ss -lntp | grep sshd
# 或者
sudo grep -E '^Port|^#Port' /etc/ssh/sshd_config
默认是 22,但如果你改过,UFW 里就要放行那个端口,放行 22 是没用的。
第二,确认你有 VNC / 控制台权限。
这是最关键的保命措施。UFW 配错了 SSH 进不去,控制台是你唯一的入口。买机器时确认过有控制台吗?没有的话现在去后台找一下能不能打开。
第三,把规则一次性备好再启用。
不要"先 enable 再慢慢加规则" —— 中间那段时间你可能已经断了。
# 1. 先放行 SSH(必须在 enable 之前!)
sudo ufw allow OpenSSH
# 2. 放行 Web 端口(如果这台机器要跑网站)
sudo ufw allow 80,443/tcp
# 3. 确认规则看着对
sudo ufw show added
# 4. 启用
sudo ufw --force enable
# 5. 立刻验证状态
sudo ufw status verbose
sudo ufw allow OpenSSH 而不是 allow 22 —— OpenSSH 是 UFW 内置的应用配置(app profile),它读的是系统里实际的 SSH 端口。你改过端口的话,用 profile 名比写死端口号更不容易出错。
--force 只是跳过那个 "Command may disrupt existing ssh connections" 的交互确认,不是"强制执行危险操作"。交互场景下不加也行,脚本里必须加。
验证这一步别省:另开一个终端窗口测试 SSH 能连上,确认之后再关掉当前这个会话。
# 放行单个端口(tcp 和 udp 都放行)
sudo ufw allow 8080
# 只放行 tcp
sudo ufw allow 8080/tcp
# 放行端口范围
sudo ufw allow 8000:8100/tcp
# 只允许某个 IP 访问
sudo ufw allow from 203.0.113.5 to any port 3306 proto tcp
# 允许整个网段
sudo ufw allow from 203.0.113.0/24 to any port 22
# 删除规则(两种方式)
sudo ufw delete allow 8080 # 按内容删
sudo ufw delete 3 # 按编号删
先看编号列表:
sudo ufw status numbered
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80,443/tcp ALLOW IN Anywhere
[ 3] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 4] 80,443/tcp (v6) ALLOW IN Anywhere (v6)
如果启用了 IPv6,一条规则会产生两条(v4 和 v6 各一条)。ufw delete 3 只删掉 v6 那条,v4 那条还在。
想一次删干净,用内容删(ufw delete allow 8080),或者照官方手册的建议——把要删的规则原样打一遍,前面加 delete:
sudo ufw delete allow 80,443/tcp # v4 和 v6 一起删
这个坑最容易出现在"我以为删了但规则还在生效"的时候,尤其是排查端口为什么还通的时候。
UFW 是按顺序匹配的,命中第一条就停止,后面的规则不再看。所以:
sudo ufw deny from 203.0.113.5
sudo ufw allow from 203.0.113.5 to any port 22
第二条永远不会生效 —— 因为第一条已经把这台机器的所有流量拒了。
正确顺序是具体的在前,宽泛的在后:
sudo ufw allow from 203.0.113.5 to any port 22 # 先放行特定 IP
sudo ufw deny 22/tcp # 再拒绝其余的
理解这一点,很多"规则写了没生效"就解释得通了。
sudo ufw limit ssh
它放行正常连接,但同一个 IP 在 30 秒内发起 6 次以上连接就会被封禁。
装 Fail2Ban 之后这条的必要性下降,但两个一起用没有坏处 —— UFW 的 limit 在更底层,响应更快,而且不需要额外服务。
注意 limit 也可能误伤自己。 频繁重连(比如调试脚本、自动化工具反复建连)会触发它。真的被自己封了,看 被 Fail2Ban 误封怎么办 的思路 —— UFW 这边是 sudo ufw status numbered 找到规则删掉,或者临时 sudo ufw disable。
不需要记端口号:
# 看有哪些可用的配置
sudo ufw app list
# 看某个配置的详情(用了哪些端口)
sudo ufw app info 'Nginx Full'
# 直接按名字放行
sudo ufw allow 'Nginx Full'
sudo ufw allow 'Nginx HTTP'
常见的几个:
| 配置名 | 端口 |
|---|---|
OpenSSH | 实际的 SSH 端口 |
Nginx HTTP | 80 |
Nginx HTTPS | 443 |
Nginx Full | 80 + 443 |
Apache Full | 80 + 443 |
配置文件放在 /etc/ufw/applications.d/,是简单的 INI 格式,可以自己加。装了 Nginx 之后 Nginx Full 才会出现 —— 这类配置随软件包安装。
UFW 默认同时管理 IPv4 和 IPv6,可以在 /etc/default/ufw 里确认:
IPV6=yes
保持 yes。 设成 no 的话 IPv6 流量会完全不受管 —— 你的服务器如果有 IPv6 地址,等于开了个后门。IPv6 的配置见 IPv6 VPS 配置指南。
这是 UFW 在容器环境下最大的坑,也是最容易造成"以为安全其实没防住"的地方。
原因在于 Docker 自己直接往 iptables 的 nat 和 filter 表里插规则,而且插在 UFW 的规则链之前。结果是:
# docker-compose.yml
services:
db:
ports:
- "3306:3306" # ❌ 这个端口会直接暴露到公网,UFW 拦不住
即使你在 UFW 里没放行 3306,docker run -p 3306:3306 或者上面的 compose 写法照样会让它可访问。
解决办法有三个,从推荐到不推荐:
1. 端口绑定到 127.0.0.1(最推荐)
ports:
- "127.0.0.1:3306:3306" # ✅ 只监听本机,公网访问不到
99% 的场景都应该这么写。 数据库、Redis、内部 API 都不需要暴露到公网,需要远程访问时走 SSH 隧道。做法和原因见 VPS 数据库不要直接暴露公网。
2. 只在 ufw-docker 这类方案下管理
社区有 ufw-docker 脚本,通过调整 iptables 链的顺序让 UFW 能管住 Docker 的端口。能用,但它改的是 Docker 的底层网络规则,Docker 升级后要重新检查。
3. 在 Docker 的 daemon 配置里关掉 iptables 管理
// /etc/docker/daemon.json
{ "iptables": false }
不建议这么做。 关掉之后容器的网络、端口映射、容器间通信都会受影响,你得自己接管全部 iptables 规则。
所以最简单也最可靠的做法就是第 1 条:写 compose 的时候养成习惯,端口前面加 127.0.0.1:。
默认全放行,个人 VPS 保持这样就行。真要收紧,注意别把自己搞瘸 —— 服务器要能访问软件源、DNS、NTP,还要能访问你业务依赖的外部 API。
# 如果真要限制出站(先想清楚,很容易把自己锁死)
sudo ufw default deny outgoing
sudo ufw allow out 53 # DNS
sudo ufw allow out 80,443/tcp # HTTP/HTTPS
sudo ufw allow out 123/udp # NTP
出站规则写错的后果比入站更隐蔽:SSH 能连上(入站是通的),但服务器上什么都下载不了,apt update 报一堆超时,排查半天才想到是防火墙。
sudo ufw logging on # 开启
sudo ufw logging medium # 调整级别:off/low/medium/high/full
日志在 /var/log/ufw.log(部分系统在 /var/log/syslog):
sudo tail -f /var/log/ufw.log
medium 是个好起点 —— low 只记录被拦截的包,medium 还会记录新连接,high/full 在大流量下会产生大量日志,反而不好用。
日志开久了会占磁盘。 配好轮转,做法见 VPS 硬盘满了怎么办,或者用 logrotate 单独管理。
看到大量 UFW BLOCK 不用慌 —— 那就是有人在扫描你的服务器,属于常态。真正该注意的是反复出现的同一个源 IP 尝试连某个端口,那说明那个端口有服务在跑。
命令行够用,但知道文件位置有助于排查:
| 文件 | 作用 |
|---|---|
/etc/ufw/user.rules | IPv4 规则(ufw 命令实际写入的) |
/etc/ufw/user6.rules | IPv6 规则 |
/etc/default/ufw | 默认策略、IPv6 开关 |
/etc/ufw/applications.d/ | 应用配置 |
/etc/ufw/before.rules | 自定义前置规则(Docker 场景会用到) |
不要直接编辑 user.rules —— ufw 命令会覆盖它。要加自定义规则用 before.rules 或 after.rules。
改动之前先备份:
sudo cp -r /etc/ufw /root/ufw-backup-$(date +%F)
开了之后 SSH 连不上
最高频的翻车。如果你当前会话还开着:
sudo ufw allow OpenSSH
sudo ufw reload
如果已经全断了:进 VNC 控制台,或者救援模式。两种自救路线的完整步骤见 开启 UFW 后 SSH 进不去怎么办。
网站能 ping 通但打不开
80/443 没放行,或者只放行了 tcp 没放行你实际用的端口。排查顺序见 VPS 服务启动了但外网访问不了。
规则加了但端口还是不通
按这个顺序查:
sudo ufw status numbered # 1. 规则在不在、顺序对不对
sudo ss -lntp 'sport = :8080' # 2. 服务真的在监听吗
sudo ufw show raw | head -30 # 3. 看底层 iptables 链
第 2 步经常被跳过 —— 防火墙放行了,但服务压根没起来,或者监听在 127.0.0.1 上(那 UFW 放行也没用,因为外部流量根本到不了)。端口占用问题见 VPS 端口被占用怎么办。
Docker 端口 UFW 拦不住
见上面 Docker 那一节 —— 这是设计如此,正解是把端口绑定到 127.0.0.1。
改了 SSH 端口,但旧规则还在
OpenSSH profile 读的是 sshd 的当前配置,改端口后要重新放行新端口、删掉旧的:
sudo ufw allow 2222/tcp
sudo ufw delete allow OpenSSH
sudo ufw reload
顺序别搞反 —— 先加新的,验证能连上,再删旧的。反过来就是自锁。
ufw status 显示 active 但规则列表是空的
说明只有默认策略在生效:所有入站拒绝。这时候如果 SSH 还能连,通常是因为你当前会话是 enable 之前建立的 —— 一旦断开就连不上了。赶紧放行 SSH。
配完之后逐项过一遍:
-
sudo ufw status verbose显示Status: active - 默认策略是
deny (incoming), allow (outgoing) - SSH 端口已放行(用
OpenSSHprofile,或实际端口号) - 网站端口 80/443 已放行(如果跑网站)
- 另开终端验证过 SSH 能连
- Docker 容器的端口都绑定在
127.0.0.1,没有裸的-p 3306:3306 -
IPV6=yes,且 IPv6 规则也放行了需要的端口 - 日志按需开启,且配了轮转
-
/etc/ufw备份过
UFW 和 iptables 什么关系?
UFW 是 iptables 的前端 —— 你敲的每条规则最终都变成 iptables 规则。好处是语法简单、不容易写错;代价是不如 iptables 灵活,某些复杂场景(比如按连接状态做策略)要写自定义规则文件。
能和 firewalld 一起用吗?
不要同时用。 两个都是前端,会互相覆盖规则,结果不可预测。Debian/Ubuntu 用 UFW,RHEL 系用 firewalld,各用各的。发行版选择的差异见 VPS 装什么系统。
改了端口之后要 reload 吗?
ufw allow/delete 立即生效,不需要 reload。ufw reload 用在直接改了 /etc/ufw/ 下的文件之后。
ufw disable 会清空规则吗?
不会。规则还在,只是不生效。enable 之后原样恢复。要清空用 sudo ufw reset —— 那会把所有规则和自定义配置都删掉,属于推倒重来。
云厂商的安全组和 UFW 冲突吗?
不冲突,是两层,都要过。典型的"端口不通"是安全组放行了但 UFW 没放行(或者反过来)。排查任何一个端口问题时,两层都要查:先在云控制台看安全组,再看 UFW。
要不要把 SSH 端口改成非 22?
降低扫描噪音有效,但不是安全措施 —— 端口扫描一样能发现。真正的防线是密钥登录(见 VPS 配置 SSH 密钥登录)。改端口的主要好处是让日志干净些。
UFW 能防 DDoS 吗?
不能。 它挡不住流量型的攻击 —— 带宽被打满时,包根本到不了你的服务器。DDoS 要在上游解决(CDN、高防),见 VPS 网站被 CC 攻击怎么办。
- VPS 开启 UFW 后 SSH 进不去怎么办 — 配错了怎么救回来
- VPS 服务启动了但外网访问不了 — 端口不通的完整排查顺序
- VPS 安全加固指南 — 防火墙之外还要做什么
- VPS 被 Fail2Ban 误封怎么办 — 限速和 Fail2Ban 的配合
- VPS 配置 SSH 密钥登录 — 比改端口更有效的防护
