安装zerotier

参考:https://zhuanlan.zhihu.com/p/123956151

https://blog.csdn.net/coldboy258/article/details/93133860

https://post.smzdm.com/p/a7nwn8q9/

视频解释:https://www.bilibili.com/video/BV1Vh411F7Mr/

写在前面

Zerotier服务分为两部分,控制器和root

Zerotier官方提供了自建的文档,其中web后台属于“controllers控制器”,控制器是开源的,但不提供webui,GitHub上有开源的ui项目,比如zero-ui和ztncui。

控制器使用根的API创建和管理网络,不参与流量通信

根服务器(Root Server)负责流量转发和P2P通信,根服务器如果是完全自建的话,那就是私服,不参与官方的节点网络,也就是Zerotier中的“Planet(行星节点)”的概念

如果想使用官方的Planet的同时使用自己的根服务器,那就是以Moon(月亮节点)的形式加入到网络中。两者用起来其实没有区别,只是标识不同,无论是自建的Planet还是Moon,都可以被自建的控制器调用

但有一点需要注意,自建控制器的网络和官方web后台不通用,你不会在官方web后台看到你在自建控制器上创建的网络,反过来也一样,自建控制器也看不到官方控制器创建的网络。但网络ID的加入是可以通用的,即使你不搭建自己的Moon节点,同样也可以使用自己的控制器+官方的Planet进行通信


创建虚拟局域网

在zerotier官网 https://zerotier.com/ 上注册账号,并创建一个虚拟局域网

下载与自动安装

zerotier官方提供了比较方便的安装方式,一条命令即可完成:

1
curl -s https://install.zerotier.com/ | sudo bash

加入网络

1
zerotier-cli join fadxxxxx5eb45a9

随后,在zerotier官网上同意这个设备的接入,此设备就加入虚拟局域网成功了

服务器注册成为Moon

这里的Moon是中继服务器,默认用使用官方的中继服务器,但延迟较高;

Moon只有在直连失败时才会使用中继服务器进行中转服务器

生成moon配置文件

1
2
3
4
#安装好zerotier后,自动会安装到此目录
cd /var/lib/zerotier-one
#该命令将id文件转换为能用于配置的json
sudo zerotier-idtool initmoon identity.public > moon.json

修改配置文件moon.json

  1. 在防火墙开放9993的udp;默认使用iptables即可
1
2
3
4
5
6
7
8
9
10
11
12
13
# 默认使用iptables即可
# 除非你非常清楚使用ufw或firewalld控制;
#iptables
iptables -A INPUT -p udp --dport 9993 -j ACCEPT
service iptables save
service iptables restart

#firewalld
firewall-cmd --zone=public --add-port=9993/udp --permanent
firewall-cmd --reload

#ufw
ufw allow 9993/udp
  1. vim 编辑 /var/lib/zerotier-one/moon.json,主要是添加公网IP,修改内容如下
1
2
3
4
5
6
7
8
"roots": [
{
"identity": "xxxx:xxxxxx",
# 修改 23.23.23.23 为 VPS 的公网的 IP,以 IPv4 为例,记得带引号
# 9993是默认端口,不建议修改
"stableEndpoints": [ "23.23.23.23/9993" ]
}
],

注:23.23.23.23为公网ip, 一定要配置正确,Zerotier依靠此配置去连接moon.

后面的端口若没有改变则默认都是9993端口, 且是UDP协议的, 此处在防火墙上需要开放UDP,否则是连接不上Moon的.

该配置里面,有一个id字段,10个字符,如: [ “id”: “18fasd2319” ] 就是moon的id, 在客户端连接时,需要用到它

这里的id还可以通过以下两个命令得到

1
2
3
4
#
grep id /var/lib/zerotier-one/moon.json | head -n 1
# 或者
zerotier-cli info

生成moon文件

1
sudo zerotier-idtool genmoon moon.json 

执行该命令后,会在在/var/lib/zerotier-one目录下生成一个类似00000018fasd2319.moon的文件…这个文件非常重要,所有的客户端要连接上moon都是依靠该文件关联的…

使moon配置文件生效

/var/lib/zerotier-one目录下,新建一个 moons.d 文件夹

1
mkdir moons.d/

并将刚生成的moon配置文件放到该文件夹下

1
mv 000000*.moon moons.d

重新启动Moon服务器

由于使用命令安装时会自动注册为服务,所以可以依靠以下命令完成启动或重启**(执行一个即可)**

1
2
3
4
5
6
7
service zerotier-one restart  #服务重启命令

/etc/init.d/zerotier-one restart #服务重启命令

service zerotier-one start #服务启动命令

zerotier-one -d #或直接程序启动

经过以上配置,服务器上的moon即配置并应用完闭.

罗列当前的moons信息

1
sudo zerotier-cli listmoons

客户端使用Moon

假设已经“A服务器”为了Moon,此时让"B服务器"设置"A"为其Moon服务器

接下来就需要在各客户端zerotier上配置,并连接此服务器

有两种方法可以完成.

方法1(自动)

离开某个orbit

1
zerotier-cli deorbit 2xx1229222

只需执行此命令即可,此处需要输入两遍id:

1
zerotier-cli orbit 18fasd2319 18fasd2319

此种方法依赖zerotier的根服务器,若根服务器连接不上,则会无效

方法2(手动)

Linux:

  1. 直接在zerotier目录(/var/lib/zerotier-one/)下,创建moons.d文件夹
  2. 并且将生成的00000018fasd2319.moon文件拷入
  3. 重启服务即可

Windows:

  1. 打开服务程序services.msc, 找到服务"ZeroTier One"
  2. 在属性内找到该服务可执行文件路径,我的环境下为C:\ProgramData\ZeroTier\One\zerotier-one_x64.exe
  3. 打开该文件夹, 并且在其下建立moons.d文件夹
  4. 将moon服务器下生成的00000018fasd2319.moon文件,拷贝到此文件夹内…再重启该服务即可

此处重启的是该项服务,不是电脑右下角的图标程序…网上大多资料都没法特别说明,或者含糊没说清,甚至重启电脑之类的说法都说出来了,比较马虎…右下角任务栏程序路径是在C:\Program Files (x86)\ZeroTier\One目录下,而服务路径却并非在该路径,若将moons.d文件夹放不对位置,是无法连上Moon服务器的.)

安卓:

推荐项目 https://github.com/kaaass/ZerotierFix 优点是可以配置moon

下载软件后,在设置中可以添加moon,输入moon对应的ID即可;或者手动导入文件,操作与上述类似

验证生效

要验证是否moon生效,只需要在客户端zerotier程序目录下,执行以下命令即可:

windows/linux通用命令

1
2
3
4
# 查看节点状态,留意moon服务器端口是否为9993
zerotier-cli listpeers
# 留意moon服务器是否是“DIRECT”
zerotier-cli peers

若有类似地址(末尾是“MOON”而且ip和端口正常),即可证明moon连接成功

1
200 listpeers 18fasd2319 23.23.23.23/9993;4242;4038 224 1.2.12 MOON

安卓

软件上peers选项卡里可以查看上述内容


在旁路由使用zerotier

假设openwrt旁路由的实际局域网为192.168.6.155

这种方式,必须让192.168.6.0/24网段下的设备,设置其网关和DNS为旁路由ip地址

打开openwrt网页中的zerotier软件,填写虚拟局域网ID,点击启用即可,随后保存并应用

image-20240525231051219

随后在zerotier的网站上,允许openwrt系统接入,在旁路由输入以下命令来判断是否加入成功

1
zerotier-cli listnetworks

返回值如下即加入成功,并且虚拟局域网ip为:172.22.33.155

1
2
200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
200 listnetworks fada252630165xxx xxxxxx bb:95:e9:ff:ee:64 OK PRIVATE zasdhyt5n4 172.22.33.155/16

为了让旁路由下的所有设备(不下载zerotier)直接可以访问虚拟局域网所有设备

并且这些设备本身不要在zerotier加入虚拟局域网,否则会出现环路,如果已经加入了就取消auth

自动允许客户端 NAT 要打开,随后保存并应用

随后在zerotier的网站上,Add Routes填写以下内容

Destination写局域网的网段,如192.168.6.0/24;Via写旁路由的虚拟ip:172.22.33.155

image-20240525231559150

从而,虚拟局域网所有设备与192.168.6.0/24网段下的所有设备互通


查看所有设备

由于ZeroTier的Web管理端做的不是很易用,每次都登录my.zerotier.com查看信息特别不方便。调研了一下,发现ZeroTier官方提供的API接口 Returns a list of Members on the network正好能提供我所需要的信息。所以写了一个one-line shell命令在终端用表格展示一下结果。

首先,安装必备的软件。这行命令需要curljq这两个工具。Linux一般默认安装了curljq则需要手动安装。安装命令为:

1
2
3
4
5
6
7
# jq官方安装文档:https://stedolan.github.io/jq/download/
# Ubuntu
sudo apt-get install jq
# Arch
sudo pacman -S jq
# Mac
sudo brew install jq

然后,申请一个ZeroTier的管理Token,在 Account页面的API Access Tokens处新建一个Token即可。

最后,执行下面的one-line脚本:

请自行替换为你申请的Token和你的网络ID

1
2
3

# bearer和token中间的空格不能省略。这个是ZeroTier官方指定的。
curl -s -X GET -H "Authorization: bearer <Token>" https://my.zerotier.com/api/v1/network/<NetworkID>/member | jq -r '([" NodeID ", "Online", "ZerotierIP", " PhysicalIP ", "Name"] | (., map(length*"-"))),(.[] | [.config.id, .online,.config.ipAssignments[0] , .physicalAddress, .name]) | @tsv'

输出结果类似于:

1
2
3
4
5
   NodeID       Online  ZerotierIP        PhysicalIP    Name
------------ ------ ---------- -------------- ----
f481514ad3 true 10.4.1.1 125.155.212.118 A1
f55176bfa2 false 10.4.1.2 125.157.213.8 A2
f765b69b0a false 10.4.1.3 125.158.146.205 A3

问题排查

确保 UFW 的默认转发策略允许 Moon 工作

建议先关掉ufw ufw disable 观察是否能使用中转服务器中转成功

并且在其它设备上,使用listpeers,观察中转服务器的端口是否为9993

如果 UFW 阻止了转发流量,请执行以下操作

  1. 启用 IP 转发:

    • 检查 /etc/sysctl.conf 中是否有以下设置:

      1
      net.ipv4.ip_forward=1

      如果没有,添加它。

    • 应用更改:

      1
      sudo sysctl -p
  2. 允许转发流量: 编辑 /etc/ufw/sysctl.conf,确保以下配置存在或修改为:

    1
    net/ipv4/ip_forward=1

    然后编辑 /etc/default/ufw 文件,将以下参数设置为 ACCEPT

    1
    DEFAULT_FORWARD_POLICY="ACCEPT"
    • 重启 UFW:
    1
    sudo ufw reload

使用 tcpdump 监控实时流量

tcpdump 可用于捕获9993端口的实时网络数据包

1
sudo tcpdump port 9993

netstat可以列出系统中当前所有端口的使用情况

1
sudo netstat -tuln | grep 9993

附录

由于很多人对配置服务端的moon都会有修改端口的需求,方法如下,但我没成功

在运行程序同级目录下建立local.conf文件:

文件内容配置如下,primaryPort即为想要配置的端口:

1
2
3
4
5
6
{
"settings":
{
"primaryPort":9994
}
}

local.conf 完整配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"physical": { /* Settings that apply to physical L2/L3 network paths. */
"NETWORK/bits": { /* Network e.g. 10.0.0.0/24 or fd00::/32 */
"blacklist": true|false, /* If true, blacklist this path for all ZeroTier traffic */
"trustedPathId": 0|!0 /* If present and nonzero, define this as a trusted path (see below) */
} /* ,... additional networks */
},
"virtual": { /* Settings applied to ZeroTier virtual network devices (VL1) */
"##########": { /* 10-digit ZeroTier address */
"try": [ "IP/port"/*,...*/ ], /* Hints on where to reach this peer if no upstreams/roots are online */
"blacklist": [ "NETWORK/bits"/*,...*/ ] /* Blacklist a physical path for only this peer. */
}
},
"settings": { /* Other global settings */
"primaryPort": 0-65535, /* If set, override default port of 9993 and any command line port */
"portMappingEnabled": true|false, /* If true (the default), try to use uPnP or NAT-PMP to map ports */
"softwareUpdate": "apply"|"download"|"disable", /* Automatically apply updates, just download, or disable built-in software updates */
"softwareUpdateChannel": "release"|"beta", /* Software update channel */
"softwareUpdateDist": true|false, /* If true, distribute software updates (only really useful to ZeroTier, Inc. itself, default is false) */
"interfacePrefixBlacklist": [ "XXX",... ], /* Array of interface name prefixes (e.g. eth for eth#) to blacklist for ZT traffic */
"allowManagementFrom": "NETWORK/bits"|null, /* If non-NULL, allow JSON/HTTP management from this IP network. Default is 127.0.0.1 only. */
"allowTcpFallbackRelay": true|false /* Allow or disallow establishment of TCP relay connections (true by default) */
}
}