使用 ZeroTier 单向打通家庭局域网

随着家里的服务和设备越来越多,在外访问家里的需求也是越来越大。

但是家庭带宽不让提供 Web 服务,有些服务也不适合放在公网上。

正好我 ZeroTier 使用也很久了,考虑再三,还是决定和家里的局域网打通。

为了偷懒,这里就单向打通了,反正需求基本也是单向的。

注意,以下 IP 均为我目前使用,每个人的实际情况不同请自行按情况更改。

图片 Pixiv ID = 92080599

2022.12.07 更新:新增 systemd 方式固化配置,以及另一种中转网关配置。

2022.12.06 更新:固化 iptables 配置。

ZeroTier 控制中心

ZeroTier 的基本使用就不赘述了,这里需要选出一台设备来作为中转的网关。

个人这里选了家庭服务器作为中转网关,分配给的虚拟局域网 IP 为 192.168.17.3

家里本身局域网的网段为 192.168.7.0/24,那么需要在 ZeroTier 控制中心新加一段路由配置,类似下图:

配置网段

这样当路由配置分发到终端设备后,访问 192.168.7.0/24 段就会知道去找网关 192.168.17.3 让它来帮忙处理。

中转网关

但是网关很懵,它咋知道它要干啥?

所以这里还得配置一下中转网关,让它知道怎么把虚拟局域网的请求送到正确的位置。

<2022.12.07 更新>

在互联网上找到一种新的配置方式,需要启用 IP 转发功能:

1
2
sysctl -w net.ipv4.ip_forward=1
sysctl -p

然后查看机器上的物理网卡和 ZeroTier 所使用的网卡:

1
ip addr

两块网卡

设置环境变量:

1
PHY_IFACE=enp2s0; ZT_IFACE=zt2lrupt2o

依次输入以下命令:

1
iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE
1
iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
1
iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT

下文为原方法

使用 ip a | grep 192.168.17.3 取一下 ZeroTier 所使用的网卡,个人这里为 zt2lrupt2o

接下来依次输入以下命令就搞定了。

1
iptables -I FORWARD -i zt2lrupt2o -j ACCEPT
1
iptables -I FORWARD -o zt2lrupt2o -j ACCEPT
1
iptables -t nat -I POSTROUTING -o zt2lrupt2o -j MASQUERADE
1
iptables -A FORWARD -d 192.168.7.0/24 -j ACCEPT
1
iptables -t nat -A POSTROUTING -s 192.168.7.0/24 -j MASQUERADE
1
iptables -t nat -A POSTROUTING -d 192.168.7.0/24 -j MASQUERADE
1
iptables -A FORWARD -s 192.168.17.0/24 -j ACCEPT

其中 192.168.7.0/24 为家庭真实局域网网段,192.168.17.0/24 为虚拟局域网网段。

这时候网络就打通啦,虚拟局域网上的终端设备可以自由访问到家庭局域网的服务了。

个人需求单向打通已经足够了,如果需要双向打通,那么在家庭局域网的网关上进行类似的配置即可。

<2022.12.07 更新>

昨天固化的方式在家里的 Debian 可以正常运作,但是公司的 Ubuntu 怎么都不行。

折腾一上午无果,在朋友的建议下,直接祭出大杀器 systemd!

1
vim /usr/lib/systemd/system/iptables-restore.service
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Restore iptables firewall rules
Before=iptables-store.service
Before=network.target
Conflicts=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/iptables-restore /root/iptables

[Install]
WantedBy=basic.target
1
2
3
systemctl daemon-reload
systemctl enable iptables-restore.service
systemctl start iptables-restore

<2022.12.06 更新>

这些配置在设备重启后会被重置,如果不想每次都启动后都重新配置,我们需要固化配置。

方法很简单,使用 iptables-save 保存规则到文件,然后开启后使用 iptables-restore 导入文件中的规则 。

新建一个脚本并赋予权限:

1
2
touch /etc/network/if-pre-up.d/iptables
chmod +x /etc/network/if-pre-up.d/iptables

然后编辑文件写入内容:

1
vim /etc/network/if-pre-up.d/iptables
1
2
#!/bin/sh 
/sbin/iptables-restore < /root/iptables

在上文 iptables 配置完成后,只需要将目前的配置保存到文件即可:

1
iptables-save > /root/iptables