使用zerotier创建虚拟局域网

手上目前有几台设备且分布在不同的地方,设备多了,难免有互相访问的情况,比如人在外面需要远程连接回家里操控一下或者取个文件啥的,但是因为实际网络情况,所有设备都没有公网IP,出门在外想联机访问就只能考虑内网穿透了,对比了好几个内网穿透方案,最终选择了使用zerotier来创建远程虚拟局域网,考虑到官方服务器中转速度强差人意,又选择了自建moon服务器,网上找的方案都有点模棱两可,这里做个笔记,供自己以及有需要的朋友参考。

设备情况

  • 2台台式机,1台笔记本,其中还运行着几台虚拟机
  • 1台手机

另外还有一台带公网IP的腾讯云服务器,带宽为5M。

台式机安装的是Windows10和黑苹果系统,手机是iOS系统,虚拟机及腾讯云服务器都是最新的Debian系统。

以及,上述几台设备所处的网络环境大多数情况还不一样,有的是电信宽带,有的是移动宽带或者是4G网络。

目的

组建一个远程虚拟局域网,加入此局域网的设备可以互相访问,同时局域网设备所运行的服务能不暴露到公网,且网络速度及质量尽量不影响使用体验。

zerotier注册及安装

在配置zerotier之前,还需要注册一个zerotier账号,注册很简单,账号密码注册或者Google账号登陆都可以,地址:https://my.zerotier.com/

注册完之后,点击“Create A Network”创建一个虚拟局域网,成功之后可以获得一个NETWORK ID,如图:

各个客户端下载地址:https://www.zerotier.com/download/

Windows和macOS很简单,点击页面对应的icon就可以下载,下载之后一步步安装,安装完了将上面获取的NETWORK ID输入进去就行了。

稍微有点特殊的是Debian,zerotier官方提供了官方源,可能需要两步操作,下面命令是在root权限下执行的:

apt update
apt install gpg
curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg' | gpg --import && \
if z=$(curl -s 'https://install.zerotier.com/' | gpg); then echo "$z" | bash; fi
curl -s https://install.zerotier.com | bash

Debian安装完成之后,使用如下命令来加入网络:

zerotier-cli join xxxxxxx # 将xxx替换成对应的NETWORK ID

如果提示“200 join OK”则证明加入网络成功。

但是只是加入网络还不够,还需要到zerotier管理面板进行审核,以允许哪些客户端加入网络,如图是加入到网络的设备信息:

如上图,可以看到哪些设备加入了同一个虚拟局域网,以及分配的IP地址,在线状态以及使用的zerotier版本以及实际的物理地址等,对于允许加入网络的设备可以点击每个设备所在行开头的Auth选项,勾选之后等待一段时间加入虚拟局域网的设备应该就可以互相访问了,命令执行结果如下:

➜  ~ ifconfig
...
feth3478: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 5000 mtu 1500
	ether 8a:e9:10:b8:4e:58
	inet 172.26.0.3 netmask 0xffff0000 broadcast 172.26.255.255
	peer: feth8478
	media: autoselect
	status: active
➜  ~ ping 172.26.0.1
PING 172.26.0.1 (172.26.0.1): 56 data bytes
64 bytes from 172.26.0.1: icmp_seq=0 ttl=64 time=38.174 ms
64 bytes from 172.26.0.1: icmp_seq=1 ttl=64 time=38.006 ms
64 bytes from 172.26.0.1: icmp_seq=2 ttl=64 time=37.438 ms
64 bytes from 172.26.0.1: icmp_seq=3 ttl=64 time=38.293 ms
64 bytes from 172.26.0.1: icmp_seq=4 ttl=64 time=43.177 ms
^C
--- 172.26.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 37.438/39.018/43.177/2.100 ms
➜  ~

上面是从172.26.0.3设备上ping IP为172.26.0.1的设备,这两台设备处于同城不同的宽带下面的内网,可以看出已经可以互相通信了。

只要开启了zerotier,不管目前所处于什么网络,都可以像访问局域网设备一样访问对应的设备,算是初步实现了我开头说的目的,但这还不够。

zerotier官方服务器缺点

上面说的虽然可以互相访问,但是由于流量还是走的zerotier的官方服务器,在高峰期或者说跨宽带运营商的情况下,网络质量实在是堪忧,最直接的体现就是ping值忽高忽低或者掉包,如果是用来长期使用,这网络质量还是有点不行。

正好腾讯云有台5M带宽的服务器,zerotier又支持自建中转服务器,腾讯云的BGP网络用来中转流量再合适不过了。

zerotier moon配置

我的腾讯云服务器安装的是最新的Debian,作为zerotier的中转服务器(moon),zerotier的安装方式以及加入网络的方式和上面一样,但是作为moon,还需要再执行几行命令,相关命令如下。

生成moon模板配置文件:

cd /var/lib/zerotier-one
zerotier-idtool initmoon identity.public >> moon.json

编辑生成的moon模板配置文件:

vim moon.json
#修改这行:
"stableEndpoints": ["1.2.3.4/9993"]

注意需要将上面的1.2.3.4替换成实际的公网IP地址,不能是内网地址。

并且,如果服务器本身开启了防火墙,需要将9993端口进行放行;同时,服务器安全组也需要放行9993端口,比如我的腾讯云轻量云服务器安全组设置截图:

然后根据模板文件生成最终的moon文件:

zerotier-idtool genmoon moon.json

执行完成之后,会在当前目录生成一个名称为000000xxxxxx.json的文件。

创建对应目录,将生成的配置文件放置进去:

mkdir moons.d
mv 000000xxxxx.moon moons.d

重启服务:

systemctl restart zerotier-one

客户端加入自定义的moon

步骤也很简单,Linux及macOS直接在终端执行,Windows需要使用管理员权限在PowerShell或者cmd执行,命令如下:

zerotier-cli orbit 0000000xxxxxxxx 0000000xxxxxxxx

如果加入成功,会有如下提示:

200 orbit OK

查看是否加入moon,在非moon设备上执行如下命令:

zerotier-cli listpeers

如果出现了对应的公网服务器IP及9993端口,说明数据是走moon中转的。比如我的:

➜  ~ zerotier-cli listpeers
200 listpeers <ztaddr> <path> <latency> <version> <role>
200 listpeers 076acf3138 81.xx.xx.xx/9993;15256;17333 -1 1.6.4 LEAF
200 listpeers 3a46f1bf30 185.180.13.82/9993;2100;1914 186 - PLANET
200 listpeers 62f865ae71 50.7.252.138/9993;22371;1886 586 - PLANET
200 listpeers 778cde7190 103.195.103.66/9993;17363;1877 223 - PLANET
200 listpeers 992fcf1db7 195.181.173.159/9993;2101;1859 291 - PLANET
200 listpeers af78bf9436 35.235.xx.xx/44739;414;414 177 1.6.4 LEAF
200 listpeers de57f73969 192.168.xx.xx/9993;15257;15248 2 1.6.4 LEAF
200 listpeers ea9be02164 117.165.xx.xx/53162;235;235 39 1.6.4 LEAF

其中第一个81开头的IP就是我腾讯云服务器。

zerotier打洞使用p2p传输

其实zerotier是支持p2p打洞流量传输的,并不是自建了moon所有流量就经过moon服务器中转的,如图这是我从我电信宽带的设备远程连接到移动宽带内网的设备,在移动宽带内网的设备的带宽统计截图:

192.168.1.13是我设备的移动宽带内网IP,106开头是我电信宽带设备IP,81开头IP是我腾讯云公网服务器,流量大多是在移动宽带和电信宽带设备之间,很少经过腾讯云moon服务器中转的,使用体验还是不错的。

稍微有点惊喜的是,我腾讯云公网服务器带宽是5M,经过zerotier打洞之后使用p2p协议,两台设备之间的带宽可以达到10M,不知道是不是能达到其中一方的带宽上传上线,如图:

内网穿透能用来干啥

对我来说,内网穿透之后,可以随时随地安全地远程连接回家里或者别的处在内网的设备,尤其是TeamViewer不能用的情况下,使用Windows的RDP或者macOS自带的VNC都能简单地进行操控。

除了远程桌面这类运用,还能将一些不方便放在公网的服务放到内网,比如说自建bitwarden或者私有NAS等,还是很方便的。