需求背景

在朋友疯狂安利下,搭建zerotier后,发现zerotier有个路由表功能,一个骚想法油然而生,那就是异地组网,可以访问设备算什么?我要能访问设备同一局域网下的全部,需求如下图。

既要使用zero内部IP(10.1.1.1)访问到该节点,又要访问到该节点真实的内网IP(192.168.2.1),还要能访问它真实内网IP下所有的设备以及该节点下任意设备可以访问其他节点以及节点子网,做到全异地组网,也就是企业常说的SD-WAN(软件定义网络)。而常规企业要依靠设备搭配网络来完成,而我属于乞丐版SD-WAN。

搭建过程

参考我的这篇文章《搭建zerotier实现异地设备统一管理》。

要解决的核心问题

众所周知,要解决跨网段通信,要解决的就是路由问题,zerotier本身提供路由表功能,也就是我们可以配置使得数据包可以到指定节点,这样的话,就可以让数据包达到指定节点,想办法让数据包再回来就行。比如我要访问图中出租房的台式机,我数据包(192.168.200.X)通过出租房节点(10.1.1.3)转发,那它怎么回包呢?因为局域网本身就没有其他子网的回程路由。所以,总结以下,节点所要解决的问题:

  • 路由功能(为了解决回程路由)

  • 开启NAT(目标子网设备可以访问任意节点或任意节点子网下设备,这点根据需求变化,如果节点设备是路由设备就不用配置)

所以核心就是要让节点的机器,能配置和实现动态路由和NAT。节点设备一般要分为路由设备(支持SSH)和非路由设备(Windows、Linux)。

配置过程(均建立在按照搭建过程搭建以后)

1、zerotier路由表设置

在服务端控制台点击路由

添加对应网段的路由,和配置路由设备的静态路由一样,目的网段和下一跳地址,下一跳地址就是对应节点的zerotier节点IP地址

2、节点设备配置

路由设备(OpenWrt为例)

打开OpenWrt控制页面,网络->接口 ,添加新接口

添加完成后编辑接口,防火墙,配置一个自定义的区域并保存应用。(独立区域流量,以免内网大量广播,例如DHCP啥的也广播到其他节点子网去,造成DHCP混乱、广播风暴等问题)

网络->防火墙,配置区域的规则,保存应用即可

非路由设备

Windows

计算机管理->服务 ,设置Routing and Remote Access服务为自动并启动该服务

打开网卡设置,右击zerotier虚拟网卡,点击状态,记录相关信息

找到本机上网网卡,右击属性,点击共享,选择zerotier的虚拟网卡,点击确定

此时,zerotier的网卡会自动桥接实体网卡,导致该网卡自动DHCP获取到本机所在内网IP,所以要右击该网卡属性,根据刚记录的相关信息,进行配置静态IP,点击确定进行保存

将ICS服务设置为自动,否则重启电脑后该网络的共享将失效

去服务里重启zerotier服务即可

群晖

修改/etc/sysctl.conf ,增加net.ipv4.ip_forward = 1 ,用于开启NAT,保存退出

重新加载该文件

sysctl -p

执行命令iptables -t nat -A POSTROUTING -o ovs_eth0 -j MASQUERADE ,其中ovs_eth0 ,请按照设备实际上网的网卡名称进行修改(为了设置防火墙规则让上网网卡走NAT)

设置计划任务,保证其开机就可以自动设置防火墙规则(这里有个坑,如果设置为开机就执行这行命令,可能存在找不到模块的情况,所以,要等待个一分钟,使其加载完所有网络模块)

记得要使用root权限,触发时机选择开机

CeontOS

修改/etc/sysctl.conf ,增加net.ipv4.ip_forward = 1 ,用于开启NAT,保存退出

重新加载该文件

sysctl -p

执行命令iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE ,其中ens33 ,请按照设备实际上网的网卡名称进行修改(为了设置防火墙规则让上网网卡走NAT)

vim /etc/rc.d/rc.local

配置开机自动添加iptables规则

chmod +x /etc/rc.d/rc.local
systemctl enable rc-local.service

注意事项

  • 如果节点为非路由设备,那么该子网下的设备必须要手动配置网关该节点设备所在内网IP才可以访问所有节点子网。(因为只有该设备有节点路由表)

测试连通性

找到任意一台连接路由器网络的设备测试到其他节点子网的路由,大功告成!!

玩法🏄‍♀️

  • 管理多局域网设备,例如群晖的共享文件夹,就可以和本地一样使用,还不会影响外网质量。

  • 多出口,可以删除本机或者出口路由的默认路由,修改为某节点,这样就可以达到切换出口的效果。(待实验)

  • 本地对象存储的外部使用。(已完成)