ZeroTier 建立虚拟局域网

这是远程联机游戏的终极解决方案。

不得不说别人建立虚拟局域网都是为了远程办公或者是使用校网权限,而我天天搞各种计算机网络的东西都是为了和同学联机。

联机游戏的连接方式有 Steam 提供的服务器、游戏官方提供的服务器(MC 的领域)、公开的游戏平台(各种战斗平台之类的),一些较老的游戏支持直连。但是就是有的游戏只支持局域网联机,想远程和同学玩只能自己搭远程服务器。

搭一个远程局域网可以解决所有支持局域网联机游戏的联机问题,一劳永逸不赶紧试试。

搭建远程局域网的工具有很多,比如偏向技术一些的通过 VPN 硬件设备搭建的 SSL VPN, PSec VPN 结构局域网,或者是大众一些的向日葵。其中一个很有名的是 Hamachi,这玩意我当年联机 Terraria 的时候就尝试用过了,迫于当时年轻不会搞,就没用下去。

但是这些软件不开源,都是商业软件,不符合 Linux 哲学,所以找到了 ZeroTier.

相关的教程比较多,但是这毕竟不是一个大众软件,没有完善的很高质量的教程。所以这也算个综述文章,把坑尝试排一排。

这个文章写的是一个 Ubuntu 主机作为 Moon 主机的搭建过程,原理在最后讲一点点。

开始搭

整体流程:

  1. ZeroTier 官网注册 + 配置一个网络
  2. Ubuntu 主机安装 ZeroTier 并连接服务器
  3. Ubuntu 主机开启 Moon 并生成 Moon 配置文件
  4. Windows 客户端安装 ZeroTier + 导入 Moon 配置文件

其中ZeroTier 官网注册 + 配置一个网络可以参考这篇文章到第八步,写的很详细。

云服务器配置 ZeroTier

然后就可以开始配置 Ubuntu 云服务器上的内容了。对于 Linux 系统 ZeroTier 官网有提供快速的安装脚本:

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

GPG base:(在连接过程中基于 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 上创建的网络:sudo zerotier-cli join aabbccddaabbccdd 是 ZeroTier 上的 Network ID。

加入成功会有 200 join OK 的提示,如果这时候去看 ZeroTier 后台的话也是能看到这个设备的,如果网络设置成 Private 的话,别忘了在后台同意一下。

N.B. 虽然连接网络是可以交给用户而不用 sudo,但是下一步生成 Moon 配置文件需要写入 /var ,早晚还是要转到 root 权限,所以直接全部 sudo 好了。

之后生成 Moon 配置文件(需要 root 权限,而且是要切换 root):

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

然后此目录下会生成 moon.json 文件,将文件中的"stableEndpoints": []中填入云服务器的公网 IP,如 "stableEndpoints": ["100.100.100.100/9993"],别忘了 9993 的端口和引号。

说到端口,这个时候需要在你云服务器的运营商后台的安全管理上把 TCP 的 9993 端口开放,这样之后才能生效。

修改完 moon.json 之后运行指令 zerotier-idtool genmoon moon.json 以生成签名文件。该签名文件就在本目录下,名称格式为六个 0 + Network ID.moon。

这个签名放这里还不行,需要在本目录下创建一个名为 moon.d 的文件夹,将这个签名文件挪进去:

mkdir moon.d
mv 000000aabbccdd.moom ./moon.d/

到这服务器端的配置就完成了,重启一下 Zero Tier 服务就会生效:service zerotier-one restart

Windows 客户端主机配置 ZeroTier

好,网上大部分教程都到这里为止。剩下的内容简单,问题也多。

毕竟我准备用这个来联机游戏,所以除了服务器,其他平台都是 Windows。Windows 上的 ZeroTier 软件安装很简单,一个 msi 安装包直接运行就可以。

连接起来也是有 GUI 的低成本操作,右键 Windows 工具栏中的 Zero Tier,选择 join network 填入 Network ID 就可以连接。

值得注意的一点是别忘了设定防火墙,强烈不推荐全关,随便找个开放 Windows 网络端口的教程顺着做一下,这样安全的多。如果想测试是否在一个局域网里,也可以把 Ping 的端口打开。

在 Windows 上安装完 ZeroTier 之后,把 Linux 上的签名文件复制到 C:\ProgramData\ZeroTier\One 下,这次同样需要创建一个 moon.d 的文件夹,再把签名文件放进去。

之后需要在 Windows 上重启 ZeroTier 的服务,只退出重启软件并没有用,需要用 cmd 或者 PowerShell 运行指令重启服务 net stop ZeroTierOneService, net start ZeroTierOneService

或者任务管理器中 Server 栏找到 ZeroTierOneService 右键也可以重启。

确保防火墙关了 + ZeroTier Server 运行正常 + 连上 Network 也同意了。Ping 一下云服务的虚拟内网 IP 试一试。这个 IP 可以用 ifconfig (Linux) 或 ipconfig(Windows) 查看,或者在 ZeroTier 后台中看到。

如果不出意外的话,所有按照这个流程操作的 Windows 主机可以互相 Ping 通。

联机试试

这个时候已经可以相互联机了,支持局域网联机的游戏在创建好房间之后其他朋友也可以看得到了。也可以通过内网 IP 直连。

但是有时候质量奇差,这个时候就要看看 Moon 配置的对不对了。如果你有一台不是云服务器的 Linux,那么查看方式可以直接运行一条指令 sudo zerotier-cli listpeers,其输出中会指明哪个是 Moon。

那么在 Windows 上有没有这个指令呢?可惜,我没找到,Windows 上的 ZeroTier 本身就没有提供 Shell 的指令,而且客户端也没有相应的界面(不知道未来版本会不会更新),所以说在 Windows 上确认 Moon 服务器似乎不太行,还是得用 ZeroTier 提供的基层指令。

如果 Moon 没有问题,这个情况就变得玄学起来了。

上可甩锅网络运营商,毕竟众所周知联通移动电信三家网路远程连接日常出问题,而且这些网络运营商本质抵触私建远程局域网,会断连接;下可怀疑 ZeroTier 的优化,毕竟网上还真每太多人拿这个来联机游戏,可能远程连个 Linux 可以低延迟,但是面对大量数据包交换的游戏 ZeroTier 并没有优化其传输。

毕竟网络这东西从物理层面都复杂,一旦远程了分析起来问题更麻烦。所以还是早早开学和同学物理局域网联机好了。

一些原理的理解

计算机网络的知识就不讲了,说说 ZeroTier 的网络结构。

ZeroTier 在世界各处有一些主机提供数据交换的处理工作,一些关于服务器的收费项目这些也是开发者的收入来源。我们在 ZeroTier 后台创建的网络就是由他们这些主机负责转发包的,只是免费网络有 100 个接入限制。

但是喜闻乐见,这些服务器都不在大陆境内,所以访问速度自然会慢,如果不做处理的话连 Ping 的稳定都不能保证。Moon 就是为此设计。

ZeroTier 的这些主机是 Planet 行星主机,我们可以用自己的主机作为 Moon 卫星主机。成功建立连接之后(包含签名认证),我们就可以比较快的用 Moon 来交换数据、组建网络,来获得一个质量比较好的虚拟局域网。

那么这么看来 Planet 主机似乎没有用处,ZeroTier 为什么不提供直接运行在 Moon 上的搭建虚拟局域网的软件。个人认为难点在于组网过程中的麻烦,倒也不是不行。目前已经有这样的工具了,如果可以全部由自己解决,那么才能叫得上是终极解决方案。