- 记于: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.x、192.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 | services: |
conf/easytier.toml
1 | listeners = [ |
这里的重点有两个:
listeners
表示 VPS 对外监听11010/tcp和11010/udp,作为其他节点的入网入口。--private-mode true
表示这台共享节点只服务自己的这个网络,不对其他 EasyTier 网络开放。
另外,云服务器的安全组和系统防火墙都需要放行:
11010/tcp11010/udp
PVE 配置#
PVE 不承担公网入口职责,它只负责两件事:
- 自己加入 EasyTier;
- 把家里的
192.168.31.0/24带进来。
docker-compose.yml
1 | services: |
conf/easytier.toml
1 | [network_identity] |
这里几个参数需要重点理解:
--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>:11010udp://<VPS公网IP>:11010
这里不建议工作机用 DHCP 方式,原因有两个:
- 这套网络里我已经手工规划了
10.100.100.0/24; - 工作机是常用节点,固定 IP 更方便记忆、排障和做书签。
如果工作机只是临时测试机器,用 DHCP 也不是不行,但要注意它不一定会落在我手工规划的 10.100.100.x 上。
验证方式#
节点都起来后,可以先在 VPS 和 PVE 上看状态:
1 | docker exec easytier easytier-cli node |
正常情况下:
- VPS 侧能看到
pve.test - 路由里能看到
10.100.100.1/24 - 路由里还能看到
192.168.31.0/24
工作机连上后,理论上应该能:
1 | ping 10.100.100.1 |
其中:
10.100.100.1是 PVE 的 EasyTier 虚拟 IP;192.168.31.x是通过 PVE 代理出来的家庭内网设备地址。
踩坑记录#
这次实际折腾时踩了几个坑,顺手记一下。
1. PVE 启动时报 Address in use#
最开始直接照着 VPS 的思路给 PVE 配了 listeners,结果启动时报错:
1 | failed to listen on tcp://0.0.0.0:11010 |
原因是 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/tcp11010/udp
只开其中一个,节点可能会表现为不断重试、连接超时或者只能部分建链。
5. 15888 不是组网端口,而是本地管理端口#
这次还遇到一个容易误判的问题:
1 | failed to connect to server: tcp://127.0.0.1:15888 |
一开始很容易把它理解成“15888 被占用了”,但其实不是。
15888 是 EasyTier 的本地管理 RPC 端口,不是节点之间真正组网和传输数据的端口。它主要给这些命令或界面使用:
easytier-cli nodeeasytier-cli peereasytier-cli route- GUI 读取本机 EasyTier 实例状态
要和 11010 区分开:
11010/tcp、11010/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 | easytier-cli --rpc-portal 127.0.0.1:15890 node |
一句话总结:
15888是 EasyTier 本地管理端口,不是业务端口;Connection refused表示默认管理端口没人监听,不等于“被占用”;- 比较稳的做法是给实例显式配置
--rpc-portal,并在easytier-cli查询时指定同一个端口。
总结#
这套方案跑通后,效果还是很满意的:
- VPS 负责公网入口;
- PVE 负责把家庭内网带出来;
- 工作机作为普通接入节点;
- 最终既可以访问
10.100.100.1,也可以访问192.168.31.0/24。
如果只想远程访问家里单个服务,frp 一类工具会更轻。
但如果目标是“把家里局域网整体搬到外面”,EasyTier 确实更顺手。