使用 ZeroTier 实现内网穿透
内网穿透是一种反向代理技术,允许你从任何位置访问一台处于复杂网络环境中的机器。它的应用场景有很多,例如,你在家中使用树莓派作为 Home Assistant 家庭中枢,但家庭网络的网关没有公网 IP,那么在离开家时就无法控制家中的智能设备。而在配置内网穿透后,就可以随时随地通过代理服务器的公网 IP 连接到树莓派,从而访问 Home Assistant 的服务。
内网穿透的原理是,利用一个具有固定公网 IP 的主机做跳板,让两个客户端建立 P2P 连接;如果不成功,就通过跳板主机中转,将所有流量代理到内网中的主机上。为不同需求所设计的内网穿透解决方案有很多,例如 frp 和 Cloudflare Tunnel。frp 允许你将内网中主机的端口映射到公网的主机上,因此使用起来非常直接。而 frp 的缺点是主机和端口都需要单独配置,如果要用多台设备组网,会有些繁琐;此外,这些端口都会直接暴露在公网上,安全性较差。另一个方案 Cloudflare Tunnel,可以直接用 Cloudflare 的节点进行中转,是非常不错的选择,但缺点和 frp 类似,在多台设备需要互相访问时很麻烦。
经过实验,如果需要将不同网络环境中的多台设备都配置内网穿透,并能够互相访问,那么使用 ZeroTier 搭建虚拟局域网是一个不错的选择。下面笔者将会介绍具体的配置方法。
准备
首先,打开 ZeroTier 官网,注册账号,然后根据使用的设备系统下载客户端并安装。ZeroTier 安装完成后,将会创建一个虚拟网卡。
在 ZeroTier 客户端中,输入 Network ID 并选择加入,你的设备就将分配到一个 ZeroTier 虚拟网络的 IP 地址。将需要内网穿透进行联网的设备都安装好 ZeroTier 客户端,并加入同一个 Network ID 的网络,就可以通过分配的 IP 地址互相访问了。就是这么简单!
自建 ZeroTier 节点
按照前面的步骤,我们使用的是由 ZeroTier 的数据中心提供的网络服务。这些服务器节点都在国外,在网络拥挤的情况下访问的速度并不是非常理想。如果有一台具备固定公网 IP 的主机,我们可以利用它来自建 ZeroTier 根服务器,官方称为 Moon 节点。以 Ubuntu 系统为例,首先和前面的步骤一样,安装 ZeroTier 并加入网络:1
2
3curl -s https://install.zerotier.com | sudo bash
sudo systemctl enable zerotier-one
sudo zerotier-cli join <network-id>
将此处的 <network-id>
替换为 16 个字符的虚拟局域网 ID。
随后,将当前主机配置为 Moon 节点。使用以下命令生成 moon.json
配置文件:1
2cd /var/lib/zerotier-one
zerotier-idtool initmoon identity.public > moon.json
moon.json
中包含一些关键的字段,包括:
id
,这是当前客户端的 ID,之后设置 Moon 节点时还会用到它,这个 ID 和zerotier-cli info
命令查看的一样;stableEndpoints
字段,值是一个字符串数组。
我们需要编辑 moon.json
,将 stableEndpoints
字段的值设置为你的服务器 IP 和 9993 端口,类似这样:1
"stableEndpoints": ["1.2.3.4/9993"]
然后,就可以生成 Moon 节点的证书了:1
2
3zerotier-idtool genmoon moon.json
mkdir moons.d
mv *.moon moons.d/
随后,在主机的防火墙设置中,放行 UDP 端口 9993,然后重启 ZeroTier 服务。1
sudo systemctl restart zerotier-one
这样,Moon 节点的配置就完成了。随后,在其它设备上,执行以下命令,启用 Moon 节点:1
2sudo zerotier-cli orbit <moon-id> <moon-id>
sudo zerotier-cli listpeers
将此处的 <moon-id>
替换为 10 个字符的 Moon 节点 ID 即可。
需要注意,Moon 节点的设置并不会在设备间同步,因此所有的节点上都需要执行上述命令。
将 OpenWrt 路由器加入 ZeroTier 网络
目前我们已经可以实现安装了 ZeroTier 客户端的设备之间互相访问。ZeroTier 实际上还支持路由设置,如果在 OpenWrt 路由器上安装 ZeroTier 客户端,并设置合适的转发规则,就可以直接将局域网网连接到 ZeroTier 的虚拟网络中。这样,就不仅可以访问 OpenWrt 路由器本身,也可以直接通过局域网 IP 访问任意设备了。
首先,打开 luci-app-zerotier 的下载页面,下载 ipk 格式的安装包。然后,将 ipk 上传到路由器上,执行以下命令安装:1
2opkg install zerotier
opkg install luci-app-zerotier_1.0-16_all.ipk --force-overwrite
第二个命令中指定的 --force-overwrite
用于覆盖默认的 ZeroTier 配置文件。
如果需要实现局域网和 ZeroTier 的虚拟网络互通,还需要进行防火墙设置。首先在「网络」 → 「防火墙」中,找到 lan → wan 的设置,并点击「编辑」。
在其中的高级设置中,将 Zerotier 对应的设备加入到 Covered devices 中,然后保存并应用设置即可。
参考文章:Private Root Servers - Creating Your Own Roots (a.k.a. Moons)