mihomo TUN 下 tcping 全是 0ms:一次假延迟的排查与绕法
mihomo TUN 下 tcping 全是 0ms:一次假延迟的排查与绕法
2026 年 11 月 6 日,我在一台江苏本地 Ubuntu 机器上给 Cloudflare 优选 IP 测延迟,tcping 测出来的结果全是 0ms——几百个 IP,清一色 0ms。第一反应是网络好到离谱,第二反应才是:这数据是假的。
现象
- 机器:Ubuntu 26.04.1 LTS,内网 172.21.3.249,跑着 mihomo TUN 模式(虚拟网卡 Meta,接管全部出站 TCP)。
- 测延迟用的 tcping(443 端口,10 次取中位数),对 1200 多个候选 IP 的结果几乎全是 0ms。
- 对照:同一台机器上
ping 223.5.5.5是正常的十几毫秒,说明物理出口本身没问题。
原因
mihomo 的 TUN 模式在系统里建了一张虚拟网卡并接管了默认路由。TCP 连接发起时,TUN 驱动在本地就把 SYN 接下来、立即回 ACK——对发起测量的程序来说,连接"建立"了,但这只是到本地 TUN 设备的握手,真实报文还没出网卡,更没到目标 IP。
所以 tcping 量的不是"到目标 IP 的延迟",而是"到本机虚拟网卡的延迟",自然全是 0ms。UDP 的 DNS 也一样会被 fake-ip 劫持,这台机器上直连 8.8.8.8 的 DNS 是超时的——不是网断了,是 TUN 把解析接管了。
判断方法很简单:如果一批地理位置、运营商各不相同的 IP 测出来延迟全一样(尤其全是 0ms 或 1ms),先怀疑测量路径被本地代理接管,而不是怀疑网络。
绕法:按源地址绑定,强制走物理出口
不需要 root,也不用停 mihomo。Python 的 socket 在 connect() 之前先 bind() 到物理网卡的源地址,策略路由就会把这条连接送进主路由表、走真实出口:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("172.21.3.249", 0)) # 绑定物理网卡地址
s.settimeout(3)
s.connect((target_ip, 443)) # 再连目标,量到的才是真实延迟
验证结果:绑源地址后,223.5.5.5 测得 13ms,直连 8.8.8.8 超时(符合国内直连预期),1200 多个候选 IP 的延迟拉开到几十到几百毫秒,恢复正常分布。
两条经验
- 测延迟之前先确认测量路径:机器上跑着 TUN / 全局代理时,裸测的数字很可能量的是本地虚拟设备。先拿一个已知延迟的公共 IP(如 223.5.5.5)做对照,数字异常就先查路径。
- 绑源地址是最轻的绕法:不用改系统路由、不用停代理进程,一行
bind()就能让单条连接绕过 TUN,适合写进批量测量脚本里长期用。
小结
TUN 接管下的 0ms 不是网络快,是握手没出门。测延迟先验路径,再谈排名。
- 点赞
- 收藏
- 关注作者
评论(0)