使用ZeroTier进行异地组网

家庭网络与IPV4的困境

随着技术水平的提升,各种需求开始出现,家里也出现了成堆NAS软路由之类的电子垃圾。又很不巧,这堆电子垃圾还需要经常访问它们的服务,保持与它们的连接。在家里使用局域网的环境还好,但是走出家门,马上就出现了一个《小问题》——你要怎么找到自家设备呢。

如果你有一个IPV4公网地址,这个问题当然就简单了,你的网关接到自家的路由器,让它帮你转发所有到局域网的请求。当然也有别的方案,端口转发和NAT之类,这里不再赘述。

那如果你没有IPV4公网地址呢?众所周知,国内的宽带运营商可是不会给你提供公网IPV4的地址的。那这个简单的问题一下就变成了一个技术问题。据我所知,现在一般有3种解决方案:公网IPV6、内网穿透和异地组网。三种方案我都踩过坑了,因此在这里都简要介绍一下。

公网IPV6+DDNS

没有IPV4就用IPV6呗。现在各家运营商的宽带基本都开启了IPV6,并且大方地给各家都配上了公网地址,因此直接把家里的设备挂上公网IPV6就ok了。如果嫌IPV6地址太长的话,可以随便买个域名把AAAA记录解析到地址。如果IPV6地址经常变动,整个DDNS服务就完事了。总之都有解决的方案。

那么这个方案的问题是什么呢?

  1. 你的宽带有了IPV6,你的流量没有啊。
    经过测试,蜂窝数据的IPV6覆盖时有时无,基本只有才城里才有,当然这也不是绝对,总之哪里有哪里没有是一门玄学。
  2. 你的宽带有了IPV6,别人的宽带没有。
  3. 你和别人都有IPV6,但是你的机器不支持IPV6。
    这个是有可能发生的,比如你的光猫可以IPV6公网,但是你的路由器可能不能用IPV6,那你就还是不能用上IPV6。

总而言之,IPV6肯定是好的,坏处只有一个——你没有IPV6。

内网穿透

内网穿透的原理也很简单——既然你没有公网IPV4地址,那我找个有公网IPV4的机器转发你的报文不就好了。内网穿透的方案也有很多,例如nps、frp之类。
这个方案自然也存在一点《小问题》

  1. 首先你得有一个有公网IPV4的机器,并且保持其稳定运行,流量足够。
    这个问题说难不难,主要就是找到一家便宜、稳定、量大的服务提供商。问就是加钱
  2. 隐私和安全的风险。
    流量终究是要过服务器的,如果是一些不太合规的服务不免出现提供商审查的风险。 (既然你搭建了本地服务器,你的服务多半不太合规) 总之我已经被腾讯云关掉了一个服务器。同时,一部分网页暴露在公网环境也有一定的风险,处理这些安全问题也是一个麻烦事。你也不希望看自己照片需要输入强密码吧
  3. 每个端口需要单独映射。
    流量是通过服务器的端口进行转发的,显然也只能转发到你家里机器的一个端口。需求一多,慢慢点吧。不过这个已经是最细枝末节的问题了。

异地组网

这部分本来是要写的,但是我仔细一想,异地组网就是下面的内容,你用就完事了,肯定好使。

Zerotier设置

注册账号

https://www.zerotier.com/ 注册一个账号,有手就行。

创建网络

注册并登录之后,可以创建一个网络。接下来介绍一些比较重要的选项。
Access Control
主要用来控制网络是否公开。

如果选项为Private,那么所有连接进来的设备都需要自行打开Auth选项才能进入网络。

如果选项为Public,那么设备只要拥有网络ID就能进入网络。

IPv4 Auto-Assign
选择一个虚拟网络的网段,随便选,只要IP不冲突均可。比如我们在这里就选择了172.30.*.*作为我们虚拟网络的网段。

客户端设置

可以看到,官网上提供了各种平台的客户端。

Private网络记得在设置完后去Zerotier网络设置中开启权限(重要)

Docker in Linux

我是懒狗,我用Docker。这里提供一个自用的docker-compose.yml文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: '3'
services:
zerotier:
image: zerotier/zerotier
container_name: zerotier-one
devices:
- /dev/net/tun
network_mode: host
volumes:
- './conf:/var/lib/zerotier-one'
cap_add:
- NET_ADMIN
- SYS_ADMIN
restart: unless-stopped

启动之后,使用以下命令加入网络。

1
docker exec zerotier-one zerotier-cli join 网络ID

这样Linux客户端的部分就部署完成了。可以通过ifconfig或者ip addr命令来查看效果,可以看到客户端已经被分配到了172.30.1.1的地址。

Windows

Windows客户端的设置属于有手就行。

  1. 下载Windows客户端并安装。
  2. 在任务栏找到图标,右键点击-加入网络-输入网络ID。
  3. 接下来会跳出一些增加网络适配器的提示,全部选是,接下来等待状态变为OK,就连接上虚拟网络了。

同样可以通过ipconfig命令或者直接进入适配器选项设置中来查看效果。

通过虚拟网络连接其他设备

到了这一步,我们已经可以通过被分配到的172.30.*.*地址来访问刚才加入到网络的设备了。我们可以ping一下试试。

显然,其他的服务也可以访问了,就像在局域网中一样。
接下来就是把所有需要连接的设备都加入虚拟网络,这样所有的设备都可以访问了。
如果你需要访问的设备已经全部加入虚拟网络,并且用起来没有问题,就不用往下再看了。

转发设置

上面的方案已经解决了大部分的设备了,但是如果你家有大量设备,或者有些设备不能安装Zerotier的客户端,那么以下的内容可能对你有用。接下来主要介绍如何把一整个局域网挂在Zerotier上。

Zerotier设置转发路由

首先我们要在Zerotier中设置一个客户端作为转发路由。比如我们选中一台设备,它在局域网中的地址为192.168.31.9,在Zerotier虚拟网络中的地址为172.30.1.1。我们设置到达192.168.31.*的请求都经由172.30.1.1转发。

接下来去设备列表中设置Allow Ethernet Bridging,选中就行。

这样Zerotier部分就设置完成了,但是我们的客户端还没有准备好转发请求,这个部分将在以下部分介绍。

使用iptables进行转发

Linux自带的iptables工具既是一个防火墙,也是一个很好的规则转发工具。我们可以对iptables进行如下配置来转发我们的请求。

1
2
3
4
PHY_IFACE=ens5; ZT_IFACE=ztxxxxxx #把两个都换成自己的接口名字
sudo iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE
sudo iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT

在Windows主机上使用tracert命令可以看到我们的请求经过转发到达了局域网内的目标机器。

1
2
3
4
5
6
7
8
9
tracert 192.168.31.8
<< EOF
通过最多 30 个跃点跟踪到 192.168.31.8 的路由

1 * 55 ms 55 ms 172.30.1.1
2 47 ms 45 ms 52 ms 192.168.31.8

跟踪完成。
EOF

但是iptables的规则重启之后就会重置,因此我们使用iptables-persistent工具对iptables进行持久化。

1
2
sudo apt install iptables-persistent
sudo netfilter-persistent save

现在,Linux的客户端就可以在提供服务的同时顺便为我们转发到达192.168.31.*的请求了。到此,整个192.168.31.*网段就与你的客户端连接起来了。

Author: Links
Link: http://blog.taiho.cc/post/Zerotier/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.