PVE + Tailscale 实现异地访问内网虚拟机

之前访问 PVE 里的虚拟机,需要先从外部机器 SSH 到一台中转机,再通过内网地址访问 PVE:

外部电脑
  |
ssh develop
  |
192.168.100.142
  |
PVE
  |
VM / LXC

这条链路能用,但每次都要多跳一次。如果只是为了访问 PVE 和它下面的虚拟机,更自然的方式是把 PVE 接入 Tailscale,并让它作为子网路由器,把内网网段发布出去。

目标拓扑

外部电脑 / 手机
  |
Tailscale
  |
PVE Subnet Router
  |
192.168.100.0/24
  |
PVE / VM / LXC / 内网服务

配置完成后,在外部设备开启 Tailscale,就可以直接访问 192.168.100.142 以及同网段里的虚拟机,不再需要先登录 develop

在 PVE 安装 Tailscale

先通过现在已有的链路登录 PVE:

ssh develop
ssh root@192.168.100.142

然后在 PVE 上安装并启动 Tailscale:

curl -fsSL https://tailscale.com/install.sh | sh
systemctl enable --now tailscaled
tailscale up

tailscale up 会输出一个登录链接,在浏览器里打开并授权这台 PVE。

开启 IP 转发

PVE 要把来自 Tailscale 的流量转发到内网,所以需要开启 IPv4 转发:

echo 'net.ipv4.ip_forward=1' >/etc/sysctl.d/99-tailscale.conf
sysctl -p /etc/sysctl.d/99-tailscale.conf

确认结果:

sysctl net.ipv4.ip_forward

应该看到:

net.ipv4.ip_forward = 1

发布内网网段

当前 PVE 地址是 192.168.100.142,所以要发布的内网网段通常是:

192.168.100.0/24

在 PVE 上执行:

tailscale up --advertise-routes=192.168.100.0/24

如果之前已经执行过 tailscale up,Tailscale 可能提示会重置参数。可以显式带上 --reset

tailscale up --reset --advertise-routes=192.168.100.0/24

在后台批准路由

登录 Tailscale Admin Console,找到这台 PVE 机器,在路由设置里批准 192.168.100.0/24。批准后,其他登录同一个 Tailscale 网络的设备就会知道这个网段可以通过 PVE 到达。

测试访问

在外部电脑上开启 Tailscale 后,直接测试 PVE:

ping 192.168.100.142
ssh root@192.168.100.142

如果虚拟机也是桥接到同一个内网,比如 192.168.100.50,也可以直接访问:

ssh root@192.168.100.50
curl http://192.168.100.50:8080

需要注意的点

最顺手的情况是 VM 使用桥接网络,例如接在 PVE 的 vmbr0 上,并且直接拿到 192.168.100.x 的内网地址。这样 Tailscale 子网路由只需要发布一个网段即可。

如果 VM 在 NAT 网络后面,外部设备可能不能直接访问 VM 的地址,需要额外处理 NAT、路由或端口转发。

另外,这里建议使用裸域名访问 WordPress API 类似的服务,是因为有些站点的 www 证书配置不一定覆盖完整;网络工具对证书会更严格。

总结

在 PVE 上安装 Tailscale 并开启 Subnet Router 后,PVE 就可以作为异地访问内网资源的入口。这样外部电脑和手机无需暴露公网端口,也无需先 SSH 到中转机,就能直接访问 PVE 以及同网段里的虚拟机。

发表评论