已连接、托盘图标是绿的,而回显地址的页面仍然显示服务商的地址,这并不自动意味着故障。客户端做的是两件彼此独立的事:建立隧道,以及修改路由表。两件事可以只发生一件,而分流路由正是刻意跳过第二件的那种配置。

客户端究竟装上了什么

别问隧道是否已启动,而要问哪个接口会把数据包送到真实目的地。没有通往该目的地的路由,隧道就是一条无人使用的私人道路。

ip route get 9.9.9.9
Find-NetRoute -RemoteIPAddress 9.9.9.9
route print -4

第一条命令在 Linux 和 macOS 上有效,另外两条是 Windows 的等价写法,其中一个就够。如果答案指向物理网卡,说明隧道已启动、默认路由从未移动。对应当走隧道的目标重复一次查询,因为一次远端、一次普通的两次查询,才能说明部署的是哪种设计。

分流路由的三种形态

全局隧道配置通常会写一条指向该接口的默认路由,或者写一对半区前缀,让它们在最长前缀匹配中胜出,而原来的默认路由仍留在表里。分流路由是另一种选择,它有多种形式。有的配置只给 RDP 服务器这样的单个主机做路由,有的把必须从特定位置访问的公网网段做路由,还有的刻意把一个应用排除在外。三种都合理,而且都不会改变普通网站看到的地址。

grep -nE "redirect-gateway|route-nopull|route " /etc/openvpn/client/*.conf
ip route show table main | head -20

先读配置里做决定的那条指令,再读路由表看它实际生成了什么。下发的指令也可能在客户端被抑制,所以在怪服务器之前,配置和路由表必须先对得上。

远端必须改写源地址

还有第二种故障,从浏览器看完全一样。路由把包送进隧道,服务器收到包后又带着客户端私有地址原样转发出去。下一跳没有回程路径,于是回应消失、页面卡住。服务器必须真的转发,并且必须把源地址转换成互联网能路由回来的地址。

sysctl net.ipv4.ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -S | grep MASQUERADE

请写明真正面向互联网的那个接口,在现代发行版上它并不总是 eth0。固定地址的托管服务器可以显式转换成那个地址,而不必使用 masquerade。两半都重要:只转发不转换会泄漏无法路由的源地址,只转换不转发则根本看不到数据包。

域名解析走它自己的路

流量可以从隧道出去,而负责查出域名的查询却发往了本地网络里的解析器。看到的地址没变,查询路径变了,而这个缺口正是分离式 DNS 设计所选择的。

resolvectl status | head -20
resolvectl query example.org

记下是哪个服务器作答,以及它是否与隧道建立前的基线不同。在分流隧道里,这通常就是人们抱怨地址时想改、却从来没看过的那个设置。

四个观察定案

在隧道关闭时记录出口地址,再在开启时记录一次。在两种状态下都运行目标查询,并每次记下接口。

curl -sS https://ifconfig.me/ip
ip route get 9.9.9.9

当查询落在隧道内、而回显仍报出服务商地址时,说明出口缺少转换。当查询落在物理网卡上时,配置是分流的,公网地址从来不在范围内。换一个你信任的回显服务,并把四个观察记在一起,因为分开看它们只是轶事。合在一起,才能说明客户端实际完成的是两件事中的哪一件。

相关文章