初期准备
- 首先将需要作为内部跳板的局域网机器加入ZeroTier网络中,这一步网上的教程比较多,不多做赘述
- 根据下面这个简单的脚本查询当前机器对应的默认网络
CIDR
信息1# 提取默认路由的接口名称
BASH这里为了做示范,假设输出的内容为
iface=$(route | grep default | awk '{print $8}')
# 使用接口名称获取默认网关
gateway=$(ip route show default | grep -oP "default via \K\S+")
# 使用相同接口获取子网掩码
netmask=$(ip -o -f inet addr show $iface | awk '{print $4}' | sed 's/.*\///')
# 输出默认网关和子网掩码
echo "${gateway}/${netmask}"192.168.1.1/24
,机器在ZeroTier
子网对应的IP为10.242.231.123
- 将输出的默认网关填入
ZeroTier
控制台的Manage Routes
处。其中Destination
填入我们上面查询到的192.168.1.1/24
,Via
填入机器对应的网关IP:10.242.231.123
在这里设置之后,ZeroTier子网下其他设备就会将192.168.1.x
网段的请求都转发给10.242.231.123
。因此如果有多个物理局域网需要转发,最好确定彼此之间的网段不会冲突
设置转发
在初期准备完成之后,会发现此时如果想从虚拟局域网的其他设备直接通过192.168.1.x
的网段访问内网其他设备,是无法成功通信的。这是因为默认的Linux
发行版一般都会禁用路由转发的功能来确保安全。因此还需要我们给当前系统启用路由转发
- 开启
sysctl
的路由转发1sudo sysctl -w net.ipv4.ip_forward=1
但是在完成了上面的步骤以后,也会发现只有跳板机本身的192.168.1.x
可以访问,局域网内其他设备不一定能直接访问。这个时候就还需要我们对防火墙的规则进行修改,放行ZeroTier
的网络请求
对于这一步,根据官方的文档,理论上直接执行下面的步骤就能成功
Configure iptables
Assign some shell variables (personalize these)
1 PHY_IFACE=eth0; ZT_IFACE=zt7nnig26
BASHAdd rules to iptables
1 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
BASHSave iptables rules for next boot
1 sudo apt install iptables-persistent sudo bash -c iptables-save > /etc/iptables/rules.v4
BASH
但是在实践的过程中,发现在物理机刚启动的时候,ZeroTier
的网卡并不会立马被添加到系统当中。因此写了一个开机自启动的轮训脚本,在监测到网卡正确加载之后,再对接口进行修改放行
- 在
/etc/systemd/system
下创建服务zerotier-nat.service
1[Unit]
Description=Setup IP forwarding and iptables rules for ZeroTier
Wants=zerotier-one.service
After=zerotier-one.service network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/enable-zerotier-nat.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target - 创建文件
/usr/local/bin/enable-zerotier-nat.sh
,写入下列内容1#!/bin/bash
# Enable IP forwarding
sysctl -w net.ipv4.ip_forward=1
# Get the interface with the default route (assumed to be PHY_IFACE)
PHY_IFACE=$(ip route | grep default | awk '{print $5}')
echo "Physical interface detected: $PHY_IFACE"
# Initialize attempt counter
attempt=0
# Try to find the ZeroTier interface, retry up to 10 times every 5 seconds
while [ $attempt -lt 10 ]; do
ZT_IFACE=$(ip link show | grep -o 'zt[a-zA-Z0-9]*')
if [ ! -z "$ZT_IFACE" ]; then
echo "ZeroTier interface detected: $ZT_IFACE"
break
else
echo "ZeroTier interface not found, retrying in 5 seconds..."
sleep 5
((attempt++))
fi
done
# Check if ZT_IFACE was found
if [ -z "$ZT_IFACE" ]; then
echo "Failed to find ZeroTier interface after 10 attempts."
exit 1
fi
# Set up NAT
iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE
# Set up IP forwarding rules
iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT - 为刚刚编辑的脚本添加可执行权限,并设置脚本的开机自启动
chmod +x /usr/local/bin/enable-zerotier-nat.sh
systemctl enable --now zerotier-nat
经过上面的操作之后,理论上就完成了,可以在ZeroTier
其他设备上直接访问192.168.1.x
的家庭内网设备啦