太痛快了!恭喜你,终于亲手斩杀了这个折磨了你无数个日夜的“7秒幽灵”!

这绝对是一场教科书级别的硬核网络排障战役。从 DNS 污染到内核 IPv6 黑洞,从代理软件底层的 5 秒死锁再到最终的局域网非对称路由,我们几乎把透明代理架构里所有的天坑都踩了一遍。

为了让你能完美地记录在博客上,我为你整理了一份详尽的**《记一次 RouterOS 旁路由架构下 TLS 握手固定延迟 7 秒的终极排障指南》**。你可以直接复制使用!


记一次 RouterOS 旁路由架构下 TLS 握手固定延迟 7 秒的终极排障指南

📌 背景与架构说明

在折腾家庭网络透明代理时,我采用了目前极其主流且性能强悍的架构:

  • 主路由 (Gateway): RouterOS (ROS) - IP: 192.168.10.254

  • 旁路由 (TProxy): Debian 虚拟机运行 sing-box - IP: 192.168.10.253

  • 客户端: Rocky Linux / Windows 等 - IP: 192.168.10.x网段

  • 远端节点: VPS 运行 Xray (VLESS-Reality)

  • 分流逻辑: ROS 使用 Mangle 表,将非 CNIP 的海外流量打上 cross 标记,策略路由至 Debian 旁路由。

🚨 诡异的故障现象:精确的 7 秒延迟

在客户端使用 curl -Iv https://www.google.com 测试时,发现每次请求都会出现极其稳定的 7 秒左右延迟

通过 curl 的性能分析命令拆解耗时,发现了惊人的“错觉”:

Bash

curl -o /dev/null -s -w "TCP连接耗时: %{time_connect} 秒\nTLS握手耗时: %{time_appconnect} 秒\n" https://www.google.com
  • TCP 连接耗时: 0.02 秒 (极快,说明局域网畅通)

  • TLS 握手耗时: 6.85 秒 (极慢,卡死在这里)

  • 总耗时: 7.35 秒

直觉往往会让人去排查远端节点慢、线路丢包或者 DNS 慢,但在这套复杂的透明代理架构下,TLS 耗时高只是一个表象,真正的凶手往往藏在底层的网络协议栈中。

🕵️ 漫长而硬核的排障过程(避坑指南)

在最终破案前,我们进行了深度排查,排除了以下常见的“透明代理天坑”,这些经验同样值得记录:

  1. 排除 GFW DNS 污染与本地死锁

    • 客户端拿到了 Facebook 的被墙 IP (31.13.x.x),这是正常的,因为 sing-box 开启了 sniff: true,会通过 SNI 提取真实域名并在远端解析。

    • 避坑: 确保旁路由代理配置中没有多余的 ip_is_private 等需要本地反查 IP 的规则,否则会触发代理引擎内部的 DNS 5秒死锁。

  2. 排除 VPS 端 IPv6 与 WARP 黑洞

    • 通过 VPS 端的 tcpdump 发现,Xray 拿到了 Google 的 IPv6 地址并尝试连接。如果 VPS 的 IPv6 路由不通或配置了死掉的 WARP 虚拟网卡,会导致 TCP SYN 握手包被静默丢弃 (DROP)。

    • 根据 Linux 内核 TCP 重传机制 (1秒+2秒+4秒=7秒),这会完美制造 7 秒延迟。

    • 操作: 在 VPS 彻底禁用 IPv6 (sysctl -w net.ipv6.conf.all.disable_ipv6=1),并强制 Xray 出站规则使用 "domainStrategy": "UseIPv4"

  3. 排除 MTU (PMTUD) 丢包

    • 怀疑 Google 下发的巨型 TLS 证书包超过了 PPPoE 宽带的 1492 MTU,导致丢包重传。测试将 VPS 和旁路由的 MTU 降至 1360,故障依旧。
  4. 排除 Xray 内部 DNS 解析超时

    • 发现 Xray 配置文件中 DNS 设置为 localhost,导致其向无 IPv6 能力的宿主机发起 AAAA 查询,触发 Go 语言底层的 5.0 秒硬性超时。修改为 8.8.8.8 后故障依旧。

💡 破局之战:SOCKS5 绕过测试

当外部环境被彻底清洗干净后,我们采用了**“终极二分法”**。

在旁路由的 sing-box 开启 SOCKS5 端口 (1080),然后在客户端强制走 SOCKS5 代理:

Bash

time curl -x socks5h://192.168.10.253:1080 -Iv https://www.google.com

结果:real 0m0.616s (瞬间秒开!)

这个测试一锤定音:VPS 是完美的,国际链路是完美的。这 7 秒的真凶,100% 锁死在局域网的透明代理 (TProxy) 与主路由转发机制上!

💥 最终真相:致命的“三角路由” (Asymmetric Routing)

结合客户端、旁路由和主路由都在 同一个 /24 局域网网段 的拓扑结构,真相大白:

  1. SYN 出发:客户端 101 发送 TCP SYN 给主路由 254

  2. Mangle 转发:主路由 254 将包转发给旁路由 253,并在连接跟踪 (Conntrack) 记录:状态 SYN_SENT

  3. 抄近道回信:旁路由 253 收到后,回复 SYN-ACK。但由于旁路由发现客户端 101 就在同网段,于是不经过主路由,直接通过二层 MAC 地址把包发给了客户端

  4. 灾难降临:客户端收到 SYN-ACK,立刻发送 ACKTLS Client Hello 数据包给主路由 254

  5. 防火墙拦截:主路由 254 的防火墙一看,自己明明只记录了 SYN,根本没见过 SYN-ACK,判定这个 Client Hello非法状态连接 (Invalid),直接 DROP 丢弃

  6. 死等 7 秒:客户端包被吞,死等重传。直到 5 秒后主路由的 SYN_SENT 状态超时失效,客户端第 7 秒的重传包被当做新连接放行,这才最终连上网络。

🛠️ 终极解决方案:在 ROS 补全 NAT 伪装

要打破这种因为单臂路由“抄近道”导致的 TCP 状态阻断,必须让流量有去有回,全部经过主路由的防火墙

操作方法:

在 RouterOS 中增加一条 Source NAT (Masquerade) 规则,将发往旁路由的流量的源 IP,伪装成 ROS 自己的 IP。这样旁路由回信时,只能先发给 ROS,再由 ROS 转交给客户端,TCP 状态机完美闭环!

RouterOS 修复代码:

(注:br-lan 为内网网桥接口,cross 为策略路由标记,请根据实际情况替换)

代码段

/ip firewall nat
add chain=srcnat action=masquerade out-interface=br-lan routing-mark=cross comment="Fix Bypass Asymmetric Routing"

规则生效后,再次执行 curl 测试,7 秒钟的噩梦彻底消失,网页秒开,丝滑无比!

📝 总结

在透明代理和单臂旁路由架构中,同网段内的非对称路由是极其容易被忽视的隐形杀手。任何看似毫无头绪的 TLS 握手卡顿、TCP 固定秒数延迟,首先应当通过 SOCKS5 等协议剥离透明网关进行对比测试,并时刻警惕底层的 TCP 状态机是否被防火墙阻断。