一觉醒来,突然发现家里的 OpenWRT 软路由无法通过 Zerotier 网络访问了,虽然面板上显示设备在线,但不管是 Ping 还是 curl ,都会报错:No route to host。
09:54:21.055775 [0-0] * [HTTPS-CONNECT] adjust_pollset -> 1 socks
09:54:22.048545 [0-0] * [HTTPS-CONNECT] connect, check h21
09:54:22.049187 [0-0] * connect to 192.168.100.22 port 443 from 10.1.1.111 port 59496 failed: No route to host
首先,我们需要判断这个问题是否能在 Zerotier 网络中其他节点复现,通过登录不同节点执行 ping 跟 curl,发现只有 OpenWRT 在 Zerotier 网络中不可达。
接下来登录 OpenWRT 上查看 Zerotier 客户端的状态:
$ zerotier-cli info -j
{
"address": "....",
"clock": 1748052290108,
"config": {
"settings": {
"allowTcpFallbackRelay": true,
"forceTcpRelay": false,
"homeDir": "/var/lib/zerotier-one",
"listeningOn": [
"192.168.100.1/9993",
"192.168.1.2/9993"
],
"portMappingEnabled": true,
"primaryPort": 9993,
"secondaryPort": 44537,
"softwareUpdate": "disable",
"softwareUpdateChannel": "release",
"surfaceAddresses": [
"家宽公网 IP"
],
"tertiaryPort": 44486
}
},
"online": true,
"planetWorldId": 149604618,
"planetWorldTimestamp": 1738848951118,
"publicIdentity": "....",
"tcpFallbackActive": false,
"version": "1.14.1",
"versionBuild": 0,
"versionMajor": 1,
"versionMinor": 14,
"versionRev": 1
}
$ zerotier-cli peers
200 peers
<ztaddr> <ver> <role> <lat> <link> <lastTX> <lastRX> <path>
778cde7190 - PLANET 225 DIRECT 44578 134480 103.195.103.66/9993
cafe04eba9 - PLANET 318 DIRECT 44578 134387 84.17.53.155/9993
cafe80ed74 - PLANET 165 DIRECT 4519 129532 185.152.67.145/9993
cafefd6717 - PLANET 263 DIRECT 44578 129434 79.127.159.187/9993
可以看到 OpenWRT 上的客户端并没有显示任何异常信息,这也对应了控制面板上看到的设备在线状态。但值得注意的是,在 surfaceAddresses
字段上显示的是我的家庭宽带公网出口地址,这也对应了控制面板上显示的该设备的物理地址。考虑到 Zerotier 可能已经被中国联通给 Ban 了,所以接下来可以尝试让 Zerotier 客户端通过代理连接 Planet。
这时,有意思的事情出现了,尽管我在代理软件中正确地设置了 Zerotier 的协议转发规则(转发目标端口为 9993 的 TCP/UDP 流量),但我在代理软件的日志中却无法查看到 Zerotier 相关的流量信息。
我的规则设置有误还是代理软件在这个场景下存在 Bug ?这可以通过一个实验来验证,使用 ncat -vuz 84.17.53.155 9993
就可以向 Zerotier 的 Planet 发送一个用来测试连接性的 UDP 包。
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 84.17.53.155:9993.
Ncat: UDP packet sent successfully
Ncat: 1 bytes sent, 0 bytes received in 2.00 seconds.
可以看到这个 UDP 包被成功发送了,而且在代理软件的日志中也能找到相关的转发记录。这说明我的代理软件规则配置是正确的,而且代理软件也没有任何问题。那为什么在代理软件的日志中看不到 Zerotier 的流量呢,难道 Zerotier 客户端压根没有去连接 Planet ?这就需要使用 Wireshark 来分析 OpenWRT 的流量了。
# on my laptop
$ ssh openwrt 'tcpdump -s 0 -U -n -w - -i eth0' | sudo wireshark -k -i -<br>
通过分析 OpenWRT 各个网络设备上的流量,可以发现 Zerotier 的 UDP 包确实被发送了,但它是通过 OpenWRT 的 WAN 地址发送的,而我的代理软件只会通过 nft 拦截来自 localhost 跟 LAN 的流量,这就解释了为什么代理软件无法转发 Zerotier 的流量。
确实,在网络编程中,当机器被绑定了多个 IP 地址时,我们可以指定某个特定的 IP 作为源 IP,对于 VPN 软件 Zerotier 来说,这样做更是基操。所以,在 Zerotier 的配置文件中肯定存在某个配置项,用来设置 Zerotier 流量的出口网络。
通过翻阅它的文档,可以看到有两个选项会影响 Zerotier 流量的发送地址:
{
"settings": {
"interfacePrefixBlacklist": [ "XXX",... ], /* Array of interface name prefixes (e.g. eth for eth#) to blacklist for ZT traffic */
"bind": [ "ip",... ], /* If present and non-null, bind to these IPs instead of to each interface (wildcard IP allowed) */
}
}
在我的测试下,需要指定 bind
为 LAN 地址,才能真正解决这个问题。这样设置后,Zerotier 就会通过代理服务跟 Planet 沟通,在管理面板上,OpenWRT 的物理地址也会被展示成代理服务的 IP。
实测下来,从外网访问 OpenWRT 的速度还是能达到家庭宽带的上限,网络延迟也还不错,问题终于解决了~
发表回复