Surge Tailscale 引擎重写:从实验性库到自研实现

Surge 最新 TestFlight 版本发布了一项重要更新:Tailscale 集成从官方实验性 Rust 库 tailscale-rs 全面切换为自研实现,直接内嵌在 Surge 的网络引擎中。这次升级的意义超出技术栈替换本身,它揭示了依赖实验性上游库时,生产级软件需要面对的现实抉择。

Surge Tailscale 引擎重写:从实验性库到自研实现

tailscale-rs:官方自己标注了"实验性"

Tailscale 官方在 GitHub 上维护着 tailscale-rs 项目,定位很明确:实验性 Rust 库。仓库 README 的第一句话就是警告:

"Please do not build production software using these libraries or rely on it for data privacy."

使用时必须设置环境变量 TS_RS_EXPERAL=this_is_unstable_software 才能编译。这种命名方式本身就在传递信号——连 Tailscale 自己都不建议在生产环境使用它。

更有说服力的是 tailscale-rs 的功能缺失清单。以下功能在官方 Go 客户端中是标配,但在 tailscale-rs 中明确标注为"不支持":

网络层

  • Peer relays(对等中继)
  • Exit Nodes(出口节点,无论作为提供方还是使用方)
  • MagicDNS
  • Private DERP relays(私有中继)
  • Split DNS
  • Subnet Routers(子网路由器)

平台支持

  • Android、iOS、BSDs 全不支持,仅覆盖 Linux/macOS/Windows

可观测性

  • Client Metrics、Endpoint Collection、Log Streaming、Network Flow Logs 全部缺失

对普通应用来说,这些缺失或许可以容忍。但对 Surge 这样的网络代理工具,直连(NAT traversal)、Exit Node、MagicDNS 恰好是 Tailscale 集成最核心的价值点。tailscale-rs 唯一支持的通信方式是公共 DERP 中继——所有流量都要经过中转服务器,延迟高、带宽受限,P2P 直连完全不可用。

自研实现补齐了什么

Surge 的自研 Tailscale 引擎直接内嵌在 Surge 的网络引擎中,逐一补齐了 tailscale-rs 的功能缺口。

P2P 直连与 NAT 穿透

新实现支持完整的对等直连,包括 NAT traversal 和路径发现(path discovery)。Surge 会自动优先使用直连路径,仅在直连不可用时回退到 DERP 中继。同时提供了 derp-only 选项,可以强制所有对等流量走中继——在某些网络环境下有安全合规价值。

单线程 1.5 Gbps 吞吐

Surge 团队在实验室环境下测试,新实现的单线程数据面吞吐量达到约 1.5 Gbps,与官方 Tailscale 客户端在同等测试条件下表现相当。这个数据放在 tailscale-rs 只能走 DERP 中继的背景下,差距尤为明显。

Exit Node 作为出站策略

Tailscale 的 Exit Node 功能现在可以作为 Surge 的一个常规出站策略(outbound policy)使用。Surge 根据自己的规则体系将特定流量分配给 Tailscale 策略,这些流量再通过配置的 Exit Node 转发。关键在于:这只影响 Surge 规则匹配到的流量,不会改变设备级的默认路由。

这种设计与 Surge 的整体架构一致——Tailscale 在这里作为策略层接入 Surge 的网络引擎,可以和规则、策略组、手动选择等机制组合使用。

子网路由器与 MagicDNS

授权的 Tailscale 子网路由器广播的路由现在可以被 Surge 识别和使用。MagicDNS 也得到了更完整的支持,可以直接通过 Tailscale 名称解析和连接对等节点。

Tailscale 感知的延迟测试

Surge 为 Tailscale 策略设计了专门的延迟测试逻辑:

  • 未配置 Exit Node 时,Surge 会对在线的 Tailscale 对等节点执行原生连接探测。没有合适的对等节点时,测试 home DERP 服务器作为替代。
  • 配置了 Exit Node 或 test-url 时,使用标准的 HTTP 测试流程。
  • 额外预留了控制面初始化和 WireGuard 握手的时间,避免因启动延迟误判节点不可用。

运行时诊断

Surge 在 UI 中加入了大量 Tailscale 运行时诊断信息:控制连接状态、分配地址、Exit Node 状态、DERP 区域、直连与中继的路径对比、对等节点延迟、活跃连接、端点信息、MagicDNS 信息。这些诊断维度在 tailscale-rs 的可观测性缺失列表中几乎全部被列为"不支持"。

兼容性与迁移

Surge 官方确认,现有的 Tailscale profile 和持久化的节点身份保持兼容,不需要 profile 迁移。但由于核心引擎的替换,Tailscale 需要重新注册。如果之前没有启用 auth key 的 reuse 选项,需要生成新的 auth key 完成新设备注册流程。

为什么不基于 tailscale-rs 改进

一个自然的疑问:Surge 为什么不直接给 tailscale-rs 贡献代码,补齐缺失功能?

tailscale-rs 的架构决定了这不是补充几个功能模块就能解决的问题。NAT traversal、Disco 协议、WireGuard 集成、控制面通信——这些是 Tailscale 客户端的核心网络栈,tailscale-rs 作为从零开始的 Rust 重写,在这些基础能力上几乎空白。将 Tailscale 深度集成到 Surge 现有的网络引擎中,在工程可控性上反而更有优势——Surge 已经有一套成熟的网络引擎,Tailscale 的功能可以作为引擎的一个策略层接入,不需要从底层重建网络栈。

从 Tailscale 官方的角度看,tailscale-rs 仍处于早期阶段。官方在博客中提到,选择 Rust 是为了给 Go 之外的语言生态提供 Tailscale 库,但明确表示这是"preview"级别的发布。Tailscale 的核心团队精力仍集中在 Go 客户端,tailscale-rs 的开发优先级和节奏无法满足 Surge 这种生产级产品的迭代需求。

未来路线

Surge 计划在后续版本中加入通过 WireGuard 和 Tailscale 的入站访问,允许远程设备连接到 Surge 并将其作为网络网关使用。这将进一步强化 Surge 作为网络中枢的定位——不只是出站代理,也是入站网关,Tailscale 网络中的设备可以把运行 Surge 的机器当作网络出口。

小结

Surge 这次 Tailscale 引擎重写的决策脉络清晰:当一个上游库的官方定位是"实验性"、核心功能大面积缺失、开发节奏不受自己控制时,自研是生产级软件的理性选择。新实现带来的 P2P 直连、1.5 Gbps 吞吐、Exit Node 策略、完整诊断,让 Tailscale 在 Surge 中的可用性上了一个台阶。

参考链接: