Zerotier - 分分钟组网工具

之前一直在用,v2ray 服务器在内网开端口,相当于通过代理的方式访问内网,利用内网的 openwrt 中 smartdns 做 dns 解析服务。

同事最近买了个群晖,但是家里没有公网 IP,所以一直在用 Frp 做内网穿透。但是 FRP 使用过的比较清楚,速度依靠公网服务器的带宽,而且每起一个服务都要暴露一个端口。

在此之上,我进行了一番搜索,发现了一个新东西——Zerotier。

这是一个类似于 ZooKeeper 的工具,一款异地组网工具。每台服务器上只需要安装对应的客户端,连接到同一个网络,就可以实现 IP 互相访问。在此之上,还有自定义 DNS 服务器的功能,将通过 IP 这个步骤转换为通过域名进行访问,相当实用。

纵观国内的文章,基本都是上来就一步一步搭建,没有任何解释性说明。在几天的折腾后,搞了篇解释比较强的文章。

根据 Zerotier 的官方简介,是这个意思:

Connect team members from anywhere in the world on any device. ZeroTier creates secure networks between on-premise, cloud, desktop, and mobile devices.

概念

所有的设备都是客户端,连接方式是点对点。在路由器下面的话是用 uPnP 的方式进行转发实现客户端到客户端的直接连接。如果 uPnP 没有开启,会通过传统的服务器转发的方式进行连接。

Earth

根据其介绍,将地球上的所有设备连起来。那这里的 Earth 指的就是整体的一个服务。

Network

每一个 Network 包含的所有设备都在同一个网络里。每个网络有一个 Network ID。各客户端通过这个 ID 连接到此网络。当然,一个账号是可以创建多个网络的。

网络氛围 Public 和 Private。一般我们自己组网是要用 Private,需要在页面授权设备才可以进行访问。Public 权限好像不太有人会需要吧..

以下介绍的所有概念都是属于 Network 下的。

Planet

星球嘛。指的是官方提供的服务器节点。各客户端都是通过这些服务来互相寻址的。相当于 zookeeper 的不同节点。

Moon

自定义的 Planet。由于 Zerotier 没有国内节点,在两个设备刚开始互连的时候有可能需要通过国外的节点寻址(不过我没发现有什么慢的)导致创建连接的速度偏慢。在自己的网络里搭建 Moon 可以使连接提速。

Leaf

客户端。就是连接到网络上的每一个设备。其实经过测试,Moon 也是客户端的一种。这里特指没有额外功能,单纯用于连接的客户端。

开始使用

Zerotier 支持基本所有设备:Windows、MacOS、iOS、Android、Linux、FreeBSD、Synology、QNAP、WD MyCloud、OpenWRT。再不济,支持 Docker,凡是能跑 Docker 能联网的设备都可以用。

其中 iOS 不支持自定义 Moon,Android 的自定义 Moon 要下载非官方的 APP。

本着不给自己找麻烦的原则,能用 ui 就用 ui,能一键搭建就一键搭建。给了 docker-compose 就直接用,不要折腾乱七八糟的东西。

注册账号

官方网站登录,我直接用 Github 登录。登录后发现我两年前玩过这个东西…

创建网络

不用输入任何没用的信息,上来直接创建网络,只需一次点击,网络就创建好了。

记住这个 Network ID,以后会经常见到。

点击网络进去,默认配置基本够用。

连接客户端

  • MacOS

brew install zerotier-one

官方下载链接

安装好后,启动。

在下面输入网络 ID,点击 Join Network 即可。

Windows 的 UI 跟这个一毛一样。

  • iOS

AppStore 搜索 Zerotier,下载。点击右上角加号,输入网络 ID,OK。

  • Linux

根据官网给的说明,直接运行脚本即可。

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

如果你安装了 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" | sudo bash; fi

脚本会自动将 Zerotier 的源添加到 apt/yum 里并安装。

安装好后,运行命令 sudo zerotier-cli join 你的网络ID

即可。

  • 群晖

DSM 7 不支持 root 安装第三方程序,因此官网建议使用 Docker 来实现。英文文档在这里:https://docs.zerotier.com/devices/synology/

简单说就是 ROOT 权限。

首先,将虚拟网卡添加到启动项:

1
2
3
echo -e '#!/bin/sh -e \ninsmod /lib/modules/tun.ko' > /usr/local/etc/rc.d/tun.sh
chmod a+x /usr/local/etc/rc.d/tun.sh
/usr/local/etc/rc.d/tun.sh

以上执行后就有虚拟网卡了。然后创建 docker 容器:

1
2
3
4
5
6
7
8
docker run -d           \
  --name zt             \
  --restart=always      \
  --device=/dev/net/tun \
  --net=host            \
  --cap-add=NET_ADMIN   \
  --cap-add=SYS_ADMIN   \
  -v /var/lib/zerotier-one:/var/lib/zerotier-one zerotier/zerotier-synology:latest

启动后,执行以下加入网络

1
docker exec -it zt zerotier-cli join 你的网络ID

有 compose 的话,我是这么操作的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
version: "3.3"
services:
  zerotier-synology:
    container_name: zt
    restart: always
    devices:
      - /dev/net/tun
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    network_mode: host
    volumes:
      - "./data:/var/lib/zerotier-one"
    image: "zerotier/zerotier-synology:latest"

加入网络:

1
docker-compose exec zerotier-synology zerotier-cli join 你的网络ID
  • OpenWRT

软路由上,有一个 Zerotier 工具,启用,输入网络 ID,保存并启用即可。

  • Docker

首先启用虚拟网卡(跟群晖一样,这步我还不知道怎么搞)

用以下 docker compose 文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
version: "3.3"
services:
  zerotier:
    devices:
      - /dev/net/tun
    privileged: true
    image: zerotier/zerotier
    network_mode: host
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    command: ["你的网络ID"]
    volumes:
      - ./data:/var/lib/zerotier-one

我不知道为什么网上的人都爱用第三方很久不更新的镜像。用官方的不香吗。

直接启动即可。

授权

每一次添加了客户端后,在控制面板上会显示新设备加入,勾上前面的勾表示对这个设备授权,会给其分配 IP,显示 zerotier 客户端的版本号和物理地址。

免费版最多一个网络可以有 50 个设备。真大方.. 怎么用都够用了。

使用

好了,这回,只要输入对应的虚拟 IP,就可以访问对应的设备了。这些设备相当于都处于同一个局域网下了。你会发现,速度相当快了。

状态管理

命令行的使用

所有的设备都是使用 zerotier 相同源码编译的客户端。我们平时主要操作的就是 zerotier-cli。其他的,zerotier-one 是运行程序,zerotier-idtool 是生成客户端 id 使用的。zerotier-cli 要使用root权限运行。

  • 查看所有设备

zerotier-cli peers

Path 指的是连接时连接到的 IP 地址。这台机器是我最头疼的一台,它给 zerotier 的地址都是 ipv6 的,导致它的节点与其他 ipv4 的节点没办法互联,搞了我好几天了。

不过也可以看见,同一内网下的话,IP 会使用内网的 IP,不需要再经历转发的流程。

其中 link 代表了连接状况。DIRECT 代表可以直接连接,RELAY 代表需要转发。转发的速度当然会慢一些,因此尽量保证你的 NET 类型为 A/B。(跟 switch 学来的)这里我还没有细致研究,不过只要你的路由器支持 uPnP,一般都是直连。

这里有连接方式的官方介绍,我懒得看:https://docs.zerotier.com/zerotier/troubleshooting#recommended-local-network-and-internet-gateway-configuration

  • 查看网络

zerotier-cli listnetworks

这里有以下信息:网络 ID、名称、本机的虚拟 IP 地址,和网络状态。其中,网络状态 OK 表示正常,REQUEST_CONFIGURATION 表示没有 uPNP,连不上,ACCESS_DENIED 表示还没有授权。其他的状态我还没见过。

  • 查看连接情况
1
zerotier-cli info

高级

自定义 Moon

任何一个节点都可以作为 Moon 使用。当然,正常的我们肯定会选择公网 IP 的节点,一般都会使用云服务器。

官方文档在这里:https://docs.zerotier.com/zerotier/moons

那么第一步就是搞一台云服务器,在上面连接好网络。

进入配置文件夹,linux 上的是/var/lib/zerotier-one。执行zerotier-idtool initmoon identity.public >>moon.json

打开的文件大概长这个样子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "id": "deadbeef00",
  "objtype": "world",
  "roots": [
    {
      "identity": "deadbeef00:0:34031483094...",
      "stableEndpoints": []
    }
  ],
  "signingKey": "b324d84cec708d1b51d5ac03e75afba501a12e2124705ec34a614bf8f9b2c800f44d9824ad3ab2e3da1ac52ecb39ac052ce3f54e58d8944b52632eb6d671d0e0",
  "signingKey_SECRET": "ffc5dd0b2baf1c9b220d1c9cb39633f9e2151cf350a6d0e67c913f8952bafaf3671d2226388e1406e7670dc645851bf7d3643da701fd4599fedb9914c3918db3",
  "updatesMustBeSignedBy": "b324d84cec708d1b51d5ac03e75afba501a12e2124705ec34a614bf8f9b2c800f44d9824ad3ab2e3da1ac52ecb39ac052ce3f54e58d8944b52632eb6d671d0e0",
  "worldType": "moon"
}