VPS 自建 / 02

私人小机场:多个节点的搭建

在 Debian 上将已验证的 sing-box Reality 配置复制到香港、日本和美国 VPS,再部署 Sub-Store 管理多个节点,生成客户端订阅。

当第一个 Reality 节点稳定运行后,可以把同一份 sing-box 配置复制到香港、日本和美国 VPS,组成只供自己、家人或少量可信设备使用的“私人小机场”。

系统范围:本篇仅适用于 Debian 12/13。 香港、日本和美国服务器都应安装 Debian,并使用相同的软件源、systemd 服务和目录结构。Alpine、Ubuntu 及其他系统不在本篇操作范围内,不要直接照抄命令。

这篇只在已跑通的节点上增加两件事:复制配置到其他 VPS,再用 Sub-Store 管理订阅。具体步骤如下:

  1. 先确定可用配置: 让所有服务器运行同一份 VLESS + TCP + Reality + Vision 配置,减少重复填写。
  2. 保持关键参数一致: UUID、Reality 密钥、Short ID、端口和 SNI 不变,确保客户端只维护一套凭据。
  3. 只区分地址与名称: 每个客户端节点仅修改服务器 IP 和地区名称,最不容易填错。
  4. 最后集中管理订阅: 用 Sub-Store 保存多个节点,并按不同客户端输出所需格式。

开始前应先完成搭建第一个节点:sing-box Reality + VLESS Vision,并在该文选择 普通 VPS(Debian / Ubuntu) 路线、使用 Debian 跑通第一个节点。本文不会重新生成密钥,而是复用已经通过测试的 Debian 服务端配置。

这套方案部署和换机非常简单;代价是任意一台服务器上的私钥泄露,都需要为全部节点更换同一套密钥和 UUID。节点只应分享给可信设备,不适合对外售卖或大规模多人使用。

私人多节点通过 Sub-Store 管理香港、日本和美国出口的拓扑

规划香港、日本和美国节点

节点推荐线路主要用途购买选择
香港RFCHost HK-CO日常主力、低延迟Mini 起步
日本RFCHost JP-CO(官网当前为 JP2-CO)日本内容、香港故障时切换Micro 或 Mini
美国VMISS US.LA.TRI三网优化、大流量和海外服务Pro 起步

香港:RFCHost HK-CO

香港适合作为默认主力。仅运行 sing-box 时,HK-CO-Mini 的 1 核、1 GB 内存和 1,500 GB 流量已经足够;同时部署监控或其他服务再考虑 Standard。

查看 RFCHost HK-CO

日本:RFCHost JP-CO

RFCHost 官网当前将完整的日本优化线路标为 JP2-CO。预算优先可选 Micro,希望获得更宽裕内存和更大端口则选 Mini。本文所说的 JP-CO 对应当前 JP2-CO 产品线。

查看 RFCHost JP2-CO

美国:VMISS 洛杉矶 TRI

VMISS 的 US.LA.TRI 面向三网优化。Pro 配置足以承载个人节点,通常比香港套餐拥有更大的端口和更充足的月流量,适合作为下载、海外服务或故障切换节点。

查看 VMISS US.LA.TRI

建议先按月购买,分别在晚高峰测试自己的宽带和手机网络。地区名称相同不代表本地路由表现相同,最终顺序应以实际丢包、延迟和速度为准。

准备统一的可用配置

在第一台节点上确认服务正常:

sing-box check -c /etc/sing-box/config.json
systemctl is-active sing-box
ss -lntp | grep ':443'

把当前配置复制为可用配置并记录校验值:

install -m 600 /etc/sing-box/config.json /root/sing-box-golden.json
sha256sum /root/sing-box-golden.json

以下字段在所有服务器上必须保持一致:

  • users.uuid
  • users.flow
  • tls.reality.private_key
  • tls.reality.short_id
  • listen_port
  • tls.server_name
  • tls.reality.handshake.server

服务器地址不写在服务端配置中,所以同一文件可以直接部署到不同 VPS。客户端只需使用不同 IP 和节点名称。

在每台 VPS 安装相同环境

三台服务器必须使用 Debian 12 或 Debian 13,并完成上一篇文章中的系统更新、BBR,以及停止并禁用 UFW 的新手设置。本文后续的 APT、systemd、目录和日志命令均按 Debian 编写。

在每台新 VPS 上通过官方 APT 源安装:

apt update
apt install -y curl ca-certificates gnupg
mkdir -p /etc/apt/keyrings

curl -fsSL https://sing-box.app/gpg.key \
  -o /etc/apt/keyrings/sagernet.asc
chmod a+r /etc/apt/keyrings/sagernet.asc

cat >/etc/apt/sources.list.d/sagernet.sources <<'EOF'
Types: deb
URIs: https://deb.sagernet.org/
Suites: *
Components: *
Enabled: yes
Signed-By: /etc/apt/keyrings/sagernet.asc
EOF

apt-get update
apt-get install -y sing-box
sing-box version

尽量让三台机器使用相同 sing-box 主版本。正式升级时先更新一台备用节点,测试正常后再更新其他节点。

复制配置完成重复部署

使用 MobaXterm 保存会话,并通过当前 SSH 连接自带的左侧 SFTP 面板完成配置复制;Windows 不需要预装 scp 或 OpenSSH:

  1. 下载可用配置: 打开第一台节点的 MobaXterm 会话,在左侧 SFTP 面板进入 /root,选中 sing-box-golden.json 并下载到电脑。
  2. 建立三个服务器会话: 分别为香港、日本和美国 VPS 创建 MobaXterm SSH 会话,填写各自地址、端口、用户名和密码。
  3. 逐台上传配置: 打开目标服务器会话,在左侧 SFTP 面板进入 /tmp,上传可用配置并将文件名确认为 config.json
  4. 执行部署命令: 在当前目标服务器的 MobaXterm 终端粘贴下面的命令,检查成功后再处理下一台服务器:
install -d -m 755 /etc/sing-box
install -m 600 /tmp/config.json /etc/sing-box/config.json
rm -f /tmp/config.json

sing-box check -c /etc/sing-box/config.json
sha256sum /etc/sing-box/config.json

systemctl enable --now sing-box
systemctl restart sing-box
systemctl status sing-box --no-pager
ss -lntp | grep ':443'

三台机器的 SHA-256 应与可用配置一致。如果使用的不是 443,请替换为实际端口;UFW 保持 inactive,并在各家 VPS 控制台的云防火墙中允许相同 TCP 端口。

为什么新手应逐台部署

MobaXterm 可以保存多个服务器会话,已经足够减少重复输入。第一次扩容不要使用本地 Shell 循环同时操作多台服务器:逐台上传、检查、启动并测试,能够准确知道哪一台在哪一步失败,也能避免错误配置一次扩散到所有节点。

客户端只修改 IP 和名称

从上一篇文章的生成器复制 VLESS URI,然后制作三份。所有查询参数保持不变,只替换 @ 后、端口前的服务器 IP,以及 # 后的名称:

vless://同一个UUID@香港IP:443?...相同参数...#HK-RFC-HKCO
vless://同一个UUID@日本IP:443?...相同参数...#JP-RFC-JP2CO
vless://同一个UUID@美国IP:443?...相同参数...#US-VMISS-LATRI

IPv6 地址必须放在方括号内:

vless://同一个UUID@[2001:db8::10]:443?...相同参数...#JP-Reality

不要重新输入 UUID、公钥和 Short ID。复制第一条已通过测试的 URI,只替换 IP 和名称最不容易出错。

同一份可用配置复制到多台 VPS 并输出多客户端订阅的流程

部署 Sub-Store

Sub-Store 可以保存本地节点、组合多个订阅,并输出 sing-box、Mihomo、Surge、Loon、Egern、Shadowrocket、Quantumult X 等格式。

建议部署在一台稳定的管理服务器上。下面使用官方 Wiki 指向的 Docker 镜像,只监听 127.0.0.1,通过 SSH 隧道访问,避免节点凭据和管理面板直接暴露公网。

准备目录和随机后端路径

确认 Docker 与 Compose 已安装:

docker version
docker compose version

创建持久化目录及随机路径:

install -d -m 700 /opt/sub-store
cd /opt/sub-store

printf 'SUB_STORE_PATH=/%s\n' "$(openssl rand -hex 16)" > .env
chmod 600 .env
cat .env

保存输出的 SUB_STORE_PATH,不要把它发布到公开页面或代码仓库。

编写 Docker Compose

使用 cat 一次创建 /opt/sub-store/compose.yaml

cat > /opt/sub-store/compose.yaml <<'EOF'
services:
  sub-store:
    image: xream/sub-store:latest
    container_name: sub-store
    restart: unless-stopped
    environment:
      SUB_STORE_FRONTEND_BACKEND_PATH: ${SUB_STORE_PATH}
      SUB_STORE_CORS_ALLOWED_ORIGINS: http://127.0.0.1:3001
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - ./data:/opt/app/data
EOF

启动并检查:

cd /opt/sub-store
docker compose up -d
docker compose ps
docker compose logs --tail 100 sub-store

健康检查:

SUB_STORE_PATH="$(cut -d= -f2- /opt/sub-store/.env)"
curl "http://127.0.0.1:3001${SUB_STORE_PATH}/api/utils/env"

返回版本信息表示服务正常。数据保存在 /opt/sub-store/data,重建容器不会丢失。

使用 MobaXterm SSH 隧道打开管理面板

使用 MobaXterm 的图形化隧道功能建立本地端口转发:

  1. 打开隧道工具: 点击顶部 Tunneling,选择 New SSH tunnel
  2. 选择转发类型: 选择 Local port forwarding,表示把电脑上的一个端口安全转发到服务器内部。
  3. 填写目标服务: Forwarded port 填 3001,Remote server 填 127.0.0.1,Remote port 填 3001
  4. 填写登录服务器: SSH server 填 Sub-Store 服务器 IP,SSH login 填 root 或实际用户名,SSH port 填该服务器的 SSH 端口。
  5. 保存并启动: 保存隧道后点击启动按钮,保持 MobaXterm 与该隧道运行。

然后访问 http://127.0.0.1:3001。如果前端没有自动找到后端,先在服务器的 MobaXterm 会话中读取随机路径:

cat /opt/sub-store/.env

假设输出:

SUB_STORE_PATH=/0123456789abcdef0123456789abcdef

则在本地浏览器访问:

http://127.0.0.1:3001?api=http://127.0.0.1:3001/0123456789abcdef0123456789abcdef

确认后端在线。不要把端口改成 0.0.0.0:3001 后直接暴露公网;后端保存了完整节点链接,泄露后相当于泄露全部节点凭据。

在 Sub-Store 添加三个节点

新建本地订阅

进入“订阅”,新建本地订阅:

  • 名称:uufly-private
  • 显示名称:私人多节点
  • 来源:本地节点

把三条真实 VLESS URI 每行一条粘贴到本地节点内容:

vless://UUID@香港IP:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=download-installer.cdn.mozilla.net&fp=chrome&pbk=公钥&sid=ShortID&type=tcp#HK-RFC-HKCO
vless://UUID@日本IP:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=download-installer.cdn.mozilla.net&fp=chrome&pbk=公钥&sid=ShortID&type=tcp#JP-RFC-JP2CO
vless://UUID@美国IP:443?encryption=none&flow=xtls-rprx-vision&security=reality&sni=download-installer.cdn.mozilla.net&fp=chrome&pbk=公钥&sid=ShortID&type=tcp#US-VMISS-LATRI

替换 UUID、公钥、Short ID、IP 和端口。保存后预览,确认:

  • 协议为 VLESS。
  • 安全类型为 Reality。
  • 流控为 xtls-rprx-vision
  • 三个地址不同。
  • 名称能区分地区和服务商。

使用组合订阅

以后加入家庭出口或其他订阅时,新建“组合订阅”,把 uufly-private 与其他订阅组合。这样可以统一排序、过滤和重命名,而不必反复复制节点。

推荐命名格式为“地区-服务商-线路”:

HK-RFC-HKCO
JP-RFC-JP2CO
US-VMISS-LATRI

为不同客户端生成订阅

在订阅或组合订阅页面选择“订阅链接”。通用链接可根据客户端 User-Agent 自动选择格式,也可以明确指定:

客户端建议输出
Clash Mi、Clash Verge Rev、Mihomo PartyMihomo / Clash Meta
sing-box、SFA、SFMsing-box
ShadowrocketShadowrocket
LoonLoon
EgernEgern
Quantumult XQX
SurgeSurge

在客户端中添加 Sub-Store 输出的订阅链接并更新,然后逐个测试三个地区。

本文的 Sub-Store 只在本地 SSH 隧道下可访问,适合电脑端管理和导出。手机需要自动更新时,可选择:

  • 连接家庭 VPN 后访问局域网 Sub-Store。
  • 使用带认证的 HTTPS 反向代理并限制访问来源。
  • 将生成结果同步到自己的私有存储,再提供只读链接。
  • 在电脑端导出对应格式,安全传送到自己的设备。

不要为了方便更新而公开裸面板和随机后端路径。

更新、备份和扩容

更新与备份 Sub-Store

更新前先备份:

tar -C /opt/sub-store \
  -czf "/root/sub-store-$(date +%F).tar.gz" \
  data .env compose.yaml

cd /opt/sub-store
docker compose pull
docker compose up -d
docker compose logs --tail 100 sub-store

备份包含完整节点凭据,应按私钥文件处理。

更新 sing-box

先更新一台非主力节点:

apt update
apt install --only-upgrade sing-box
sing-box check -c /etc/sing-box/config.json
systemctl restart sing-box

客户端测试正常后再更新其他机器,不要同时重启全部节点。

增加或替换节点

  1. 安装相同版本: 先在新 VPS 安装 sing-box,避免版本差异造成配置字段不兼容。
  2. 复制可用配置: 写入同一份文件并运行 sing-box check,确认内容没有损坏。
  3. 启动并验证端口: 保持 UFW 关闭,在云防火墙允许统一端口,然后确认服务正在监听。
  4. 生成新节点链接: 复制现有 VLESS URI,只替换服务器 IP 和名称,其他参数保持不变。
  5. 更新 Sub-Store: 添加新 URI 或替换旧地址,让订阅成为唯一维护入口。
  6. 刷新所有客户端: 确认新节点出现并测试成功后,再下线被替换的服务器。

迁移服务器时密钥参数无需变化,只需在 Sub-Store 更新对应 IP。

故障隔离与密钥轮换

只有一个地区无法连接

在对应服务器检查:

systemctl status sing-box --no-pager
journalctl -u sing-box -n 100 --no-pager
ss -lntp | grep ':443'
sha256sum /etc/sing-box/config.json

服务正常时继续检查云防火墙、本地运营商路由和 VPS IP 状态。其他地区可用,说明统一配置大概率没有问题。

全部节点同时无法连接

优先检查订阅是否被错误修改,以及 UUID、公钥、Short ID、SNI 是否一致。三个不同地区同时发生线路故障的概率通常低于订阅参数错误。

任意一台服务器疑似泄露

所有节点共用凭据,应立即:

  1. 生成新凭据: 在第一篇搭建教程的生成器中刷新全部参数,让泄露的旧参数失效。
  2. 更新可用配置: 保存新的服务端配置,作为接下来所有节点的唯一来源。
  3. 逐台替换服务端: 每更新一台就检查并重启,避免所有节点同时不可用。
  4. 更新 Sub-Store: 替换三条 URI,让客户端订阅拿到新公钥、UUID 和 Short ID。
  5. 刷新可信设备: 逐台确认新订阅能够连接,再继续处理下一台设备。
  6. 处理可疑服务器: 销毁或重装原实例,避免残留配置继续被使用。

密钥轮换会让旧订阅立即失效。建议先更新服务器,再更新 Sub-Store,最后让客户端刷新,并在过程中保留一个临时备用连接。