【文章标题】:Tailcat: Secure Tunnels in Seconds (Tailscale)
【文章标题】:Tailcat:秒级建立安全隧道 (Tailscale)
【文章正文】: “Tailscale without Tailscale, by Tailscale” Tailcat is a remix of Tailscale open source pieces to act like netcat, but over Tailscale’s data plane, without Tailscale’s control plane. Tailscale’s data plane (magicsock, internally) gives you point-to-point WireGuard®-encrypted tunnels between two machines with DERP as the NAT-hole-punching communication side channel and the ultimate relay-of-last-resort if NAT traversal fails. Instead of using the Tailscale control plane, all tailcat connection metadata is exchanged out of band, however you want.
【文章正文】: “没有Tailscale的Tailscale,由Tailscale出品” Tailcat是对Tailscale开源组件的重新组合,其作用类似于netcat,但运行在Tailscale的数据平面上,而不依赖Tailscale的控制平面。Tailscale的数据平面(内部称为magicsock)能在两台机器之间建立点对点的WireGuard®加密隧道,并使用DERP作为NAT打洞的通信旁路通道,以及在NAT穿透失败时作为最终的兜底中继。Tailcat不使用Tailscale控制平面,所有连接元数据都通过带外方式交换,具体方式由你决定。
The tailcat CLI (in cmd/tailcat) is built on the tailcat Go library (importable as github.com/tailscale/tailcat). Whether you use tailcat as a CLI tool or library, one side runs a tailcat server (listener) and gets back a short connection token. The other side passes that token to tailcat’s client side to connect. All traffic between the two is encrypted end-to-end with WireGuard. The initial connection bootstraps through Tailscale’s DERP relay network, and then magicsock performs NAT traversal to upgrade to a direct peer-to-peer UDP connection when possible (usually!).
tailcat命令行工具(位于cmd/tailcat)基于tailcat Go库(可通过github.com/tailscale/tailcat导入)构建。无论将tailcat用作CLI工具还是库,都需要一端运行tailcat服务器(监听器)并获取一个短连接令牌。另一端将该令牌传递给tailcat客户端进行连接。两者之间的所有流量均通过WireGuard进行端到端加密。初始连接通过Tailscale的DERP中继网络进行引导,随后magicsock会执行NAT穿透,在可能的情况下(通常都可以!)升级为直接的点对点UDP连接。
You don’t need a Tailscale account, root/admin access on the machine (it doesn’t alter your machine’s routing tables, DNS, etc.). It’s just a userspace library and CLI tool. And it’s all open source.
你不需要Tailscale账户,也不需要机器的root/管理员权限(它不会修改机器的路由表、DNS等)。它只是一个用户态库和CLI工具。 而且完全开源。
You can use our free rate-limited DERP relays (the default DERP map is https://tailcat.dev/derpmap.json) or you can run your own.
你可以使用我们免费的、有速率限制的DERP中继(默认DERP映射为 https://tailcat.dev/derpmap.json),也可以自行搭建。
Server starts, printing out its ephemeral address: $ tailcat
Selected bootstrap relay region 302, San Francisco
🐈 Server listening with new address: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
(hangs, waiting…)
服务器启动,打印出其临时地址: $ tailcat
已选择引导中继区域 302,旧金山
🐈 服务器正在监听新地址:tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
(挂起,等待中…)
And then the client can: Then the server unblocks: $ tailcat
Selected bootstrap relay region 302, San Francisco
🐈 Server listening with new address: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
hello $
然后客户端可以执行: 随后服务器解除阻塞: $ tailcat
已选择引导中继区域 302,旧金山
🐈 服务器正在监听新地址:tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
hello $
Or you can serve a local TCP port, forwarded to localhost: $ tailcat —serve=8080,8443 # or —serve=all
🐈 Server listening with new address: tcXXXXXXXXX
And then the client: $ tailcat tcXXXXXXXXX 8080 GET / HTTP/1.1 Host: foo HTTP/1.1 200 OK …
或者你可以提供本地TCP端口服务,并转发到localhost: $ tailcat —serve=8080,8443 # 或 —serve=all
🐈 服务器正在监听新地址:tcXXXXXXXXX
然后客户端: $ tailcat tcXXXXXXXXX 8080 GET / HTTP/1.1 Host: foo HTTP/1.1 200 OK …
On Linux and macOS, you can run an SSH server too with no auth. (If you want auth, you can just tailcat —serve=22 and proxy to your system SSH server) $ tailcat —serve=no-auth-ssh
🐈 Server listening with new address: tcXXXXXXXXX
And on the client side: tailcat ssh tcXXXXXXXXX ls -la
在Linux和macOS上,你还可以运行一个无需认证的SSH服务器。(如果需要认证,只需使用 tailcat —serve=22 并代理到系统SSH服务器) $ tailcat —serve=no-auth-ssh
🐈 服务器正在监听新地址:tcXXXXXXXXX
在客户端: tailcat ssh tcXXXXXXXXX ls -la
Ping to test connectivity; each pong reports whether it arrived via a
DERP relay or a direct path. —until-direct keeps pinging (up to
—timeout, default 10s) until a direct path works, exiting non-zero
if one doesn’t:
$ tailcat ping —until-direct
使用Ping测试连通性;每次pong响应都会报告它是通过DERP中继还是直接路径到达的。—until-direct 会持续ping(直到 —timeout,默认10秒),直到直接路径生效,如果未生效则以非零状态退出:
$ tailcat ping —until-direct
Run a command through a SOCKS5 proxy routed over the tunnel:
tailcat socks curl http://
通过隧道路由的SOCKS5代理运行命令:
tailcat socks curl http://
Act as an exit node so the client can reach the server’s network: $ tailcat —serve=exit-node
充当出口节点,使客户端能够访问服务器所在的网络: $ tailcat —serve=exit-node
Parse a connection token and print its contents (the server’s WireGuard public key and DERP info) as JSON, without connecting to anything: $ tailcat parse tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu { “ServerPublic”: “nodekey:9c8d2e6728da80a1dd37e275a82595b42d9a838610bc53f74a7670d1610f2e34”, “RegionID”: 302 }
解析连接令牌并将其内容(服务器的WireGuard公钥和DERP信息)以JSON格式打印,不连接任何目标: $ tailcat parse tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu { “ServerPublic”: “nodekey:9c8d2e6728da80a1dd37e275a82595b42d9a838610bc53f74a7670d1610f2e34”, “RegionID”: 302 }
Resolve a short token (which references a DERP region by ID, requiring clients to fetch the DERP map) into a longer self-contained one with the DERP server info embedded, letting clients connect more quickly: $ tailcat resolve tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFygaFhToGjYWhudGMzMDJhLmlwbi5kZXZhNG0yMDguMTExLjM5LjM4YTZzMjYwNzpmNzQwOjA6M2Y6OjcyMA
将短令牌(通过ID引用DERP区域,要求客户端获取DERP映射)解析为包含DERP服务器信息的更长的独立令牌,让客户端能够更快地连接: $ tailcat resolve tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFygaFhToGjYWhudGMzMDJhLmlwbi5kZXZhNG0yMDguMTExLjM5LjM4YTZzMjYwNzpmNzQwOjA6M2Y6OjcyMA
Parsing that resolved token shows the embedded DERP info: $ tailcat parse tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFygaFhToGjYWhudGMzMDJhLmlwbi5kZXZhNG0yMDguMTExLjM5LjM4YTZzMjYwNzpmNzQwOjA6M2Y6OjcyMA { “ServerPublic”: “nodekey:9c8d2e6728da80a1dd37e275a82595b42d9a838610bc53f74a7670d1610f2e34”, “Region”: [ { “Nodes”: [ { “HostName”: “tc302a.ipn.dev”, “IPv4”: “208.111.39.38”, “IPv6”: “2607:f740:0:3f::720” } ] } ] }
解析该解析后的令牌会显示嵌入的DERP信息: $ tailcat parse tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFygaFhToGjYWhudGMzMDJhLmlwbi5kZXZhNG0yMDguMTExLjM5LjM4YTZzMjYwNzpmNzQwOjA6M2Y6OjcyMA { “ServerPublic”: “nodekey:9c8d2e6728da80a1dd37e275a82595b42d9a838610bc53f74a7670d1610f2e34”, “Region”: [ { “Nodes”: [ { “HostName”: “tc302a.ipn.dev”, “IPv4”: “208.111.39.38”, “IPv6”: “2607:f740:0:3f::720” } ] } ] }
A server can print the long self-contained form directly with the —full-address flag.
服务器可以使用 —full-address 标志直接打印长的独立格式。
A server’s address (connection token) is derived from its WireGuard key, so the key you use determines who can reach you:
Ephemeral keys (the
服务器的地址(连接令牌)由其WireGuard密钥派生,因此你使用的密钥决定了谁能访问你:
临时密钥(the