Tailscale releases Tailcat, netcat over WireGuard tunnels

Tailscale has open-sourced Tailcat, a small CLI tool and Go library built from pieces of Tailscale's own codebase. It works like netcat, sending data between two machines, but it moves that data over Tailscale's data plane (internally called magicsock): point-to-point WireGuard-encrypted tunnels that use DERP relay servers for NAT hole-punching and as a relay of last resort. The difference from Tailscale itself is that Tailcat skips the control plane entirely. There is no Tailscale account, no admin console, and connection details are exchanged out of band, however the two sides agree to share them. The tool needs no root or admin access and does not touch the machine's routing tables or DNS; it runs entirely in userspace.
One side runs a tailcat server, which prints a short connection token. The other side passes that token to the client to connect. All traffic is end-to-end encrypted with WireGuard. The connection first bootstraps through a DERP relay, then magicsock attempts NAT traversal to upgrade to a direct peer-to-peer UDP connection when possible. Beyond the basic netcat-style pipe, the CLI can forward a local TCP port to a remote client, run a passwordless SSH server (or one restricted to a specific client key via --allow), route a command through a SOCKS5 proxy over the tunnel, act as an exit node, and parse or resolve connection tokens to inspect or shorten their contents. A --until-direct flag on the ping subcommand keeps probing, up to a configurable timeout (default 10 seconds), until a direct path is established rather than staying on the DERP relay.
A connection token is a 'tc'-prefixed, base64-encoded CBOR blob holding the server's WireGuard public key (a 32-byte Curve25519 key) plus DERP relay information. By default each server run generates a fresh, ephemeral key that is discarded when the process exits, so a shared address only ever refers to that one run; tailcat genkey can instead save a key to disk so the address stays stable across restarts, at the cost that anyone who has ever seen that address can reconnect to any future server using the same key unless access is restricted to specific client identities. Tokens can be published as DNS TXT records and used as hostnames, and a --fixed-region flag pins a server's key to a specific DERP region so a published address keeps working across restarts. Tailcat can use Tailscale's free, rate-limited public DERP relays, or point at a self-hosted DERP server (via the derper tool, which can obtain its own Let's Encrypt certificate) or a custom DERP map. An experimental WebAssembly build runs Tailcat in the browser to send files or text; that browser traffic is relayed over DERP only, with no direct peer-to-peer connections until WebRTC support (tracked in a linked GitHub issue) is added.
Key facts
- Tailcat is a netcat-like CLI and Go library that tunnels over Tailscale's data plane (WireGuard plus DERP relays) but skips Tailscale's control plane, account system, and root/admin requirements entirely.
- One side runs a server and gets a connection token; the other side uses that token to connect. Traffic is end-to-end WireGuard-encrypted, bootstrapping through a DERP relay before magicsock tries to upgrade to a direct peer-to-peer UDP connection.
- Beyond a basic pipe, the CLI can forward local TCP ports, run a no-auth or client-restricted SSH server, proxy traffic through a SOCKS5 tunnel, and act as an exit node.
- A connection token embeds the server's 32-byte Curve25519 WireGuard public key and DERP region data as base64-encoded CBOR. Ephemeral keys are the default (discarded when the server process exits); saved keys via tailcat genkey keep an address stable across restarts but let anyone who saw that address reconnect later unless client access is restricted with --allow.
- Users can rely on Tailscale's free, rate-limited public DERP relays or run their own; an experimental WebAssembly build lets Tailcat run in a browser, relayed over DERP only until WebRTC support ships.
Why it matters
Tailcat strips out the part of Tailscale that usually anchors a connection: the control plane and the account behind it. What is left is a scriptable, point-to-point encrypted tunnel that two machines can set up on the spot, with no mesh network to provision and no admin console to configure. That makes it a fit for automation and one-off transfers rather than the persistent, managed network Tailscale itself provides.
Who it affects
Developers and infrastructure engineers who want an encrypted point-to-point connection or SSH access scripted into a tool or a CI job, without asking every peer to hold a Tailscale account. The Go library form also lets it be embedded directly in other software, as the minimal server and client examples in the documentation show.
How to use it
Tailcat is open source and free to install, via 'go install github.com/tailscale/tailcat/cmd/tailcat@latest' or through Nix flakes. It can use Tailscale's own DERP relays for free, subject to their rate limits, or a self-hosted DERP server for unlimited throughput. No pricing or paid tier is mentioned for the tool itself.
How solid is it
The project ships with working CLI examples, a Go library API, and an in-browser WebAssembly demo that interoperates with the CLI. It also documents its own current limits openly: browser connections are DERP-relay-only until WebRTC support lands, tracked as an open GitHub issue, and another open issue notes the client is not yet robust to the DERP map changing over time. No version number or release date is given in the documentation.
Risks and caveats
The convenience of a saved, stable key cuts against its security: once an address built from a saved key has been shared, anyone who saw it can connect to any future server run with that same key, unless the server restricts clients to specific allowed identities. Connection tokens are also case-sensitive, which works with curl and most CLI tools but breaks if pasted into a browser, since browsers lowercase hostnames. The safer default is Tailcat's ephemeral, one-run-only key.
“Anyone else's handshake is silently ignored: they can't reach the SSH server, or even learn that one is running.”
— Tailcat documentation