文章重点解析 EasyTier 自建方案中的架构角色划分:Caddy 作为反向代理提供安全访问入口,easytier-web-embed 是管理平面,负责 Web UI、API 和机器配置下发;easytier-core 是数据平面,处理 TUN、P2P、NAT 穿透和路由。作者强调 Web 用户与 EasyTier 网络不是同一概念,并解释了 Core 为何使用 host 网络模式而 Web 使用 Bridge 网络,以及如何通过端口映射让 Core 用 localhost 访问 Config Server。理解这些关系是部署成功的关键。
EasyTier 是一个开源、去中心化的异地组网工具,可以将家庭 NAS、云服务器、办公电脑等位于不同网络环境中的设备组成一个虚拟局域网。
它支持 NAT 穿透、P2P 直连、中继转发、子网代理和多种传输协议,不要求所有设备拥有公网 IP,也不依赖中心服务器承载实际业务流量。
本文采用一套完整的自建方案:
Internet
│
│ HTTPS :443
▼
┌───────────┐
│ Caddy │
└─────┬─────┘
│
Docker Network
│
▼
┌─────────────────────┐
│ easytier-web-embed │
│ Web / API :11211 │
│ Config :22020/UDP │
└──────────┬──────────┘
│
│ Config Server
▼
┌─────────────────────┐
│ easytier-core │
│ network_mode: host │
│ /dev/net/tun │
└──────────┬──────────┘
│
▼
EasyTier Network
三个组件的职责分别是:
组件 | 作用 |
|---|---|
| 负责虚拟网络、P2P、NAT 穿透、路由和实际数据传输 |
| 提供 Web 控制台、API 和 Core 配置下发 |
Caddy | 提供 HTTPS、域名和 Web 访问控制 |
可以将 EasyTier Web 理解为管理平面,而 easytier-core 才是真正的数据平面。
一、EasyTier 如何组网
假设有三台机器:
云服务器
家庭 NAS
办公电脑
加入同一个 EasyTier 网络后,可以获得类似:
EasyTier Network
10.10.10.1 Gateway
│
┌───────┴───────┐
│ │
10.10.10.2 10.10.10.3
NAS PC
之后可以像访问普通局域网设备一样:
ping 10.10.10.2
ssh 10.10.10.1
EasyTier 会优先尝试建立 P2P:
Node A <──────────────> Node B
P2P
如果由于 NAT、防火墙或运营商网络限制无法建立直连,则可以通过其他 EasyTier 节点进行中继:
Node A
│
▼
Relay
│
▼
Node B
因此,一个用于帮助节点发现彼此的 Gateway 或 Peer,并不意味着后续全部业务流量都必须经过它。
实际网络建立后可能变成:
Gateway
/ \
Node A Node B
\ /
\_____/
P2P
这也是 EasyTier 与传统中心化 VPN 在使用方式上的主要区别之一。
二、完整部署:Caddy + EasyTier Web + EasyTier Core
本文使用 Docker Compose 部署 EasyTier Web 和 Core,Caddy 独立运行,并通过一个公共 Docker Network 与 Web 控制台通信。
目录可以组织为:
easytier/
├── docker-compose.yml
├── web/
│ ├── app/
│ └── machine-id
└── core/
├── app/
└── machine-id
caddy/
├── docker-compose.yml
├── Caddyfile
├── data/
└── config/
首先创建公共网络:
docker network create caddy-network
2.1 部署 Caddy
docker-compose.yml:
services:
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./data:/data
- ./config:/config
networks:
- caddy-network
networks:
caddy-network:
external: true
Caddy 将作为 EasyTier Web 的 HTTPS 入口,也可以同时代理服务器上的其他服务。
2.2 部署 EasyTier Web 和 Core
EasyTier 使用一个 Compose 同时运行 Web 和 Core:
services:
easytier-web:
image: easytier/easytier:latest
container_name: easytier-web-embed
hostname: easytier-web
restart: unless-stopped
ports:
- "22020:22020/udp"
environment:
- TZ=Asia/Shanghai
volumes:
- ./web/app:/app
- ./web/machine-id:/etc/machine-id:ro
entrypoint: easytier-web-embed
command: >
--api-host https://yourdomain.com/
networks:
- caddy-network
easytier-core:
image: easytier/easytier:latest
hostname: easytier-core
restart: unless-stopped
network_mode: host
privileged: true
cap_add:
- NET_ADMIN
- NET_RAW
environment:
- TZ=Asia/Shanghai
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ./core/app:/app
- ./core/machine-id:/etc/machine-id:ro
command: >
--config-server udp://127.0.0.1:22020/srvkey
--hostname gateway-aliyun
networks:
caddy-network:
external: true
启动:
docker compose up -d
查看运行状态:
docker compose ps
整个容器网络关系为:
Docker Host
caddy-network
┌──────────────────────────────┐
│ │
│ Caddy ───── EasyTier Web │
│ :443 :11211 │
│ │ │
└──────────────────┼───────────┘
│ :22020
▼
Host Network
│
EasyTier Core
│
TUN
│
▼
EasyTier Network
2.3 配置 Caddy
Caddyfile:
https://yourdomain.com {
handle /api/v1/auth/captcha {
respond 404
}
handle /api/v1/auth/register {
respond 404
}
handle {
reverse_proxy http://easytier-web:11211
}
}
正常的 Web 请求路径为:
Browser
│
│ HTTPS
▼
Caddy
│
│ Docker Network
▼
easytier-web:11211
因此 Compose 中不需要将:
11211
映射到宿主机。
公网只访问:
443
而 Caddy 通过 caddy-network 直接访问 EasyTier Web。
Docker 会为同一网络中的容器提供 DNS,因此:
easytier-web
可以直接作为反向代理目标。
三、理解这套配置
部署完成后,有几个地方值得单独说明,因为它们决定了整个架构为什么能够工作。
3.1 Web 和 Core 为什么使用不同网络模式
EasyTier Web 本质上是普通 Web/API 服务,因此运行在 Docker Bridge Network 即可:
Caddy
│
Docker Bridge
│
EasyTier Web
Core 则需要处理:
TUN 虚拟网卡;
系统路由;
NAT;
TCP / UDP Listener;
NAT Traversal;
P2P;
Relay。
因此使用:
network_mode: host
让 Core 直接进入宿主机网络栈:
EasyTier Core
│
▼
Host Network
│
├── eth0
├── lo
├── routes
└── TUN
这样可以避免额外经过一层 Docker Bridge。
3.2 Core 为什么连接 127.0.0.1:22020
Core 的配置:
--config-server udp://127.0.0.1:22020/srvkey
第一次看到时可能会产生疑问,因为 Web 和 Core 并不是同一个容器。
关键在于 Core 使用:
network_mode: host
所以 Core 容器中的:
127.0.0.1
实际上就是宿主机。
Web 则通过:
ports:
- "22020:22020/udp"
把 Config Server 映射到了宿主机。
完整路径为:
EasyTier Core
│
│ udp://127.0.0.1:22020
▼
Host :22020/UDP
│
▼
Docker Port Mapping
│
▼
EasyTier Web Config Server
因此 Web 可以继续运行在 Bridge Network,而 Core 仍然可以通过 localhost 访问它。
3.3 Web 用户与 EasyTier 网络不是一个概念
例如:
--config-server udp://127.0.0.1:22020/srvkey
最后的:
srvkey
代表 Web Console 中管理该机器的用户。
而真正决定 Core 加入哪个 EasyTier 网络的是:
network-name
network-secret
两者关系可以理解为:
Web Account
│
▼
Machine
│
▼
EasyTier Core
│
▼
EasyTier Network
│
├── network-name
└── network-secret
Web Console 管理的是“机器和配置”,EasyTier Network 描述的则是“这些机器如何组成虚拟网络”。
3.4 --api-host
Web 使用:
--api-host https://yourdomain.com/
因为浏览器实际访问的是:
https://yourdomain.com
而不是 Docker 内部地址:
http://easytier-web:11211
注册、验证码以及部分前端 API 请求都会使用这个地址。
反向代理场景下,应让 api-host 与用户实际访问 Web Console 的外部地址对应。
3.5 TUN、Capabilities 与 machine-id
Core 映射:
devices:
- /dev/net/tun:/dev/net/tun
用于访问 Linux TUN 设备。
可以在宿主机检查:
ls -l /dev/net/tun
如果没有加载:
sudo modprobe tun
同时提供:
cap_add:
- NET_ADMIN
- NET_RAW
用于网络接口、路由和底层网络操作。
部分环境还可能使用:
privileged: true
如果运行环境仅依靠:
NET_ADMIN
NET_RAW
/dev/net/tun
即可正常工作,也可以减少额外权限。
另外:
./core/machine-id:/etc/machine-id:ro
用于保持机器身份稳定。
如果容器重建后 machine-id 发生变化:
Old Container → Machine A
Recreate
New Container → Machine B
Web Console 可能将其识别为新机器。
持久化后:
Old Container ─┐
├── Machine ID X
New Container ─┘
同一台机器应保持稳定的 machine-id,不同服务器则应使用不同值。
四、组网、Peer 与高级网络能力
Core 成功连接 Web Console 后,就可以通过 Web 页面配置实际的 EasyTier 网络。
4.1 network-name 与 network-secret
一个基本 EasyTier 网络需要:
network-name
network-secret
例如:
network-name:
home-network
network-secret:
<random-secret>
多个节点使用相同的:
network-name
+
network-secret
即可加入同一个逻辑网络。
密钥建议使用随机值:
openssl rand -base64 32
不要使用:
123456
password
easytier
home
之类的简单字符串。
4.2 Peer 与 P2P
节点需要先找到网络中的其他 EasyTier 节点。
例如:
Node A
│
│ Peer
▼
Gateway
可以配置:
tcp://gateway.example.com:11010
作为初始 Peer。
但 Peer 的作用主要是帮助建立网络连接,并不意味着所有流量永久经过它。
网络形成后:
Node A ─── Gateway ─── Node B
如果 NAT 条件允许,EasyTier 会继续尝试:
Node A <────────────> Node B
P2P
因此公网 Gateway 可以同时承担:
初始 Peer;
节点发现入口;
P2P 失败时的 Relay。
而成功直连的节点则不需要让正常数据流量经过 Gateway。
4.3 子网代理
EasyTier 不仅能连接安装了 Core 的机器,还可以通过一个 Core 访问它背后的整个局域网。
例如:
Remote PC
│
│ EasyTier
▼
Gateway
│
├── NAS 192.168.10.10
├── Server 192.168.10.20
└── Camera 192.168.10.30
Gateway 可以发布:
192.168.10.0/24
对应:
--proxy-networks 192.168.10.0/24
这样不需要在 NAS、摄像头等所有设备上安装 EasyTier。
如果两个地点恰好都使用:
192.168.1.0/24
还可以使用网段映射解决地址冲突,例如将远端:
192.168.1.0/24
映射为:
10.10.1.0/24
再通过映射后的地址访问。
五、安全与其他部署方式
5.1 Web 管理面安全
本文的 Web 入口为:
Internet
│
▼
Caddy
│
▼
EasyTier Web
Web 侧可以遵循几个基本原则:
只通过 HTTPS 访问;
不直接暴露
11211;使用高强度登录密码;
创建完成用户后关闭不需要的公开注册入口;
定期更新 EasyTier;
必要时增加 IP ACL、Cloudflare Access 或其他认证层。
本文 Caddy 中:
handle /api/v1/auth/captcha {
respond 404
}
handle /api/v1/auth/register {
respond 404
}
就是在完成账户创建后,直接从反向代理层关闭注册接口。
请求会在 Caddy 结束:
Register Request
│
▼
Caddy
│
X
HTTP 404
如果以后需要重新注册用户,需要同时恢复 CAPTCHA 与 Register 接口。
5.2 EasyTier 网络安全
Web 登录安全和 EasyTier 网络本身的安全是两个不同层次。
网络侧至少需要关注:
network-secret
Secure Mode
Private Mode
Relay
支持的版本中可以启用:
--secure-mode
进一步增强节点认证、端到端加密、防重放和会话密钥管理。
如果使用第三方或公共 Relay,还可以通过 Peer 公钥锁定验证所连接的 Relay 身份。
如果某个节点只用于自己的 EasyTier 网络,可以启用:
--private-mode true
限制其他网络使用该节点。
同时还可以使用 Relay 白名单限制允许转发的网络,避免公网节点承担非预期第三方流量。
5.3 不使用 Compose 时
虽然本文以 Compose 为主,但整体架构并不依赖 Docker Compose。
使用普通 Docker 时仍然是:
Docker Caddy
│
Docker EasyTier Web
│
Docker EasyTier Core
只需要分别通过 docker run 启动。
如果完全不用 Docker,也可以在 Linux 上运行:
Linux
├── Caddy
├── easytier-web-embed
└── easytier-core
此时连接关系变成:
Internet
│
▼
Caddy :443
│
▼
127.0.0.1:11211
│
▼
EasyTier Web
│
│ 127.0.0.1:22020
▼
EasyTier Core
Core 可以注册为 systemd 服务:
[Unit]
Description=EasyTier Core
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/easytier/easytier-core \
--config-server udp://127.0.0.1:22020/srvkey \
--hostname gateway
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Web 同样可以:
[Unit]
Description=EasyTier Web Console
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/easytier/easytier-web-embed \
--api-host https://yourdomain.com/
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Caddy 则继续使用相同的 Caddyfile,只需要把:
easytier-web:11211
改成:
127.0.0.1:11211
即可。
因此无论采用:
Docker Compose
Docker
systemd
整体逻辑始终没有变化:
Caddy
│
EasyTier Web
│
EasyTier Core
│
EasyTier Network
六、运维、常见问题与总结
常用命令
查看服务:
docker compose ps
查看 Core 日志:
docker compose logs -f easytier-core
查看 Web 日志:
docker compose logs -f easytier-web
查看 EasyTier 节点:
docker compose exec easytier-core easytier-cli node
查看 Peer:
docker compose exec easytier-core easytier-cli peer
检查 TUN:
ls -l /dev/net/tun
检查 Config Server:
ss -lunp | grep 22020
检查其他监听:
ss -lntup
Core 出现 TunError
先检查:
ls -l /dev/net/tun
如果没有:
sudo modprobe tun
然后确认 Compose 中存在:
devices:
- /dev/net/tun:/dev/net/tun
以及:
cap_add:
- NET_ADMIN
- NET_RAW
Web Console 看不到 Core
首先检查:
--config-server
例如:
udp://127.0.0.1:22020/srvkey
再查看:
docker compose logs easytier-web
以及:
ss -lunp | grep 22020
为什么不开放 11211?
因为 Web 的公网访问路径是:
Browser
│
HTTPS
▼
Caddy
│
Docker Network
▼
EasyTier Web :11211
11211 只需要在 Docker 内部网络中可达。
为什么 Core 使用 localhost 访问 Web?
因为 Core 使用:
network_mode: host
而 Web 的:
22020/UDP
映射到了宿主机。
所以:
127.0.0.1:22020
正好就是 Web Config Server 的宿主机入口。
Docker 重建后为什么出现新机器?
重点检查:
machine-id
Web Console 需要稳定的 machine-id 来识别同一台 Core。
容器可以重建,但:
machine-id
不能随之随机变化。
可以连接 EasyTier,但节点无法 P2P
先检查:
easytier-cli node
easytier-cli peer
如果 Relay 通信正常但始终没有 P2P,一般继续检查:
NAT 类型;
防火墙;
UDP 可达性;
IPv6;
公网端口;
运营商网络限制。
P2P 失败并不一定表示 EasyTier 网络异常,只可能意味着当前流量需要经过 Relay。
总结
本文部署最终形成三个层次:
┌───────────────────────────────┐
│ Caddy │
│ HTTPS / Web Access │
└──────────────┬────────────────┘
│
▼
┌───────────────────────────────┐
│ easytier-web-embed │
│ Management Plane │
└──────────────┬────────────────┘
│
▼
┌───────────────────────────────┐
│ easytier-core │
│ Data Plane │
└──────────────┬────────────────┘
│
▼
EasyTier Network
其中 Caddy 负责:
HTTPS
TLS
域名
访问控制
EasyTier Web 负责:
Web UI
API
机器管理
配置下发
EasyTier Core 负责:
TUN
P2P
NAT Traversal
Relay
Routing
Subnet Proxy
在此基础上,还可以根据网络规模进一步增加:
Secure Mode
Private Mode
Subnet Proxy
Relay Control
Peer Public-Key Pinning
最终形成一个既有集中管理入口,又保持 EasyTier 去中心化数据通信特性的私有异地网络。
DISCUSSION
评论
还没有公开评论,欢迎留下想法。