前言

前两年如果说异地组网,那肯定非Tailscale和Zerotier莫属(其实现在也一直都是,因为它们比较偏向于企业化安全性优先),但是现在我不得不介绍一下EasyTier,它的穿透打洞能力,可以说是最强的。

直观对比:

项目 EasyTier Tailscale ZeroTier
双对称 NAT 直连率 60%+(可优化到90%+) <5%(基本中继) <10%(基本中继)
自建中继难度 一条命令 Headscale(较复杂) 自建根服务器(麻烦)
延迟(国内) 20-60ms 80-200ms(海外中继) 50-150ms
性能(Rust/Go) 零拷贝最强 优秀 一般
WebUI 细节 最强(路由路径全可见) 一般
价格 永久免费 免费有限制 免费有限制
去中心化程度 ★★★★★ ★★☆☆☆ ★★★☆☆

穿透打洞的成功率,与自身的网络环境密切相关,尤其是在双方都是对称NAT的纯IPv4网络下,可以说是难上加难,几乎不可能成功。

为什么我会非常推荐EasyTier?

因为公司的网络情况,一般公司不强制要求连接企业的VPN,但是公司一般往往也只提供IPv4,而且是对称NAT,就比如我的网络。想偷懒摸鱼想连接家里PS5打会儿游戏、或者连一下家里NAS、维护一下家里的服务器。

基于我自身的网络情况,测试下来的情况:

  1. 使用 Tailscale 和 Zerotier 只能 relay(中转),无法打洞成功;

  2. 改用 EasyTier,它的对等节点作为连接桥梁,即使一开始显示 relay,随后过几秒钟就可协商打洞成功。

借用官方的说明,即使我的网络属于下表中 最难双对称型NAT 的情况下,依然能够成功打洞。

建立 P2P 连接难度表

NAT 类型 开放型互联网 对称型防火墙 完全圆锥型 NAT 受限圆锥型 NAT 端口受限圆锥型 NAT 对称型递增 NAT 对称型 NAT
开放型互联网 容易 容易 容易 容易 容易 容易 容易
对称型防火墙 容易 简单 简单 简单 简单 简单 简单
完全圆锥型 NAT 容易 简单 简单 简单 简单 简单 简单
受限圆锥型 NAT 容易 简单 简单 中等 中等 中等 中等
端口受限圆锥型 NAT 容易 简单 简单 中等 中等 中等 中等
对称型递增 NAT 容易 简单 简单 中等 中等 困难 困难
对称型 NAT 容易 简单 简单 中等 中等 困难 极难

简介

EasyTier官网:EasyTier - 简单、安全、去中心化的异地组网方案

特点:

  1. NAT 穿透能力:双对称 NAT(NAT4-NAT4)下,EasyTier 是唯一能打的

  2. 去中心化 + 自建共享节点:零成本、零依赖、零海外延迟

  3. 性能拉满:Rust + 零拷贝 + 多协议,速度吊打

  4. WebUI + 监控细节拉满,新手老鸟都爱

  5. 完全免费、无设备限制、跨平台最全

  6. IPv6 + 双栈原生支持

前提

需要有一台有公网IP的设备。

因某些因素,原本官方提供的公共对等节点已暂停维护,目前只能自行搭建对等节点。

翻译过来就是:现在使用EasyTier,需要借助公网IP,也就是VPS这类有IPv4公网的设备,或者如果可以接受纯IPv6打洞的话,任意设备搭建IPv6的服务端也行。

IPv6本身就是公网IP,可以进行直连,它的应用稍显局限,但也有一些其他的应用,文章后面会说明。

步骤

1. 搭建对等节点

访问 Releases · EasyTier/EasyTier 下载对应的版本。一般VPS都是Linux系统,我就直接以命令行展示:

也可以通过Docker搭建,可自行查看官方文档: 安装 (命令行程序) | EasyTier - 简单、安全、去中心化的异地组网方案

使用以下命令在公网IP的服务器上即可搭建对等节点:

easytier-core \
  --network-name <网络名称> \
  --network-secret <网络密码> \
  --private-mode true \ # 私有模式(可选,但推荐)
  --ipv4 10.0.10.1 \ # 分配不同虚拟 IP
  -peers tcp://0.0.0.0:11010 \ # 监听公网TCP IP:11010 
  -peers udp://0.0.0.0:11010 \ # 监听公网UDP IP:11010,一般建议加UDP提升打洞成功率

2. 设备连接

在两台设备上使用EasyTier客户端连接该对等节点即可(图片为MacOS端端客户端):

由于两台设备无法直连,初始状态肯定是 relay ,等过一会儿,VPS会作为可靠的协调桥梁,帮助双方完成打洞。

初始状态

最终完成打洞:P2P直连

3. 开机启动服务

确定设备正常可以打洞成功后,只需根据上面的终端命令,再参考根据官方的文档注册为系统服务保持开机启动即可:

vim /etc/systemd/system/easytier.service

内容为:

[Unit]
Description=EasyTier Service
After=network.target syslog.target
Wants=network.target

[Service]
Type=simple
ExecStart=/etc/easytier-core --ipv4 10.0.10.1 --network-name <网络名称> --network-secret <网络密码> --private-mode true --peers tcp://0.0.0.0:11010 --peers udp://0.0.0.0:11010

[Install]
WantedBy=multi-user.target

开机启动:systemctl enable easytier.service

启动服务:systemctl start easytier.service

停止服务: systemctl stop easytier.service

其他:任一设备搭建IPv6的对等节点

前提是双方都有IPv6网络。

可以直接通过 IPv6 实现原生端到端直连,完全绕过 IPv4 NAT 的所有限制。

这个情况就简单多了,直接借助IPv6进行打洞即可,但是由于IPv6经常变动,因此其中一台设备强烈建议做DDNS动态域名解析,比如解析到: a.yourdomain.com 。(动态域名解析就不多赘述了)

然后在这台设备下载安装对应的版本:Releases · EasyTier/EasyTier

我还是以Linux设备的终端演示,使用以下命令即可搭建服务端:

easytier-core \
  --network-name <网络名称> \
  --network-secret <网络密码> \
  --private-mode true # 私有模式(可选,但推荐)
  --ipv4 10.0.10.1 \ # IPv4 虚拟地址(保持原样)
  --ipv6 fd12:3456:789a::1 \ # IPv6 虚拟地址(手动分配,推荐 fd开头的 ULA 或你的公网前缀)
  -peers tcp://0.0.0.0:11010 \ # 监听所有 IPv4 接口
  -peers udp://0.0.0.0:11010 \ # UDP 监听(打洞优先)
  -peers tcp://[::]:11010 \ # 监听所有 IPv6 接口(关键![::] 表示 IPv6 任意地址)
  -peers udp://[::]:11010 \ # IPv6 UDP 监听
  --mapped-listeners tcp://[你的公网IPv6]:11010 \ # 声明公网 IPv6 映射(如果服务器有公网 IPv6)
  --mapped-listeners udp://[你的公网IPv6]:11010 \

实际操作中,为了兼容性、稳定性,即使没有公网IPv4无法成功连接,还是建议添加 0.0.0.0:1101

另一台设备,使用EasyTier客户端连接该对等节点即可,对等节点就是做了DDNS动态域名解析的地址:tcp://a.yourdomain.com:11010 以及 udp://a.yourdomain.com:11010

应用

这样其实有点绕远路了,因为双方都支持IPv6了,本来做了域名解析就可以直接通过域名访问,没必要再P2P打洞。

我能想到的使用这种方法适用的情况只有访问家里整个局域网的设备的需求:

也就是 子网代理 :在家里的设备启动中添加参数: -n <局域网CIDR> ,比如家里局域网是 192.168.1.x,那么就增加 -n 192.168.1.0/24 的启动参数。这样另一台设备就可以访问家里整个局域网设备了。

这样做的好处就是安全,不需要将自己部署的各种应用直接暴露在网上,暴露的仅仅是一个IPv6的11010端口。

最后

这篇文章可能说的不是很清晰,因为在我原本的设想中,是可以使用官方的对等节点的,但是在我测试的时候,发现对等节点已经停止维护了,而且网上很多公开的共享对等节点,基本已经失效。

因此就只能介绍现在可行的两种方法,内容就显得简单无趣了些。

根据我目前的使用情况,EasyTier的打洞成功率确实非常高,再然后补充一下为什么我选择EasyTier的另一个原因:完美支持nftables,这也是由于OpenWRT新版本防火墙规则的底层是基于nftables,直接在OpenWRT上安装显得简单一些。

可以参考:GitHub - EasyTier/luci-app-easytier: OpenWrt里的EasyTier安装包(IPK和APK) · GitHub

拓展:通过Cloudflare搭建对等节点

最近查了点资料。发现 Easytier 原生支持 ws://wss://(WebSocket)协议,而 Cloudflare Workers 也能支持 WebSocket 的转发,于是搜索了一下,发现Github上面有几个项目可以通过Cloudflare的Workers搭建对等节点,这样可以省去了服务器。

项目

GitHub - NotTropical/easytier-ws-relay

GitHub - IceSoulHanxi/easytier-ws-relay

这两个项目可以说基本一样,任意选一个。

下面以 IceSoulHanxi/easytier-ws-relay 为例进行演示

步骤

1. Fork项目

2. 创建Workers

前提条件:在Cloudflare上面绑定好自己的域名(可以找免费的申请)

Cloudflare分配到 workers.dev 大陆无法访问,因此必须绑定自己的域名。

登陆Cloudflare,进入界面左侧栏目的【Compute】-【Workers 和 Pages】,点击【创建应用程序】:

接着选择【Continue with GitHub】,搜索并选择这个项目:

直接点击【部署】即可:

等待后台构建成功:

3. 配置

在项目的【设置】,点击【域和路由】右侧的【添加】,添加【自定义域】,添加一个自己绑定域名的子域名,我这边添加的为: easytier.luxiyue.cn

再简单介绍一下默认的环境变量:

  • EASYTIER_COMPRESS_RPC = 1 控制 RPC(远程过程调用)消息是否启用压缩。

    • 1 表示开启压缩,可以减少传输数据量,提高效率。

    • 0 表示关闭压缩,方便调试或避免某些兼容性问题。

  • EASYTIER_DISABLE_RELAY = 0 控制是否禁用中继功能。

    • 0 表示启用中继,客户端可以通过 relay 转发数据。

    • 1 表示禁用中继,只允许纯 P2P 模式(节点之间必须直连)。

  • LOCATION_HINT = apac 指定 Durable Object 的部署区域。

    • apac 表示亚太地区(Asia Pacific)。

    • 这个配置影响 relay 的地理位置,选择离客户端更近的区域可以降低延迟。

  • WS_PATH = ws 指定 WebSocket 的路径。

    • 默认是 /ws,客户端连接时需要在地址后加上这个路径。

    • 例如:wss://your-worker.workers.dev:0/ws

环境变量这边可以不用变,或者改一个 WS_PATH = ws 就行了,我现在得到的最终对等节点为: wss://easytier.luxiyue.cn:0/ws

easytier中端口号使用0为使用协议默认端口,ws对应80,wss对应443

这边其实可以直接使用: wss://easytier.luxiyue.cn:443/ws

连接测试

在两台设备,演示的一台电脑使用家里的网络,对称NAT4的痛。。。

另一台直接用手机蜂窝数据。

电脑端端设置以及手机端的设置:

点击连接后,因为家里的对称NAT网络,一下子没那么容易连,开始显示的 中继relay

几秒钟后就显示直连了,电脑端也显示P2P,打洞成功:

Cloudflare Workers 一天有 10万次 的请求数限制,但是只要打洞成功,直连后就不需要通过它中转。

可能的问题

  • WebSocket: 在Cloudflare域名-网络板块,打开WebSockets

  • EasyTier网络名称与密码:我一开始设置的网络名称是 luxiyue.cn ,不知道是不是因为有 . 导致无法连接,后来我改成了 luxiyue 后就正常了。(上文图片是一开始截的图,后来更正后就懒得重新截图了)

最后的最后

这样也算是给EasyTier画上一个完美的句号了。

通过Cloudflare Workers纯手动自行部署,数据都在自己手上,也不用担心走其他公共服务器导致隐私泄漏。