EasyTier + VPS + PVE 实现家庭局域网异地组网

  • 记于:2026-07-08 下午
  • 地点:浙江省·温州市·家里
  • 天气:晴天

背景#

最近想把家里的 PVE 和局域网打通,目标比较明确:

  • 家里有一台长期运行的 PVE 宿主机;
  • 家里网络是光猫 192.168.1.x,路由器下挂主局域网 192.168.31.x
  • 另外有一台带公网 IP 的云服务器;
  • 希望在外面的工作机上,既能访问 PVE 本机,也能访问家里的 192.168.31.0/24 网段。

最开始也看了 frp、WireGuard 等方案,最后还是选择了 EasyTier。主要原因是它更像一个“虚拟局域网”,除了节点互通,还能顺带做子网代理,把家里的整段 LAN 带出来。

整体拓扑#

这次实际采用的是三角色结构:

  • VPS:共享节点 / 中继节点
  • PVE:正式节点 + 子网代理节点
  • 工作机:普通接入节点

逻辑上是这样:

1
工作机 <----> VPS(公网入口) <----> PVE <----> 192.168.31.0/24

这里要注意,VPS 不是传统意义上的“中心 VPN 服务器”,而更像 EasyTier 网络里的公网入口点。能直连时节点会尽量直连,不能直连时再走中继。

地址规划#

为了避免和家里的 192.168.1.x192.168.31.x 混淆,我单独规划了一段 EasyTier 虚拟网:

  • EasyTier 虚拟网:10.100.100.0/24
  • PVE:10.100.100.1
  • 工作机:10.100.100.2

家里真实局域网仍然保持原样:

  • 家庭 LAN:192.168.31.0/24

PVE 通过子网代理,把 192.168.31.0/24 发布到 EasyTier 网络里。

VPS 配置#

VPS 使用 Docker Compose 运行。

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
services:
easytier:
image: easytier/easytier:latest
hostname: easytier
container_name: easytier
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
environment:
- TZ=Asia/Shanghai
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- /etc/machine-id:/etc/machine-id:ro
- ./conf:/config
command: >
-c /config/easytier.toml
--private-mode true

conf/easytier.toml

1
2
3
4
5
6
7
8
listeners = [
"tcp://0.0.0.0:11010",
"udp://0.0.0.0:11010",
]

[network_identity]
network_name = "ysm.easytier"
network_secret = "请替换成自己的强密码"

这里的重点有两个:

  • listeners
    表示 VPS 对外监听 11010/tcp11010/udp,作为其他节点的入网入口。
  • --private-mode true
    表示这台共享节点只服务自己的这个网络,不对其他 EasyTier 网络开放。

另外,云服务器的安全组和系统防火墙都需要放行:

  • 11010/tcp
  • 11010/udp

PVE 配置#

PVE 不承担公网入口职责,它只负责两件事:

  • 自己加入 EasyTier;
  • 把家里的 192.168.31.0/24 带进来。

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
services:
easytier:
image: easytier/easytier:latest
hostname: easytier
container_name: easytier
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
environment:
- TZ=Asia/Shanghai
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- /etc/machine-id:/etc/machine-id:ro
- ./conf:/config
command: >
-c /config/easytier.toml
--ipv4 10.100.100.1
--hostname pve.test
-p tcp://<VPS公网IP>:11010
-p udp://<VPS公网IP>:11010
-n 192.168.31.0/24
--no-listener

conf/easytier.toml

1
2
3
[network_identity]
network_name = "ysm.easytier"
network_secret = "请替换成与 VPS 相同的强密码"

这里几个参数需要重点理解:

  • --ipv4 10.100.100.1
    给 PVE 分配固定的 EasyTier 虚拟 IP。
  • -p tcp://... / -p udp://...
    告诉 PVE 先去找哪台公网节点入网。
  • -n 192.168.31.0/24
    这是子网代理,把家里的主 LAN 发布出去。
  • --no-listener
    表示 PVE 不在本机额外监听端口,只主动连出。

最后这个 --no-listener 很重要。因为我的 PVE 宿主机上本来就还有别的服务占用了默认端口,继续让 EasyTier 监听 11010 容易直接报 Address in use

工作机配置(GUI)#

工作机这边我用的是 EasyTier GUI,没有手写配置文件。

我的配置思路是:

  • 网络名:ysm.easytier
  • 网络密码:与 VPS、PVE 一致
  • 虚拟 IP:固定填 10.100.100.2
  • Peer:
    • tcp://<VPS公网IP>:11010
    • udp://<VPS公网IP>:11010

这里不建议工作机用 DHCP 方式,原因有两个:

  • 这套网络里我已经手工规划了 10.100.100.0/24
  • 工作机是常用节点,固定 IP 更方便记忆、排障和做书签。

如果工作机只是临时测试机器,用 DHCP 也不是不行,但要注意它不一定会落在我手工规划的 10.100.100.x 上。

验证方式#

节点都起来后,可以先在 VPS 和 PVE 上看状态:

1
2
3
docker exec easytier easytier-cli node
docker exec easytier easytier-cli peer
docker exec easytier easytier-cli route

正常情况下:

  • VPS 侧能看到 pve.test
  • 路由里能看到 10.100.100.1/24
  • 路由里还能看到 192.168.31.0/24

工作机连上后,理论上应该能:

1
2
ping 10.100.100.1
ping 192.168.31.x

其中:

  • 10.100.100.1 是 PVE 的 EasyTier 虚拟 IP;
  • 192.168.31.x 是通过 PVE 代理出来的家庭内网设备地址。

踩坑记录#

这次实际折腾时踩了几个坑,顺手记一下。

1. PVE 启动时报 Address in use#

最开始直接照着 VPS 的思路给 PVE 配了 listeners,结果启动时报错:

1
2
failed to listen on tcp://0.0.0.0:11010
Address in use

原因是 PVE 本机已经有别的服务占用了默认端口。
解决方式有两个:

  • 给 PVE 改监听端口;
  • 或者像我这样,直接使用 --no-listener

对“PVE 只是接入节点 + 子网代理”的场景,后者更简单。

2. 工作机同时连多个 EasyTier 网络时,11010 冲突#

我的工作机 GUI 里原本还连着另一个 EasyTier 网络,启动当前网络时报本地 11010 端口占用。

这里要区分清楚:

  • 106.12.x.x:11010
    这是远端 VPS 的端口;
  • 0.0.0.0:11010
    这是工作机本地监听端口。

同一台机器上多个 EasyTier 实例不能同时抢同一个本地监听端口。处理办法:

  • 给不同网络配置不同本地 listener 端口;
  • 或者对纯接入场景的实例关闭 listener。

3. Virtual IPv4: undefined#

工作机一开始用 GUI 的 DHCP 模式时,状态里一直显示:

1
Virtual IPv4: undefined

后来改成固定虚拟 IP 后恢复正常。
所以如果网络拓扑已经比较清晰,固定虚拟 IP 往往更省事。

4. 防火墙一定要放 TCP 和 UDP#

VPS 入口端口要同时开放:

  • 11010/tcp
  • 11010/udp

只开其中一个,节点可能会表现为不断重试、连接超时或者只能部分建链。

5. 15888 不是组网端口,而是本地管理端口#

这次还遇到一个容易误判的问题:

1
2
failed to connect to server: tcp://127.0.0.1:15888
Connection refused

一开始很容易把它理解成“15888 被占用了”,但其实不是。

15888 是 EasyTier 的本地管理 RPC 端口,不是节点之间真正组网和传输数据的端口。它主要给这些命令或界面使用:

  • easytier-cli node
  • easytier-cli peer
  • easytier-cli route
  • GUI 读取本机 EasyTier 实例状态

要和 11010 区分开:

  • 11010/tcp11010/udp
    这是 EasyTier 节点之间真正建链和通信的数据面端口;
  • 15888
    这是本机 easytier-cli 去查询 easytier-core 状态的管理面端口。

所以 Connection refused 的真实含义通常是:

  • 当前实例没有监听默认的 15888
  • 或者当前实例其实用了别的 RPC 端口;
  • 或者实例正在重启,cli 查询时端口还没就绪;
  • 或者因为 network_mode: host,同一台机器 / 同一网络命名空间里还有别的 EasyTier 实例,导致默认端口行为混乱。

这里还有一个容易忽略的点:

  • 不同机器之间,rpc-portal 可以相同;
  • 只有在同一台机器 / 同一网络命名空间里存在多个 EasyTier 实例时,才建议显式区分。

为了排障稳定,最好不要依赖默认 15888,而是显式指定。

例如:

  • VPS:--rpc-portal 15889
  • PVE:--rpc-portal 15890

查询状态时也显式指定同一个端口:

1
2
3
easytier-cli --rpc-portal 127.0.0.1:15890 node
easytier-cli --rpc-portal 127.0.0.1:15890 peer
easytier-cli --rpc-portal 127.0.0.1:15890 route

一句话总结:

  • 15888 是 EasyTier 本地管理端口,不是业务端口;
  • Connection refused 表示默认管理端口没人监听,不等于“被占用”;
  • 比较稳的做法是给实例显式配置 --rpc-portal,并在 easytier-cli 查询时指定同一个端口。

总结#

这套方案跑通后,效果还是很满意的:

  • VPS 负责公网入口;
  • PVE 负责把家庭内网带出来;
  • 工作机作为普通接入节点;
  • 最终既可以访问 10.100.100.1,也可以访问 192.168.31.0/24

如果只想远程访问家里单个服务,frp 一类工具会更轻。
但如果目标是“把家里局域网整体搬到外面”,EasyTier 确实更顺手。

参考资料#