📌 项目地址:tailscale/tailcat | ⭐ 2,502 颗星 | 🔧 Go | 📜 未标注

tailscale/tailcat,Go 写的,2502 颗星。官方一句话介绍:”Tailscale without Tailscale, by Tailscale”——把 Tailscale 的数据平面单独抽出来,控制平面整个不要。

它在什么位置

两台都在 NAT 后面的机器想互传数据,可选方案不多:SSH 隧道要求一端公网可达,netcat 不加密也打不了洞,装完整的 Tailscale 又要注册账号、改路由表、动 DNS。

tailcat 只保留 Tailscale 内部叫 magicsock 的那部分:WireGuard 端到端加密的点对点隧道,DERP 做打洞信令通道,打洞失败时 DERP 降级为中继。原本由控制平面负责的连接元数据交换,改成你自己带外传递——复制粘贴一个 token。

结果就是:

  • 不需要 Tailscale 账号
  • 不需要 root/管理员权限,纯用户态,不改路由表和 DNS
  • 连接先经 DERP 引导,能打洞就升级成直连 UDP(官方的说法是”通常能成功”)

用法

安装只有两条路:

$ go install github.com/tailscale/tailcat/cmd/tailcat@latest

或 Nix:

$ nix run github:tailscale/tailcat
$ nix profile install github:tailscale/tailcat

机器间管道传输

服务端裸跑,打印一个临时地址后挂起:

$ tailcat
# Selected bootstrap relay region 302, San Francisco
# 🐈 Server listening with new address: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
(hangs, waiting...)

把地址发给对方,客户端:

$ echo hello | tailcat tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu

服务端立刻解阻,输出 hello。行为对齐 netcat,stdin/stdout 接什么都行。

端口转发

README 还展示了 --s 参数,把本地 TCP 端口通过隧道暴露、转发到 localhost。README 在这个示例处截断了,完整参数我建议装好后跑一下帮助命令确认。

浏览器 Demo

官方有个编译成 WebAssembly 的实验性在线版:https://tailscale.github.io/tailcat/ ,能在浏览器里收发文件和文本,和 CLI 互操作。限制:浏览器端只走 DERP 中继,没有直连,WebRTC 支持还挂在 Issue #4。

当库用

tailcat 同时是个可导入的 Go 库(github.com/tailscale/tailcat,pkg.go.dev 有文档)。一侧起 server 拿 token,另一侧拿 token 连接,流程和 CLI 一致。把这个隧道嵌进自己的程序里,我觉得这比命令行工具本身更有意思——毕竟自带 NAT 穿透和加密的点对点传输,自己从零写很难写对。

需要注意的地方

DERP 是硬依赖。默认用官方免费限速的 DERP 中继(默认 DERP map 在 https://tailcat.dev/derpmap.json ),连接引导必须经过它,哪怕最后能直连。介意的话可以自建 DERP,官方文档指向 tailscale 仓库的 cmd/derper。

token 即凭证。token 泄露等于隧道泄露,传递别走不可信渠道。

没有持久网络。每次连接都要重新交换 token,没有常驻的虚拟网络。这是设计取舍,它替代不了 Tailscale 本体的组网场景,定位就是临时连接。

小结

作为工具,它是“临时给对方传个文件、暴露个端口”场景里最省事的方案之一,双方各跑一条命令。作为代码,magicsock 和 NAT 穿透的实现长期藏在 tailscale 主仓库里,现在被剥离成一个独立可读的库,想学这块的人机会不多。

这篇文章对你有帮助吗?

发表回复