5 刀一个月的新加坡 VPS,跑一个独享的翻墙节点,最大的隐藏成本不是钱,是你在它上面踩的每一个坑。

我把整个过程从头到尾走了一遍,记一下,给以后自己换机器、给想自建的朋友省一两个晚上。

起点:装完了,但是不通

环境是这样的:

  • VPS:Vultr 新加坡,$5/月,1C1G/25G SSD/1TB 流量
  • 系统:Ubuntu 24.04 LTS
  • 协议栈:3x-ui v2.9.2 + Xray + VLESS+REALITY,伪装 SNI 选了 www.oracle.com

3x-ui 装完,节点也建了,443 在 ss -tlnp 里看着也好好的。但客户端连不上,浏览器直接访问 https://<VPS_IP> 也超时。

第一反应就是怀疑现场 WiFi 出口给我封了——毕竟人在新加坡,家里到 Vultr 新加坡机房,理论上同城应该秒通。

三个一组的端口测试,立刻定位

懒得乱猜,跑一组并行测试:

ping -c 3 <VPS_IP>
nc -zv <VPS_IP> 22       # SSH
nc -zv <VPS_IP> 80
nc -zv <VPS_IP> 443

结果:

测试 结果
ICMP ping ✅ 通(84ms)
TCP 22 (SSH) ✅ 通
TCP 80 ❌ 超时
TCP 443 ❌ 超时

排除掉的可能:

  • ❌ 不是当前 WiFi 的封锁——如果是,22 也该不通
  • ❌ 不是 VPS 死机——ping/SSH 都正常
  • ❌ 不是 IP 被运营商屏蔽——ICMP 通

剩下三种最可能的:Vultr 控制台的云防火墙、VPS 系统的 ufw/iptables、或者 xray 没真的 listen 在 0.0.0.0:443。

SSH 进去一查:

ss -tlnp | grep -E ':(80|443|2053)'
ufw status verbose

ss 输出说 xray 老老实实 listen 在 *:443,从内部 curl -k https://127.0.0.1:443 也能 TLS 握手成功——服务本身没问题。问题在 ufw:

Status: active
Default: deny (incoming), allow (outgoing)

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

只放了 22。Ubuntu 装了 ufw 是默认拦一切的,3x-ui 安装脚本也不会帮你开 443。一行修:

ufw allow 443/tcp

立马就通了。

这个坑的本质:3x-ui 把"程序 listen 端口"和"端口对外可达"当成了一回事,但 Linux 上这是两层。装完不通,永远先看 ufw status,比看 xray 日志快十倍。

测速:体感跟数字是两回事

通了之后第一件事是测速。在 VPS 上跑 speedtest:

下行: 3495 Mbps
上行: 2642 Mbps

这个数字看着爽,但客户端连上以后用 fast.com 测,只有 16 Mbps。差了两百倍——是 VPS 被偷偷限速了吗?

不是。两个测试的链路完全不一样:

VPS speedtest 测的是:
  VPS ──(机房光纤,1.8ms)── speedtest新加坡节点
  纯机房内网,VPS 出口能力的天花板

客户端测的是:
  你的设备 ──(WiFi)── 路由器 ──(运营商出口)
        ──(跨网到 Vultr,84ms)── VPS
        ──(VLESS 隧道)── VPS 内网 ──(机房)── speedtest
  端到端 5 跳,最慢的那跳决定速度

84ms 的 RTT 单 TCP 连接受窗口限制,理论上限就在 16-20Mbps 上下,跟我测出的体感完全吻合。Clash/Xray 真正用的时候是多连接并发,体感能拉到 50-100Mbps。

VPS 的"出口带宽"和你能感受到的"翻墙速度"不是一回事。前者是机房光纤的能力,后者受限于你到 VPS 的那段公网,再被 RTT 卡一刀。

CPU 才 1%,是不是还能塞点东西?

跑了一天看一眼 htop:CPU <1%,内存 369/955 MB。$5 都花了,闲着就觉得亏。一开始想塞 Vaultwarden(密码管理)、Memos(笔记)、AdGuard Home、RSSHub 一堆。

后来想清楚了——Cloudflare Pages/Workers 能搞定的别自托管。博客、笔记、密码管理这种,Cloudflare 全免费,签证书、扛攻击都不用我管。自己塞进 VPS 反而要装 Docker、配 Caddy、定期升级、出问题还得自己救。

VPS 唯一不可替代的优势是:

  • 后台长时间任务:aria2 离线下载海外资源
  • 不能跑在 serverless 上的服务:要常驻进程、要 puppeteer、要超过 10ms CPU 的逻辑

我盘了一圈自己的需求,发现真没有非自托管不可的东西。最后结论:

开服务器不是为了榨干 CPU,是为了你需要的时候它在那儿。

什么都不塞,就让它一直跑 VPN,反而是这 5 刀最舒服的花法。

顺便说说 Vultr 的计费坑

很多人栽在这上面:关机不停费

Vultr 是按小时计费 + 流量配额的双轨制:

  • $5 套餐 ≈ $0.007/小时,月封顶 $5
  • 网页控制台点 Stop、系统里 shutdown -h now,仍然计费——因为实例还占用 IP、磁盘、配额
  • 想停止扣费唯一方法:Destroy(销毁实例),但销毁后 IP 和数据全丢
  • 流量含 1TB/月,超出 $0.01/GB

如果你只是临时不用,5 刀就让它开着;想保住 IP 又省钱可以用 Reserved IP($3/月独立保留),不过单 VPS 没必要。重点是去后台开 Bandwidth Alert,等会儿讲。

订阅 URL:base64 还是 yaml,老 Clash 不认

3x-ui 自带订阅服务,端口是 2096,路径可以自己设随机串防扫描。开起来之后能直接生成订阅 URL:

http://<VPS_IP>:2096/sub_<random12hex>/<subId>

填到 Clash Verge / V2RayN 里立即生效,多设备一处改全员同步,每 12 小时客户端自己拉最新配置。

但是!手机上一个老版本的 Clash for Android 死活不认——因为 3x-ui 默认订阅响应是 base64 编码的 vless:// 链接列表,而老 Clash 只认原生 yaml 格式,根本不支持 VLESS 协议。

两条路:

A. 换客户端——ClashMetaForAndroid(CMFA),或者 mac 上的 Mihomo Party / Clash Verge Rev / ClashX Meta,全都支持 VLESS,跨设备一致。

B. 自己生成 yaml ——在 VPS 上装个 Caddy,把节点参数渲染成 Clash Meta 格式的 yaml 文件,托管在另一个端口和随机路径下:

http://<VPS_IP>:8080/<random12hex>/clash.yaml

所有 Clash 系客户端无差别识别。代价是这是个静态文件,节点变了要手动重新生成。

我两个都开了——base64 给 V2RayN 用,yaml 给 Clash 系用,路径都带 12 位随机 hex 防扫描。

安全加固:上线 24 小时已经被扫了

有了订阅 URL 之后,开始想"这玩意儿真的扛得住别人攻击吗"。

第一件事看 SSH 登录失败日志:

journalctl -u ssh | grep "Failed password" | wc -l

24 小时 210 次失败,主力是俄罗斯一个 IP 段(80.94.92.0/24)持续在扫。再看看 SSH 配置:PermitRootLogin yes、密码登录、没装 fail2ban。这一套就跟把家门钥匙挂在门把手上没区别。

我做了三件事,性价比从高到低:

1. fail2ban + 系统补丁

apt update && apt upgrade -y
apt install -y fail2ban
systemctl enable --now fail2ban

默认配置就是 SSH 5 次失败封 1 小时,装完几分钟内立刻封了那个俄罗斯段的 5 个 IP。这个收益最大——所有自动化扫描立刻失效。

2. 3x-ui 面板改成只听 127.0.0.1

面板默认监听 0.0.0.0:2053,虽然 ufw 没放行,外网摸不到,但单层防御总是不安全。改成只听本地,以后哪怕 ufw 误开端口也不会暴露面板:

# 在 3x-ui 面板 → 面板设置里把"监听 IP"改成 127.0.0.1
# 或者直接改数据库
sqlite3 /etc/x-ui/x-ui.db \
  "UPDATE settings SET value='127.0.0.1' WHERE key='webListen';"
systemctl restart x-ui

代价是以后访问面板必须走 SSH 隧道:

ssh -L 2053:127.0.0.1:2053 root@<VPS_IP> -N
# 浏览器打开 http://127.0.0.1:2053

不方便,但只有自己能进。

3. 跳过的几个

  • SSH 密钥登录 —— 本地没配过密钥,麻烦,密码 16 位混合 + fail2ban 已经够
  • SSH 端口换号 —— 噪音再多也是噪音,没增益
  • IP 白名单 —— 5G/酒店/公共 WiFi 经常切,不现实
  • Cloudflare 套域名 —— 不想再绑域名

跑完这三步,自动化扫描这条最大攻击面被堵死,剩下的风险只剩"密码被撞库",强度足以扛。

真正想清楚的问题:URL 泄露 = 账单失控

加固完之后我才想明白一件更深的事:

订阅 URL 一旦泄露,谁拿到 yaml 都能直接用我的 VPS 翻墙。

如果攻击者拿到 URL(中间人嗅探、不小心复制错地方、被人转发),就能:

玩法 后果
挂 4K 视频 1TB ≈ 100 小时刷爆
跑爬虫/挖矿/CC 几天 5-10TB
超 1TB 后 $0.01/GB,10TB = $90,100TB = $999

URL 路径再随机也没用——一旦泄露就是永久泄露,靠"猜不到"已经失效。Vultr 不会自动封顶,账单理论上能失控。

这才是自建 VPN 真正应该担心的事,比 GFW 封 IP 还要紧。

三层防御 + 一道兜底

3x-ui / Xray 在协议层有原生限额支持,无视 URL 泄露:

{
  "limitIp": 3,        // 最多 3 个不同 IP 同时连
  "totalGB": 200,      // 月流量 200GB,超了自动停
  "expiryTime": 0      // 不过期
}

核心机制:即使 URL 全网公开,攻击者最多只能 3 个 IP 同时连,且共用 200GB 月度上限。配合 Vultr 含 1TB,永远刷不爆。

再设月度自动重置(数据库里的 traffic_reset = monthly),每月 1 号 0 点清零,被刷爆下月还能用。

最后一道兜底——Vultr 后台开 Bandwidth Alert:

Account → Notifications → Bandwidth Alerts
阈值设 80%(800GB)

理论上 client 200GB 自动停在前,VPS 总流量根本到不了 800GB。Vultr 邮件告警是兜底,万一 Xray 的 200GB 限额因为某个 bug 失效,至少能在出账单前知道。

最坏情况推演:

URL 全网公开
  ↓
xray 检查同时连接 IP > 3 → 拒绝
  ↓
即使能进,所有流量计入这个 client
  ↓
累计 200GB 后自动停用 client
  ↓
Vultr 1TB 配额内,永远不收超额费
  ↓
异常 → 后台一键重置 UUID,老 yaml 全部失效

最大可能损失:200GB / 月,0 元

最终的端口和资源占用

22    ufw allow            ← SSH,fail2ban 自动封爆破
443   ufw allow → xray     ← VPN(VLESS+REALITY)
2053  127.0.0.1 only       ← 3x-ui 面板,SSH 隧道访问
2096  ufw allow → x-ui     ← base64 订阅
8080  ufw allow → caddy    ← Clash yaml 订阅

资源占用:

服务 内存
xray + 3x-ui ~100 MB
caddy ~15 MB
fail2ban ~30 MB
系统 ~200 MB
总计 ~350 MB / 955 MB

CPU 常年 1% 以下,富余巨大,但我什么都不打算再塞了。

结尾的几条心得

  1. ss -tlnp 跟外网可达不是一回事——程序在 listen 不代表别人能连进来,永远先看 ufw。
  2. VPS 出口带宽是天花板,不是体感——你的速度由本地→VPS 那段公网决定,跨网就是跨网,不是钱能解决的。
  3. 不要为了"榨干 CPU"塞服务——能用 Cloudflare 解决的别自托管,每塞一个就多一份维护成本和攻击面。
  4. 订阅 URL 的真实威胁是账单刷爆,不是被 GFW 发现——URL 泄露不可恢复,必须在协议层(limitIp + totalGB)做硬限制。
  5. fail2ban + 关闭 root 密码 + 面板 127.0.0.1——三件套做完,剩下能打到你的攻击都不便宜。

5 刀一个月的隐性成本不是钱,是你愿意花多少时间把它跑出"放着不用管"的状态。这套配置基本上做到了:节点自己跑、订阅自己同步、被攻击 fail2ban 自动挡、被偷流量协议层自动停。

剩下的就是每月 1 号收 Vultr 那封 5 刀的扣费邮件。