用 WireGuard 网状网络搭建私有 VPS 集群
用 WireGuard 全网状网络把多个 VPS 节点连成私有集群:统一的地址规划、每个节点一个 [Peer]、/32 AllowedIPs、严格的防火墙,以及绑定到 wg0 的服务。
简答:要把多台 VPS 组成私有集群,请为每个 VPS 节点配置一个 WireGuard 接口,地址取自同一个私有子网;把其他每个节点都添加为 `[Peer]`,填写其公网 `Endpoint`,并在 `AllowedIPs` 中写入一个 `/32`;只允许你自己的节点访问 UDP 51820;并把数据库和内部服务绑定到 `wg0` 地址而不是公网 IP。大约十个节点以内,手工或用模板维护都很容易;超过这个规模,就应使用能自动生成和分发配置的工具。
本指南假定你已经掌握 WireGuard VPN 指南中的基础知识,并已按照 SSH 加固指南加固了每个节点的 SSH;若要通过跳板机访问节点而不使用代理转发,请参阅 StrictModes 与代理转发指南。
VPN 节点的地址规划
选择一个不与你正在使用的其他任何网段(家庭局域网、Docker、Kubernetes Pod 网段)冲突的私有网段。对于小集群,一个 `/24` 就够了,地址也易于辨认。为每个节点分配固定地址,并把规划纳入版本控制,因为所有配置都由它推导而来。
| 节点 | 角色 | 公网 IP | wg0 地址 | ListenPort |
|---|---|---|---|---|
| node1 | 应用 | 203.0.113.11 | 10.88.0.1/24 | 51820 |
| node2 | 应用 | 203.0.113.12 | 10.88.0.2/24 | 51820 |
| node3 | 数据库 | 203.0.113.13 | 10.88.0.3/24 | 51820 |
| node4 | 监控 | 203.0.113.14 | 10.88.0.4/24 | 51820 |
每个 VPS 节点上的对端配置
在全网状网络中,每个节点都直接与其他所有节点通信,因此每份配置包含一个 `[Interface]` 和 N-1 个 `[Peer]` 段。四个节点共有六条隧道;十个节点则有 45 条。每个节点都有公网 IP,所以通常不需要 `PersistentKeepalive`;详情见 keepalive 与 PresharedKey 指南。
- 01.在每个节点上运行 `apt install wireguard`,然后运行 `umask 077; wg genkey | tee /etc/wireguard/wg0.key | wg pubkey > /etc/wireguard/wg0.pub`。
- 02.把所有公钥和地址规划汇总到一处。
- 03.可选:为每对节点生成一个 `wg genpsk` 密钥,作为抗量子防护。
- 04.按下文所示在每个节点上编写 `/etc/wireguard/wg0.conf`。
- 05.运行 `systemctl enable --now wg-quick@wg0`,并检查 `wg show`,确认与每个对端都有最近的握手。
# /etc/wireguard/wg0.conf on node1
[Interface]
Address = 10.88.0.1/24
ListenPort = 51820
PrivateKey = <node1 private key>
[Peer]
# node2
PublicKey = <node2 public key>
Endpoint = 203.0.113.12:51820
AllowedIPs = 10.88.0.2/32
[Peer]
# node3
PublicKey = <node3 public key>
Endpoint = 203.0.113.13:51820
AllowedIPs = 10.88.0.3/32
[Peer]
# node4
PublicKey = <node4 public key>
Endpoint = 203.0.113.14:51820
AllowedIPs = 10.88.0.4/32AllowedIPs 在网状网络中如何工作
`AllowedIPs` 同时承担两项工作。出站时,它是路由表:发往 `10.88.0.3` 的数据包会交给列出 `10.88.0.3/32` 的对端。入站时,它是访问控制列表:来自该对端的数据包,只有源地址位于该对端的 `AllowedIPs` 范围内才会被接受。这就是为什么每个对端只分配它自己的 `/32`,而不是整个 `/24`。
`Address` 行中的 `/24` 只是在 `wg0` 上为该子网创建内核路由;随后 WireGuard 会按目标地址选择正确的对端。
- ▹同一接口上的两个对端绝不能有重叠的 `AllowedIPs` 范围;后写的会覆盖前面的。
- ▹如果某个节点还路由一个私有子网(例如 node3 上的 Docker),请在其他节点上把该子网加到 node3 的 `AllowedIPs` 中。
- ▹除非你确实希望所有流量都从该节点出去,否则不要在网状网络的对端中写入 `0.0.0.0/0`。
防火墙:只有你的节点能访问隧道
WireGuard 不会响应未经认证的数据包,但把 UDP 51820 限制为已知节点 IP 仍能减少干扰。在隧道内部,只开放每项服务所需的端口。这个适用于 Debian 12/13 和 Ubuntu 24.04 的 nftables 示例放在 `/etc/nftables.conf` 中;用 `nft -f /etc/nftables.conf` 加载,并启用 `nftables.service`。测试期间请保持一个已打开的 SSH 会话。
table inet filter {
set mesh_peers {
type ipv4_addr
elements = { 203.0.113.11, 203.0.113.12, 203.0.113.13, 203.0.113.14 }
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
meta l4proto { icmp, ipv6-icmp } accept
tcp dport 22 accept
udp dport 51820 ip saddr @mesh_peers accept
iifname "wg0" ip saddr 10.88.0.0/24 tcp dport { 5432, 6379, 9100 } accept
}
}把服务绑定到 wg 接口
防火墙是一层防护;第二层是根本不在公网地址上监听。把内部服务绑定到节点的 `wg0` 地址,这样即使防火墙配置出错也不会暴露它们。由于 `wg0` 必须在服务绑定之前存在,请用 systemd drop-in 安排单元的启动顺序,或者用 `net.ipv4.ip_nonlocal_bind = 1` 允许绑定到尚未启用的地址。
# PostgreSQL on node3: postgresql.conf
listen_addresses = '10.88.0.3'
# pg_hba.conf
host all all 10.88.0.0/24 scram-sha-256
# Redis: /etc/redis/redis.conf
bind 10.88.0.3
# systemctl edit postgresql (repeat for other services)
[Unit]
[email protected]
[email protected]Note · 用 `ss -tlnp` 检查结果:内部服务应显示 `10.88.0.x`,绝不能是 `0.0.0.0` 或公网 IP。
扩展:何时改用自动化工具
在节点数量少、变更不频繁时,手写的网状网络完全够用。每新增一个节点都意味着要编辑所有现有配置,因此工作量呈平方级增长。一旦这变成负担,就应该生成配置而不是手写。
在 NoctisNode,所有新 VPS 节点都部署在 FI-1(芬兰),每个节点都有独立 IPv4 和不限流量的 1 Gbps 端口;按小时计费加上 agent API(支持自动销毁 TTL),让添加和移除测试节点的成本很低。套餐从 Wisp 起步;参见 VPS 套餐。
| 集群规模 | 方案 |
|---|---|
| 2–5 个节点 | 手写配置,地址规划存放在文本文件中 |
| 5–15 个节点 | 用 Ansible 或其他配置管理工具,从一份清单生成 wg0.conf 模板 |
| 15 个以上节点或频繁变动 | 使用自动分发密钥和对端的网状网络管理器,或采用星型(hub-and-spoke)架构 |
常见问题
Q如何把多台 VPS 连接成一个私有网络?
A在每台 VPS 上安装 WireGuard,为每个节点分配同一私有子网中的地址,并把其他每个节点列为对端,填写其公网端点和 /32 的 AllowedIPs。然后把内部服务绑定到 WireGuard 地址。
QWireGuard 网状网络中的 VPN 节点需要 PersistentKeepalive 吗?
A通常不需要,因为每个 VPS 节点都有公网 IP,可以被直接访问。只有位于 NAT 之后的节点才需要添加 `PersistentKeepalive = 25`。
Q每个 VPS 节点的 AllowedIPs 应该设为什么?
A每个对端只分配它自己的 WireGuard 地址(/32),以及该节点所路由的子网。为每个对端都使用整个集群子网会导致路由重叠,使网状网络失效。
QWireGuard 网状网络最多能有多少个节点?
AWireGuard 本身能处理大量对端,但手工维护的全网状网络在约十个节点后就会变得繁琐,因为每个节点都需要所有其他节点的配置。超过这个规模,请用自动化生成配置或使用网状网络管理器。