📌 项目地址: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 主仓库里,现在被剥离成一个独立可读的库,想学这块的人机会不多。