Zerotier 搭建私有planet根服务器及创建虚拟局域网
一、Zerotier 原理
关于 zerotier,搜集网上资料和个人一点浅薄的理解。
planet:
核心角色,官方不允许自建私有,zerotier 的行星服务器,用于管理全球所有的 zerotier 客户端的地址信息,帮助建立客户端间的直接链接,以及在无法建立直接链接时,作为中继服务器转发设备间的流量。
moon:官方允许自建私有,作为离客户端更近的中继服务器存在,可以使转发的效率更高。
原理
客户端注册
在内网机器上启动一个 zerotier 客户端,使用 join 加入一个网络,在控制台对客户端进行授权,此时 planet 上有如下记录:
10.0.0.1 - 150.0.0.1/15679
10.0.0.2 - 160.0.0.1/22226
尝试 p2p 连接
当在 10.0.0.1 机器上访问 10.0.0.2,内网机器向 planet 查询到目标地址的公网 160.0.0.1,端口为 22226。
10.0.0.1 尝试与 160.0.0.1的 22226 端口进行直接数据交互,这个过程称为 udp 打洞实现 p2p 直连。
planet 转发
由于各种网络限制,p2p 不能直连。
此时通过 planet 转发,如果还配置了 moon 节点,此时会通过速度快的 moon 节点进行转发。
如上图则大概率从上海的 moon 节点进行数据转发,此时网络取决于 moon 的带宽。
二、私有 zerotier-planet 的优势
解除官方的设备连接数限制
提升手机客户端连接的稳定性
三、搭建私有 planet
了解了 zerotier 的概念原理,那么大概了解搭建私有 planet 的重要性。
1、运行控制器容器
docker run -d \
--name zt-ui \
-v /home/docker/zt-ui/zerotier-one:/var/lib/zerotier-one \
-v /home/docker/zt-ui/ztncui/etc:/opt/key-networks/ztncui/etc \
-p 4000:4000 \
-p 9993:9993 \
-p 9993:9993/udp \
-e MYADDR=1.1.1.1 \
-e HTTP_PORT=4000 \
-e HTTP_ALL_INTERFACES=yes \
-e ZTNCUI_PASSWD=admin123 \
--restart=always \
hausen1012/ztncui
这里需要注意的是传参需要将 1.1.1.1 修改为公网 ip。
2、生成 planet 文件
sudo docker exec -it zt-ui bash /tmp/patch.sh && \
sudo docker restart zt-ui
如果 linux 内核版本太低,可能报错 FATAL: kernel too old,那么需要升级内核。
关于升级内核,可以参考这篇文章 Linux 系统内核升级。
当然,如果你觉得云服务器不太方便升级内核,那么完全可以用一台测试的虚拟机进行生成文件,文件生成后用 ftp 上传到 /home/docker/zt-planet
目录,然后再启动容器。
3、测试
sudo docker exec -it zt-ui zerotier-cli listmoons
显示如下内容则表示搭建成功
[
{
"id": "00000004e3b1b4b0",
"roots": [
{
"identity": "04e3b1b4b0:0:ea0c548b45efcc701c052305f06568c749a4647b9a5b111e2b372c05f7c3ed56ae1009c29cb1aa51d95057bf1b65b3a2f7b01d129437f6b72efd08f68281fb52",
"stableEndpoints": [
"1.1.1.1/9993"
]
}
],
"signature": "b4f539ef93e198203d9e270c155d091769408ff98489d83bcf6444d2a95112ca7369138b98d42512caa3c878f3eff2c27ecada28f549ea19e3a407e71bbeb008d51f6ba92af17e8b6e4c1b8eacbd4abc42f0f639746ea924cffb99b539f94e2b",
"timestamp": 1665642068786,
"updatesMustBeSignedBy": "7fcb120079801a1ddde8c1fb6657365351bca7279e8470728f4cf01fb5efc81b57cde03338b4ea76dfd39570f74f2654d8d52a22613e77ed2e4cbb46a648a42d",
"waiting": false
}
]
1.1.1.1 为公网 ip 则搭建 planet 成功。
四、创建私有网络
访问 http://公网ip:4000,账号密码:admin/admin123
1、创建网络
1665677264789.png
2、初始化网络
点击 Easy setup
设置网段和子网掩码
五、安装 zerotier 客户端
使用docker 安装
既然已经搭建了私有的 planet,当然是使用自己的,需要先下载服务器 /home/docker/zt-planet/zerotier-one 目录下的 planet 文件。
1、启动 zerotier 客户端
sudo docker run -d \
--name=zt-cli \
--device=/dev/net/tun \
--net=host \
--cap-add=NET_ADMIN \
--cap-add=SYS_ADMIN -d \
-v /home/docker/zt-client/zerotier-one:/var/lib/zerotier-one \
--restart unless-stopped \
hausen1012/zerotier
2、替换 planet 文件
将服务器下载的 planet 文件上传到客户端的/home/docker/zt-client/zerotier-one
目录。
3、重启客户端
sudo docker restart zt-cli
4、查看 planet
sudo docker exec -it zt-cli zerotier-cli listpeers
1665675010184.png
可以看见 stableEndpoints 的配置是自己的公网 ip。
5、加入网络
sudo docker exec -it zt-cli zerotier-cli join 8b8b9ed58a10bd45
6、授权
1665677970480.png
ip 也可以自己设置,不过要在刚刚设置的网段内。
1665678246335.png
Windows 安装
1、下载客户端
下载地址
2、安装客户端
双击安装即可
3、替换 planet
将下载好的 planet 文件复制到 C:\ProgramData\ZeroTier\One 目录下
4、重启服务
如果仅仅只是重启 ui 是不行的,需要找到任务管理器 -> 服务 -> ZeroTierOneService,进行重启。
可以看见 planet 地址是自己的公网。
6、加入网络
点击右下角图标,join new network
,输入刚刚创建的虚拟网络 id,我这边是 8b8b9ed58a0baa3d
。
7、授权
和 dokcer 安装一样的操作,不再赘述。
六、测试
通过上述方式将两台机器加入到网络,通过 ping 查看是否能打洞成功。其中 202 本地虚拟机,vps 是有公网 ip 的云服务器。
ping 检测
在 10.0.0.202 机器上 ping 10.0.0.222。
listpeers 查看到只有自己的私有根服务器,ping 的延迟不到 100ms 和直接 ping 公网 ip 差不多,说明打洞成功。
局域网 scp 检测
可以看见速度能达到十几MB,而我的根服务器是腾讯云的 8Mbps 服务器,如果通过根服务器转发肯定不可能达到这个速度,说明打洞成功。
speedtest 测速
公网部署
这里不建议给部署了Planet 控制器的端口直接不做任何处理的暴露在公网,容易引发安全问题。毕竟谁也不想私人内网里多出来其他不知名设备,给运行在zerotier内网里的其他设备及服务器完全暴露
一、注册域名
这里随便去腾讯云或者阿里买一个几块钱一年的域名即可
一、配置nginx 反向代理
使用nginx 配置反向代理,配置如下
location ^~ /
{
proxy_pass http://localhost:4000;
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# proxy_hide_header Upgrade;
add_header X-Cache $upstream_cache_status;
#Set Nginx Cache
set $static_fileCLeGg9dj 0;
if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
set $static_fileCLeGg9dj 1;
expires 12h;
}
if ( $static_fileCLeGg9dj = 0 )
{
add_header Cache-Control no-cache;
}
}