内网穿透实战:基于 EasyTier 自建 SD-WAN 与踩坑实录
背景与痛点
在极其复杂的校园网环境下,多层 NAT 嵌套和严格的防火墙策略是常态。之前一直依赖 Tailscale 进行内网穿透,但由于打洞成功率极低,且官方 DERP 中继节点经常遭遇高延迟甚至被阻断,导致内网设备处于失联状态。
为了彻底解决网络互通问题,决定利用一台带有公网 IP 的阿里云服务器,自建一个私有的中转节点(灯塔)。在对比了多款组网工具后,选择了基于 Rust 编写的 EasyTier。其极低的内存占用(实测中度负载仅 50MB 左右)非常适合资源紧张的云服务器,且支持子网路由代理,能够完美实现异地访问本地物理局域网。
以下是完整的部署架构、操作步骤以及在此过程中踩过的各种坑。
整体网络架构
为了实现全网互通,网络拓扑划分为三个核心层级:
- 公网中继节点(灯塔):部署在阿里云,分配虚拟 IP
10.144.144.1,负责握手与流量兜底转发。 - 移动客户端:Windows 笔记本(
10.144.144.3)和 Android 手机(10.144.144.2)。 - 内网子网网关:本地的 HP400-G4 主机(虚拟 IP
10.144.144.4),负责将虚拟局域网的流量转发至本地物理网段192.168.10.0/24。

阶段一:部署阿里云公网中继节点
公网节点不需要主动连接任何人,只需监听特定端口等待客户端接入。
1. 配置安全组
在阿里云控制台,必须在安全组中放行自定义的监听端口(例如 11080)。

⚠️ 关键点: 必须同时放行 TCP 和 UDP 协议。缺少 UDP 会导致后续 P2P 打洞彻底失效。
2. Docker 部署与踩坑
在云服务器上通过 Docker 拉取并运行 EasyTier。
❌ 踩坑记录 1:参数混淆导致容器无限重启
最初使用的启动命令包含-i my_net,导致容器启动后立即报错闪退,日志显示:failed to parse ipv4 address: my_net原因:在 EasyTier 的 CLI 中,
-i实际上是--ipv4的简写,用于指定虚拟 IP 地址,而不是用来指定网络名称。
正确的部署命令:
首先删除错误的容器 docker rm -f easytier,然后使用正确的完整参数:
docker run -d \
--name easytier \
--restart always \
--cap-add NET_ADMIN \
--device /dev/net/tun \
-p 11080:11080/tcp \
-p 11080:11080/udp \
easytier/easytier:latest \
--ipv4 10.144.144.1 \
--network-name "my_net" \
--network-secret "your_password" \
--listeners tcp://0.0.0.0:11080 \
--listeners udp://0.0.0.0:11080
部署后,通过 docker ps 确认状态为 Up,且日志输出 tun device ready dev="tun0",说明中转节点搭建成功。
阶段二:客户端接入
客户端接入相对简单。
- Windows 端:直接下载
easytier-gui_x64-setup.exe图形化界面安装包,填入虚拟 IP、网络名称、密码,并在「公共节点」处填入tcp://<阿里云公网IP>:11080即可连接。 - Android 端:面对繁杂的安装包列表,主流 64 位安卓手机(如一加、红米等)直接选择
app-arm64-release.apk即可安装,不带 64 的 arm 版本是给早期 32 位设备准备的。
阶段三:部署内网网关(子网路由代理)
这一步的目的是让外网设备能够直接访问内网网段 192.168.10.x 中的所有物理设备(如 OpenWrt 路由器、NAS 等)。
1. 开启宿主机 IP 转发
内网的 HP 主机必须开启 IPv4 转发能力,否则无法充当路由器。
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
2. Docker 部署与踩坑
在内网 Linux 宿主机上部署时,遇到了几个经典的命令规范和版本迭代坑。
❌ 踩坑记录 2:换行符与空格导致的格式错误
在终端粘贴带有\换行符的命令时,如果\后面多带了空格,会导致终端解析器崩溃,报出docker: invalid reference format。解决办法是将命令写成纯粹的一整行。
❌ 踩坑记录 3:废弃参数导致启动失败
在尝试代理内网网段时,使用了--routes 192.168.10.0/24参数,容器报错:error: unexpected argument '--routes' found原因:在新版 EasyTier 中,子网代理的参数已经更改。
正确的部署命令:
必须使用 --net=host 网络模式以及 --privileged 特权模式,并将子网代理参数更正为 --proxy-networks。
sudo docker run -d --privileged --name easytier-node --net=host -v /dev/net/tun:/dev/net/tun easytier/easytier:latest --ipv4 10.144.144.4 --network-name my_net --network-secret your_password -e tcp://<阿里云公网IP>:11080 --proxy-networks 192.168.10.0/24
阶段四:网络调优与 P2P 穿透修复
组网完成后,通过查看节点连接状态,发现了一个典型的网络底层现象:
- 局域网内的 Windows 电脑与 HP 主机之间建立了 3ms 延迟的 P2P TCP 直连。
- 外网手机(使用 5G 流量)与内网 Windows 电脑成功建立了 89ms 的 P2P UDP 直连。
问题:手机与内网 HP 主机无法直连,只能通过阿里云中转,状态显示为 relay,所在网络环境被识别为严格的 Symmetric(对称型 NAT)。
原因分析:
手机使用移动网络时,运营商分配的是极其保守的 Symmetric NAT。虽然手机和 Windows 电脑能够 P2P,是因为 Windows 配合路由器底层的 UPnP 成功映射了临时端口。但在 Linux 宿主机中通过 Docker(哪怕是 host 模式)运行的程序,往往无法主动触发物理路由器的 UPnP,导致来自手机的 UDP 打洞探测包被静默丢弃。
终极解决方案:手动端口转发
登录物理主路由(OpenWrt/iStoreOS)的管理后台,进入端口转发(NAT)设置,强制凿开一条通道:
| 配置项 | 值 |
|---|---|
| 外部端口 | 11010(EasyTier 默认监听端口,不要与阿里云的 11080 混淆) |
| 内部 IP | 192.168.10.100(HP 宿主机的物理 IP) |
| 内部端口 | 11010 |
| 协议 | TCP + UDP |

配置生效后,手机重新连接流量。查看状态日志,手机与内网 HP 主机终于成功握手,状态由 relay 转变为 p2p,彻底打通了复杂 NAT 下的高速直连通道。至此,整个 SD-WAN 网络满血运行。
