tailscale/tailcat
DevOps & Self-hostingOpen a WireGuard-encrypted peer-to-peer tunnel between two machines and pipe data or ports through it without a control plane.
Tailcat is a Go CLI and library that behaves like netcat, but the connection is a Tailscale data-plane tunnel: one side runs a listener and prints a short tc… address, the other passes that address to connect. All traffic is encrypted end-to-end with WireGuard, bootstrapped through a DERP relay and upgraded to direct UDP via NAT hole-punching when possible README. No Tailscale account, root access, routing-table or DNS changes are needed, because WireGuard, magicsock and a gVisor userspace TCP/IP stack all run in-process.
What changes in practice
The address is the connection handle, shared out of band rather than through a control plane. With no arguments, tailcat pipes stdin/stdout over the tunnel; serve 8080,8443 exposes local TCP ports, and serve 5555:10.2.200.213:5555 proxies one to another host on the server's network without acting as a full exit node. forward makes remote ports available as ordinary localhost ports, browse opens a browser at one, socks runs a command through a SOCKS5 proxy, and perf runs an iperf-like throughput and latency test that refuses the shared relays unless --via-derp names a relay you run yourself. cp/ls use SFTP, with recv giving a write-only drop box and serve files serving a directory confined to that directory. ssh and no-auth-ssh offer a shell, optionally with a command pinned per connection via exec or ForceCommand-style arguments README.
Two mechanisms shape the fit. First, the address embeds the server's WireGuard public key, path-discovery key, a pre-shared key by default, and DERP region information, so knowing it is enough to connect; ephemeral keys die with the process, while genkey saves a stable key that everyone you ever shared the address with can reuse unless you add serve --allow. Second, direct connections are attempted but not guaranteed: if hole-punching fails the tunnel continues over DERP, workable but rate-limited on the shared relays.
Requirements and caveats
Install paths differ by platform: static binaries and packages for Linux/Windows, Homebrew for macOS, Scoop for Windows, Nix and conda-forge for Linux/macOS/Windows, and build-from-source for all platforms plus the browser WebAssembly demo INSTALL. The browser demo can exchange files and text with the CLI but relays only over DERP until WebRTC support lands web demo.
The address is a bearer secret. Publishing it in a public DNS TXT record requires authenticating clients separately — serve --allow or --ssh-authorized-keys — and never publishing a no-auth-ssh address. tailcat ssh probes a DNS-named server with a throwaway key and refuses to connect if that stranger login succeeds. SSH key sources must all load or startup fails; command= and from= options are rejected. Transfers are uncompressed. The project promises no API, CLI or wire-format stability, and the public relays have no uptime or throughput SLA and may be revoked README.
Written by AI from the project's README, updated October 29, 2026. The project's own docs are the source of truth.