type
status
date
slug
summary
tags
category
icon
password
坐标上海。
作为一个对延迟有洁癖的人,我一直维护着一套基于 Tailscale 的异地组网。平时不论在外面哪里,连回宿舍的 iStoreOS(OpenWrt)都是 Direct 直连,延迟稳定在 25ms 上下。
但今天下午 SSH 突然卡得像是在敲摩斯密码。直觉告诉我,直连断了。

0x01 现象与初步排查

反手敲了一个 tailscale status,果然,最不想看到的一幕出现了:
这里简单解释一下 Tailscale 的两种状态:
  • Direct (直连):这是我们追求的终极形态。你的设备和目标设备之间建立了 P2P(点对点)隧道,流量不经过第三方中转,速度最快。
  • Relay (中继):当 P2P 打洞失败时,Tailscale 为了保证“至少能连上”,会强制把流量转发到官方的中继服务器(DERP Server)。我的流量本来只要在上海市内传输,现在却要先去一趟香港再回来,延迟飙升和丢包也就在所难免。
    • notion image

0x02 根因分析:谁在抢答?

既然变成了 Relay,说明 NAT 穿透失败了。我需要知道是防火墙的问题,还是 NAT 类型变了。
使用 Tailscale 自带的诊断工具 netcheck
终端吐出了一堆报告,其中最后一行引起了我的注意:
portmap: UPnP discovery response from 192.168.5.2, but gateway IP is 192.168.5.1
这一行日志直接暴露了内鬼。
技术背景:UPnP 的局限性
Tailscale 默认会利用 UPnP 协议向网关申请一个公网端口,以便外网能直接访问进来。
  • 我的主网关(光猫/主路由)是 192.168.5.1
  • 我的旁路网关(运行 Tailscale 的 iStoreOS)是 192.168.5.2
问题就出在这里:网关错位
当 Tailscale 发出广播喊“谁是网关?我要开端口”时,iStoreOS 里的 miniupnpd 服务抢答了:“我是网关,我给你开。”
结果就是:Tailscale 以为自己在公网上开了门,但真正把守公网出口的主路由 (.5.1) 对此一无所知。外网的 UDP 握手包打在主路由防火墙上,直接被丢弃。
notion image

0x03 陷入死锁 (Deadlock)

病因找到了:必须登录主路由 (192.168.5.1),手动添加 UDP 41641 的端口映射。
但我现在人在外面,面临一个经典的运维死锁
  1. 想恢复直连,必须进主路由后台配置。
  1. 想进主路由后台,必须依赖 Tailscale 的内网访问。
  1. Tailscale 现在是 Relay 模式,丢包严重,而现代路由器的后台页面(大量的 JS/CSS 资源)在这种链路下根本加载不出来。
我尝试了 SSH 隧道 (Local Port Forwarding)
虽然 TCP 握手通了,但因为路由器后台强制 HTTPS 重定向以及 Host 头校验机制,浏览器访问 localhost 直接报错。

0x04 降维打击:OOB 带外管理

当 VPN 通道(In-Band)失效时,我们需要一条带外管理通道 (Out-of-Band Management, OOB)
我想到了手头配置的 Cloudflare Tunnel
不同于 Tailscale 依赖 UDP 打洞,Cloudflare Tunnel 是由内网机器主动向 Cloudflare 边缘节点发起 HTTP/2 连接,穿透性极强,且走的是 CDN 线路,完全不受 Tailscale 拥堵的影响。
notion image
操作步骤:
  1. 登录 Cloudflare Zero Trust 控制台。
  1. 在 iStoreOS 的 Tunnel 里新增一条 Public Hostname:router.我的域名.com -> https://192.168.5.1
  1. 关键点: 在 TLS 设置中开启 No TLS Verify
      • 注:路由器的 HTTPS 证书通常是自签名的,不受信任。如果不开启这个选项,Cloudflare 会拒绝连接并报 502 Bad Gateway。
保存生效。我在浏览器输入域名,瞬间打开了之前死活加载不出来的路由器后台。

0x05 最终解决与验证

进入后台后,事情就简单了。
在“端口转发”里添加一条静态规则:
  • 协议:UDP
  • 外部端口:41641
  • 内部 IP:192.168.5.2
  • 内部端口:41641
保存的那一刻,我切回终端验证:
via 111.186.x.x —— 流量走了公网 IP。
26ms —— 熟悉的上海同城延迟回来了。

0x06 复盘

这次故障虽然简单,但涉及了网络排查的几个核心思路:
  1. 相信日志netcheck 的报错比任何猜测都准确。
  1. 不要迷信 UPnP:在多级路由或旁路网关环境下,UPnP 的协商极其不可靠。对于关键服务,Static NAT (静态端口映射) 才是王道。
  1. OOB 思维:永远不要只留一条路回家。当 Layer 3 的 VPN 挂掉时,Layer 7 的 Tunnel (如 Cloudflare) 往往能救命。
最后,记得把 Cloudflare 里的路由器映射删掉。把核心网络设备的管理后台暴露在公网(即使有鉴权)依然是安全大忌。
 
Notion 快捷键近纲复习
Loading...