How to Use Tailcat as a SOCKS5 Proxy: Complete Setup and Architecture Guide

Tailcat converts encrypted Tunnel+WireGuard connections into a local SOCKS5 proxy by running tailcat socks <token> on the client, which starts a local TCP listener and forwards traffic through the Tailcat server while automatically injecting the all_proxy environment variable.

Tailcat is an experimental tunneling tool from the Tailscale organization (tailscale/tailcat) that bridges lightweight WireGuard connections with application-layer proxies. When you use Tailcat as a SOCKS5 proxy, you create a local TCP endpoint that tunnels arbitrary traffic through an encrypted client-to-server circuit, allowing any SOCKS5-aware application to communicate securely without native integration.

Architecture of Tailcat SOCKS5 Mode

The SOCKS5 implementation spans both client and server components, with the proxy logic running entirely within the client process.

Server Component

The Tailcat server listens for inbound WireGuard connections and advertises a ConnBlob token that clients use to establish sessions. The core server implementation resides in cmd/tailcat/tailcat.go, specifically within the newServer function and the generic Server struct. The server itself does not implement SOCKS5 logic; it merely accepts encrypted tunnels and forwards traffic to the specified destination ports.

Client SOCKS5 Implementation

The client-side SOCKS5 proxy is implemented in the clientSOCKSMode function (lines 93-104 of cmd/tailcat/tailcat.go). This function:

  1. Creates a local TCP listener defaulting to socks5h://127.0.0.1:0 (random available port)
  2. Instantiates a socks5.Server from the tailscale.com/net/socks5 package
  3. Passes a custom Dialer (defined in lines 55-72) that routes connections through the established Tailcat tunnel

Address Classification and Routing

Tailcat uses the classifySOCKSAddr function (lines 618-653 of cmd/tailcat/tailcat.go) to determine how to route each SOCKS5 request. The classification logic distinguishes between:

  • Tailcat tokens: Destination hosts matching the token format (e.g., tc1yRz…) trigger a direct dial to the Tailcat server
  • Magic hostname: The special name server.tailcat resolves to the Tailcat server itself
  • Standard destinations: Regular hostnames or IPs are resolved via lookupNetIP and tunneled through the client-to-server circuit

Unit tests in cmd/tailcat/socks_test.go (lines 31-88) validate these classification rules and edge cases.

Step-by-Step SOCKS5 Configuration

1. Start the Tailcat Server

First, initialize a Tailcat server to generate an address token. The server exposes specific ports for tunneling:


# Start server on ports 8080 (HTTP) and 8443 (HTTPS)

$ tailcat --serve=8080,8443

# Output: 🐈 Server listening with new address: tc1yRz…

Copy the token (e.g., tc1yRz…) for the client connection.

2. Launch the SOCKS5 Proxy Client

Run the tailcat socks subcommand with the server token to start the local proxy:

$ tailcat socks tc1yRz…

By default, this binds to a random local port. The proxy remains active until interrupted, forwarding all SOCKS5 connections through the encrypted tunnel to the server.

3. Configure Application Environment

For applications that read standard environment variables, export all_proxy pointing to the Tailcat listener:

$ export all_proxy=socks5h://127.0.0.1:<port>
$ curl http://example.com/

Command Execution with Automatic Proxy Injection

Tailcat can execute commands with the all_proxy environment variable pre-configured. When you append a command to tailcat socks, the client:

  1. Starts the SOCKS5 listener
  2. Sets all_proxy=socks5h://<listen_address> (implemented in clientSOCKSMode, lines 78-84 of cmd/tailcat/tailcat.go)
  3. Executes the command via exec, replacing the tailcat process

# Automatically proxies wget through the Tailcat tunnel

$ tailcat socks tc1yRz… wget https://example.org/file.txt

Advanced SOCKS5 Options

Custom Listen Addresses

Bind the SOCKS5 proxy to a specific interface and port using the --listen flag:


# Bind to all interfaces on port 1080

$ tailcat socks --listen=:1080 tc1yRz… &
$ export all_proxy=socks5h://127.0.0.1:1080

DNS-based Token Resolution

Tailcat supports resolving server tokens via DNS TXT records, eliminating the need to pass tokens explicitly on the command line:


# Assumes example.com has TXT record "tailcat=tc1yRz…"

$ tailcat socks example.com curl http://server.tailcat:8081/

The client queries DNS for the TXT record, extracts the token, and establishes the tunnel before processing the SOCKS5 request.

Summary

  • Tailcat implements SOCKS5 entirely on the client side through the clientSOCKSMode function in cmd/tailcat/tailcat.go, using the tailscale.com/net/socks5 library
  • Traffic classification via classifySOCKSAddr routes Tailcat tokens to the server and standard hostnames through the tunnel
  • Automatic environment injection sets all_proxy=socks5h://<addr> when running commands via tailcat socks
  • Flexible addressing supports explicit tokens, the server.tailcat magic hostname, or DNS TXT record resolution
  • Local binding defaults to random ports on 127.0.0.1 but supports custom --listen configurations for network-wide proxy access

Frequently Asked Questions

What is the default SOCKS5 listen address in Tailcat?

By default, Tailcat binds to socks5h://127.0.0.1:0 (a random available port on localhost) when running in SOCKS5 mode. The actual port is selected by the operating system and displayed when the proxy starts, or you can specify a fixed address using the --listen flag.

How does Tailcat route different types of SOCKS5 destinations?

According to classifySOCKSAddr in cmd/tailcat/tailcat.go (lines 618-653), Tailcat inspects the destination hostname. If it matches a Tailcat token format (starting with tc), the proxy dials the Tailcat server directly. If it matches server.tailcat, it routes to the server itself. All other hostnames or IPs undergo standard DNS resolution via lookupNetIP before being tunneled through the WireGuard connection.

Can applications use Tailcat's SOCKS5 proxy without code modifications?

Yes. Any application that respects the all_proxy or http_proxy environment variables can use Tailcat's SOCKS5 proxy without modification. Additionally, you can configure specific applications (like curl, wget, or OpenSSH via ProxyCommand as shown in cmd/tailcat/ssh.go) to use socks5h://127.0.0.1:<port> explicitly.

Is it possible to run Tailcat SOCKS5 without passing the token on the command line?

Yes. Tailcat supports DNS TXT record-based token resolution. If you provide a hostname (instead of a token) to tailcat socks, the client queries DNS for a TXT record containing tailcat=<token>, extracts the token, and uses it to establish the connection. This allows teams to distribute server addresses through DNS infrastructure rather than command-line arguments.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →