VPN 开启后 localhost 不可用:名字、代理还是绑定?
当搜索后缀或代理接管时,localhost 不再指你的机器。先修名字,再修路由,最后修工具的连接串。
一分钟前开发服务器还能应答,现在隧道一开,请求却以一个你从没输入过的主机名超时。几乎所有情况都由两种机制解释,而从外面看它们一模一样。搜索后缀把短名字变成企业域名,代理则把回环流量送到根本到不了它的主机。把两者分开只需一次查询,还能省下你正要写的防火墙规则。
当 localhost 解析进企业域
在隧道开启时查看这个名字解析到哪里,然后关掉隧道跑同一条查询,比较两个结果。线索是:你期待 127.0.0.1 的地方,却出现了企业网段的地址。一旦客户端把这个后缀加进搜索列表,像 localhost.mycompany.corp 这样的记录就会盖过回环条目,请求便流向那台该端口上无人监听的私有主机。搜索列表要读,不要猜,因为客户端可以加不止一个域,而顺序决定先试哪个候选:
getent hosts localhost
resolvectl domain
ss -ltnp | grep 8080
把应用、数据库客户端或笔记本地址中的主机名换成字面地址,再重试一次。故障消失,说明是命名问题,隧道只是触发器。故障依旧,下一个嫌疑就是监听方或路由,名字只是条假线索。
会截获回环流量的代理设置
隧道升起时生效的系统代理会接下发往 127.0.0.1 的请求,转给一台完全不懂你意图的远端代理。绕过列表为空,本地请求就变成了远端请求,而报错信息很少说明这点。把回环地址加进绕过列表时要覆盖整个会话,而不是单条命令,然后确认工具真的照做,再对网络下结论。
应用框架会读自己的环境变量,有时还读自己的配置文件,所以对一个工具有效的例外,对下一个什么也证明不了。浏览器还多一层:基于 Chromium 的浏览器对回环默认隐式绕过代理,而某个绕过标记可能取消这一行为。要查实际的代理判定,别假定操作系统设置就是全部。从 shell 启动的任何东西,两条命令就能定论:
curl --noproxy '*' http://127.0.0.1:8080/health
NO_PROXY=localhost,127.0.0.1,::1 your-tool
绑定地址决定谁能连上
在 127.0.0.1 上启动的服务器只接受本机连接,这通常是开发场景正确的默认值。在 0.0.0.0 上启动的服务器会在包括 VPN 适配器在内的所有接口上应答,暴露面比多数人以为的大。字面回环地址失败时,先查绑定,再查别的。
看监听套接字,记下它绑定在哪个地址,而不只是端口。如果另一台设备或容器要经隧道访问服务,就绑定到它将使用的那块具体接口,并有意识地放行该端口。如果只有你自己的机器需要,就保持精确绑定,修客户端而不是放宽服务器。端口转发或一层隧道能把两边接起来,但每加一层就多一个日后需要单独调试的部件。
调试工具期待局域网的地方
调试工具带着隧道会悄悄打破的假设。手机调试桥在 VPN 抓到设备子网后会丢设备,所以改用局域网地址或数据线重连就能避开冲突。浏览器自动化中枢在只能经代理访问、或本地防火墙丢掉控制端口时会超时。远程调试器可能在客户端改写路由的地方要求提权和回环地址。
把控制端口和数据端口分开识别,因为往往一个还活着,另一个已经没了。再判断修复该落在工具配置、该子网的路由,还是 拆分隧道规则。在每台开发机上改 hosts 文件扩展性最差,也最先被忘掉。优先选跟着配置文件走、且拥有隧道的人能复核的设置。
在第一个失败的环节停手
按三步往下走:解析名字,向字面地址打开套接字,再让工具自己建立连接。每步排除一层,所以第一个失败就点出了要修的那层,后面的都不用测。动任何东西之前先把结果写下来,因为测量前打上的补丁与运气无法区分。第一次失败、重试却成功,说明工具启动时隧道大概还没就绪。
把固定等待换成有上限的就绪检查,等路由就位;把失败的那一步留在日志里,让下一个人看到它停在哪。能自愈的工具并没有修好,它只是运气好,而运气会在别人的机器上耗尽。隧道放到最后改,而且只为真正失败的那一步改。这个顺序也是回到可用构建的最短路径,因为它不让你重做一个根本没参与的部件。