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

📌 项目地址tailscale/tailcat | ⭐ 2,502 颗星 | 🔧 Go

“Tailscale without Tailscale, by Tailscale” —— 官方这句自我介绍把项目定位说得很清楚:把 Tailscale 的数据平面单独拆出来用,控制平面整个扔掉。

解决什么问题

两台都在 NAT 后面的机器想互传数据,传统做法要么架公网服务器中转,要么用 SSH 隧道(需要一端公网可达),要么裸 netcat(无加密、打不了洞)。完整安装 Tailscale 又太重:注册账号、装客户端、改路由表。

tailcat 的思路是只保留 Tailscale 最有价值的部分,magicsock 数据平面。它用 WireGuard 做端到端加密,DERP 服务器负责 NAT 打洞的信令交换,打洞失败时 DERP 降级为中继。协调服务器(控制平面)被砍掉了,连接元数据由你自己带外传递,复制粘贴一个 token 就行。

实际效果:

  • 不需要 Tailscale 账号
  • 不需要 root/管理员权限,不改路由表、不动 DNS,纯用户态
  • 先走 DERP 引导连接,之后 magicsock 尝试 NAT 穿透升级为直连 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

把这个地址发给对方,客户端执行:

$ echo hello | tailcat tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu

服务端随即输出 hello。行为和 netcat 一致,可以接管道做任何 stdin/stdout 的传输。

端口转发

README 里还展示了 --s 参数,把本地 TCP 端口通过隧道暴露出去(README 在此处截断,完整参数跑 tailcat --help 看)。

浏览器 Demo

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

库的用法

tailcat 同时是一个可导入的 Go 库(github.com/tailscale/tailcat,pkg.go.dev 有文档)。一侧起 server(listener)拿到短连接 token,另一侧拿 token 连接。也就是说你可以把这条加密隧道嵌进自己的程序里,而不只是当命令行工具用,这可能比 CLI 本身更有想象空间。

几个我提醒你注意的点

DERP 依赖。默认用官方免费限速的 DERP 中继(默认 DERP map 是 https://tailcat.dev/derpmap.json )。对隐私或可用性有要求,可以自建 DERP,官方文档指向 tailscale 仓库里的 cmd/derper。连接引导必须经过 DERP,即使最终能直连。

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

一次性连接。没有持久的虚拟网络,每次连接都要重新交换 token。这是设计取舍,不是缺陷,但意味着它替代不了 Tailscale 本体的组网场景。

值不值得看

2502 颗星,Go 实现,代码全部开源。我觉得它有两个价值:作为工具,是“临时给同事传个文件/连个端口”场景下最省事的方案之一,双方各跑一条命令就行;作为代码,它是学习 magicsock 和 NAT 穿透实现的好材料,Tailscale 把核心数据平面剥离成独立可读的库,这种机会不多。

这篇文章对你有帮助吗?

发表回复