h4ck1nH4ck1n  2022-07-03 17:50 字节时代 隐藏边栏 |   2 条评论  322 
文章评分 1 次,平均分 5.0

前言

在外面的时候可能会需要连接家里放的树莓派、智能路由器(Openwrt)、NAS 等设备,但是家里的网络一般没有公网 IP 不能直接连接,这时候就需要使用各种内网穿透的方法连接家中的设备。

简介

常见的内网穿透方法有 OpenVPN、 FRP、Ngrok 等,这些方案一般需要一个有公网 IP 的 VPS 做反向代理进行内网穿透连接,连接的速度取决于做中转代理的 VPS 的最大带宽。

这里介绍另外一款免费的、可拓展的、功能强大的内网穿透工具ZeroTier

ZeroTier is a smart Ethernet switch for planet Earth.

ZeroTier通过多个根服务器帮助我们建立虚拟的局域网,让虚拟局域网内的各台设备可以打洞直连。

这些根服务器的功能类似于通过域名查询找到服务器地址的DNS服务器,它们被称为行星(Planet)。

使用官方服务

如果只想简单的使用ZeroTier,不想折腾,可以直接使用官方提供的服务。

在官网注册一个账号,登陆账号配置好自己的虚拟局域网,然后下载安装客户端让设备完成组网即可。

使用官方的服务有几个问题:

  • 免费账户有组网上限,只允许100台设备进行组网
  • 官方行星服务器部署在国外,国内访问延迟很大,虚拟局域网不稳定,容易掉链子

为了解决上面的问题,需要私有化部署ZeroTier服务,搭建私有的行星(planet)服务器。

搭建私有化 ZeroTier

下面以在腾讯云服务器上部署作为例子,记录下搭建流程。

云服务器的系统是 CentOS 7.6.1810 x86_64(Py3.7.9)

安装编译组件

yum install wget gcc gcc-c++ git -y
yum install json-devel -y

安装官方客户端

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

安装完成后,默认监听的端口是9993,这个端口需要对外提供服务,需要在服务器防火墙和云服务提供商的安全组设置放行。

  • 宝塔面板:安全->系统防火墙->输入9993,放行
  • 腾讯云安全组:新增允许访问的规则 UDP:9993TCP:9993

获取必要信息

安装完成后,到安装目录/var/lib/zerotier-one/中找到并记录identity.publicauthtoken.secret文件里的字符串,备用。

注意:每台设备不同,字符串也不同,不要混用

identity.public里的内容格式如下:

65379ff88e:0:161cd83965f056b2a1b8249bd92a7b6cb97b8dcc97808b0df1115f4af85f45474cbdc4353f77c4f033955596b30a596fc493efdb81667622b458ddf8c361c028

authtoken.secret里的内容格式如下:

w8cl25tzb38dvwffenucrbug

下载源码

直接使用 git 拉取源码:

git clone https://github.com/zerotier/ZeroTierOne

由于国内服务器对github访问有限制,可以将源码镜像到gitee,然后在拉取。

另一种简单粗暴,直接下载压缩包然后再上传到服务器解压到ZeroTierOne

修改源码

找到ZeroTierOne/attic/world/mkworld.cpp并打开,仿照mkworld.cpp原来的代码,将我们自定义的Planet服务器添加进去。

注意,需要删除或注释掉至少一个原来的Planet服务器,再增加我们自己的服务器,否则后续执行我们编译的可执行程序时程序会崩溃。

原因是代码里默认只允许4台Planet服务器,可以在World.hpp里看到如下定义#define ZT_WORLD_MAX_ROOTS 4

改后的文件部分内容如下:

    // =========================================================================
    // EDIT BELOW HERE

    std::vector<World::Root> roots;

    const uint64_t id = ZT_WORLD_ID_EARTH;
    const uint64_t ts = 1567191349589ULL; // August 30th, 2019

      // h4ck1n
    roots.push_back(World::Root());
    roots.back().identity = Identity("填写identity.public里的字符串");
    roots.back().stableEndpoints.push_back(InetAddress("服务器ip地址/通讯端口")); // 默认端口是9993,可以自行修改,但不建议

    // 下面这些是官方的根服务器,可以注释或删掉,如果想保留一些官方的根服务器,只需要删除或注释掉一个就行
    // 这里注释掉最后一个根服务器,然后增加一个自己的

    // Los Angeles
    roots.push_back(World::Root());
    roots.back().identity = Identity("3a46f1bf30:0:76e66fab33e28549a62ee2064d1843273c2c300ba45c3f20bef02dbad225723bb59a9bb4b13535730961aeecf5a163ace477cceb0727025b99ac14a5166a09a3");
    roots.back().stableEndpoints.push_back(InetAddress("185.180.13.82/9993"));
    roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c815::/9993"));

    // Miami
    roots.push_back(World::Root());
    roots.back().identity = Identity("de8950a8b2:0:1b3ada8251b91b6b6fa6535b8c7e2460918f4f729abdec97d3c7f3796868fb02f0de0b0ee554b2d59fc3524743eebfcf5315e790ed6d92db5bd10c28c09b40ef");
    roots.back().stableEndpoints.push_back(InetAddress("207.246.73.245/443"));
    roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:9002:5cb:ec4:7aff:fe8f:69d9/443"));

    // Tokyo
    roots.push_back(World::Root());
    roots.back().identity = Identity("34e0a5e174:0:93efb50934788f856d5cfb9ca5be88e85b40965586b75befac900df77352c145a1ba7007569d37c77bfe52c0999f3bdc67a47a4a6000b720a883ce47aa2fb7f8");
    roots.back().stableEndpoints.push_back(InetAddress("147.75.92.2/443"));
    roots.back().stableEndpoints.push_back(InetAddress("2604:1380:3000:7100::1/443"));

    // Amsterdam
//     roots.push_back(World::Root());
//     roots.back().identity = Identity("992fcf1db7:0:206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c50af43322bcfc8e13d3301a1f1003ceb6");
//     roots.back().stableEndpoints.push_back(InetAddress("195.181.173.159/443"));
//     roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c024::/443"));

编译配置文件

cd ./ZeroTierOne/attic/world/

source ./build.sh
./mkworld
mv ./world.bin ./planet

替换配置文件

为了让服务端和客户端都使用我们自定义的服务器,需要使用生成的planet文件替换服务器和客户端的对应文件,各平台的路径如下:

Linux: /var/lib/zerotier-one
FreeBSD/OpenBSD: /var/db/zerotier-one
Mac: /Library/Application Support/ZeroTier/One
Windows: \ProgramData\ZeroTier\One (That's the default. The base 'shared app data' folder might be different if Windows is installed with a non-standard drive letter assignment or layout.)

因此,在服务端执行命令:

cp -r ./planet /var/lib/zerotier-one/
cp -r ./planet /root # 备用

重启服务端

systemctl restart zerotier-one.service

安装管理面板

为了管理设备,需要安装后台管理面板,管理面板有很多,这里使用 ztncui

sudo yum install https://download.key-networks.com/el7/ztncui/1/ztncui-release-1-1.noarch.rpm -y
sudo yum install ztncui -y
sudo sh -c "echo 'ZT_TOKEN=authtoken.secret文件里的字符串' >> /opt/key-networks/ztncui/.env"
sudo sh -c "echo 'NODE_ENV=production' >> /opt/key-networks/ztncui/.env"
sudo sh -c "echo 'ZT_ADDR=127.0.0.1:9993' >> /opt/key-networks/ztncui/.env" # 面板与本地服务的通讯端口,没有自定义端口的话使用9993就行,否则需要和自定义的端口一致
sudo systemctl restart ztncui

更多配置信息,可以查看 README.md

访问管理面板

安装后,默认监听localhost:3000端口,如果要支持外网访问,需要启用反向代理。

宝塔面板配置反代方法:

  • 域名解析:确保域名已经解析到你的服务器ip
  • 新建站点:打开宝塔->网站->添加站点
  • 设置反代:宝塔->网站->点击域名->反向代理,目标URL填写http://127.0.0.1:3000,然后确定

因为安全原因,不建议开放外外网访问,毕竟所有组网设备都连接在一个局域网,风险比较高,而且管理面板使用的频率也不高。

这里使用SSH本地端口转发来将远程服务映射到本地,然后在本机访问。

执行命令:

ssh -p PORT root@服务器IP -L 127.0.0.1:3000:127.0.0.1:3000

现在可以在本机上访问http://127.0.0.1:3000来使用控制面板。

面板的默认账号和密码是admin/password,第一次登录需要改密码,改完密码后在页面上点注销,然后用新密码登录。

创建私有网络

登陆面板以后,点击add a network建立一个虚拟网路,network name网络名称随便填,最后按create a network按钮保存。

页面上的there are no members on this network - users are invited to join xxxxxxx这里的xxxxxxx是网络ID,需要记下方便其他电脑加入。

点击上方的Easy Setup对网络进行其他配置。

客户端组网

这里以 macOS 为例,其他系统类似。

安装官方客户端,各平台客户端下载地址

或者使用brew cask进行安装:

brew cask install zerotier-one

下载服务器上/root目录下备份的planet文件,替换掉/Library/Application Support/ZeroTier/One/planet文件。

注意,AndroidiOS客户端不存在planet文件,无法简单替换,需要特殊处理,比如静态分析后PATCH。
针对iOS客户端,我写了一个简单的Tweak,代码在这ZeroTieriOSFix,Android版本自行搜索。

重启服务:

sudo launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist
sudo launchctl load /Library/LaunchDaemons/com.zerotier.one.plist

打开刚刚安装的ZeroTier应用,在菜单栏上会出现一个图标,点击图标,选择Join New Network...,填入之前新建的网络ID,确认。

登陆管理后台,在Members列表会出现一个新设备,选择它,给设备一个名字,然后勾选Authorized

查看客户端网络状态,如果显示OK,表示组网成功,之后就可以使用管理后台显示的局域网IP对指定设备进行访问。

参考

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

h4ck1n
H4ck1n 关注:0    粉丝:0 最后编辑于:2022-09-05
这个人很懒,什么都没写

发表评论

表情 格式 链接 私密 签到

  1. W
    wwj

    大侠求教,一步步照着来,OPENWRT加了这个能看到。但电脑加了,就是在后台members看不到这个设备。也不知道哪里错了,

    • h4ck1n
      h4ck1n 永久会员 博主

      @wwj看不到这个设备基本上是因为planet文件替换不正确或者替换后服务没重启,既然OPENWRT系统OK,说明服务器配置应该是没问题的。

扫一扫二维码分享