How to Serve SSH Over Tailcat Using a Custom DERP Relay
You can route Tailcat’s auth-free SSH service through a self-hosted DERP relay by generating a region-pinned key with tailcat genkey --region=<hostname> and starting the server with --serve=no-auth-ssh.
Tailcat is an experimental tool from the tailscale/tailcat repository that provides authentication-free SSH access by leveraging Tailscale’s networking stack. While Tailcat defaults to Tailscale’s public DERP (Datacenter-Endpoint-Relay-Protocol) relays, the source code allows you to override this behavior and serve SSH over Tailcat using a custom DERP relay that you control, ensuring complete sovereignty over your connection bootstrap infrastructure.
What Is DERP and Why Custom Relays Matter
DERP acts as the initial bootstrap channel for WireGuard connections when direct UDP penetration is impossible. In tailcat.go, the DERPMapURL option (lines 91-98) defines how the client discovers available relays. By default, this points to Tailscale’s global infrastructure, but you can redirect it to your own derper instance. Running a custom DERP relay eliminates reliance on third-party infrastructure, allows you to enforce custom rate limits, and ensures availability within air-gapped or compliance-restricted environments.
Prerequisites
Before configuring Tailcat to use your own relay, ensure you have:
- A Linux or macOS server to run the Tailcat SSH service
- A publicly reachable host with a DNS name for your DERP relay (TLS certificate required)
- The
derperbinary from the main Tailscale repository deployed on that host - Tailcat installed on both server and client machines
Step 1: Deploy a Self-Hosted DERP Relay
First, run the derper binary on a machine with a public DNS name. The server must have TLS enabled—Derper can obtain certificates automatically via Let’s Encrypt.
sudo derper --hostname=derp.example.com --certmode=auto
Keep this process running. This relay will handle the initial encrypted handshake between Tailcat clients and your SSH server before the WireGuard tunnel is established.
Step 2: Generate a Region-Pinned Server Key
Next, create a Tailcat server key that embeds your custom DERP hostname. According to the README (lines 107-115), you pass the hostname via the --region flag. The generated token automatically contains the DERP node address, so clients do not need manual configuration to discover the relay.
tailcat genkey --region=derp.example.com
The output will be a token starting with tc (e.g., tcA1b2C3...). Save this token; it uniquely identifies your server and pins it to your custom relay region.
Step 3: Start the Tailcat SSH Server
Launch Tailcat with the built-in auth-free SSH service enabled. Use --serve=no-auth-ssh to activate the embedded SSH server, or --serve=22 if you prefer to proxy traffic to the local system’s OpenSSH daemon.
tailcat --serve=no-auth-ssh
Upon startup, the server logs will confirm the bootstrap region selection. Because the token generated in Step 2 already encodes the DERP hostname, you do not need to specify --derpmap-url on the command line. The HandleTailscaleSSHConn function in tailcat_ssh.go (lines 38-45) manages incoming connections, spawning the auth-free session once the WireGuard tunnel is negotiated through your custom relay.
How Client Connections Work
When a client connects using tailcat ssh <token>, the client binary parses the token to extract the embedded DERP region. It then connects to your custom relay (derp.example.com), establishes a WireGuard tunnel through that node, and authenticates the client using the WireGuard public key itself—no passwords or SSH keys are exchanged. The SSH session runs over this encrypted tunnel, providing end-to-end security without traditional authentication overhead.
# On the client machine
tailcat ssh tcA1b2C3...
If you published the token via DNS (e.g., as a TXT record), clients can simply run tailcat ssh example.com, and the client will resolve the token dynamically before connecting through your custom DERP relay.
Alternative: Proxy System SSH Instead of Built-In
If you prefer to use your existing OpenSSH configuration instead of Tailcat’s built-in server, change the serve flag to forward local port 22:
# Server side
tailcat --serve=22
# Client side (with DNS-published token)
tailcat ssh example.com
This configuration routes traffic through your custom DERP relay but delegates authentication to your underlying system SSH daemon.
Summary
- Custom DERP relays allow Tailcat to bootstrap connections without using Tailscale’s public infrastructure, as controlled via the
DERPMapURLoption intailcat.go. - Region-pinned keys embed the DERP hostname directly into the token via
tailcat genkey --region=<host>, eliminating the need for clients to specify relay addresses manually. - Auth-free SSH is implemented in
tailcat_ssh.gothrough theHandleTailscaleSSHConnfunction, which runs when--serve=no-auth-sshis enabled. - Connection flow involves the client connecting to your custom DERP relay, establishing WireGuard, and tunneling SSH traffic with cryptographic authentication derived from the WireGuard keys.
Frequently Asked Questions
What is DERP and why is it needed for Tailcat?
DERP (Datacenter-Endpoint-Relay-Protocol) is TCP-based relay protocol that routes encrypted WireGuard traffic when direct peer-to-peer UDP connections fail. Tailcat uses DERP as the initial bootstrap channel to coordinate connections before the WireGuard tunnel is established. Without DERP, clients could not locate or authenticate to the server when separated by NAT or firewalls.
Do clients need special flags to use a custom DERP relay?
No. When you generate a server key using tailcat genkey --region=<hostname>, the DERP node hostname is encoded directly into the token. Clients running tailcat ssh <token> parse this information automatically and connect to your specified relay without requiring additional command-line flags or configuration files.
Can I use Tailcat with my existing OpenSSH server?
Yes. Instead of --serve=no-auth-ssh, start Tailcat with --serve=22 to proxy incoming connections to the local SSH daemon on port 22. This preserves your existing authentication methods (keys, passwords, PAM) while still routing traffic through the Tailcat network and your custom DERP relay.
Is the SSH traffic encrypted end-to-end?
Yes. All traffic is encrypted by WireGuard before entering the DERP relay. The DERP server only sees encrypted packets and cannot decrypt the contents. The SSH session itself runs inside this WireGuard tunnel, meaning the connection is end-to-end encrypted from the client to the Tailcat server, with the custom DERP relay acting solely as an encrypted packet forwarder.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →