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:
- Creates a local TCP listener defaulting to
socks5h://127.0.0.1:0(random available port) - Instantiates a
socks5.Serverfrom thetailscale.com/net/socks5package - 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.tailcatresolves to the Tailcat server itself - Standard destinations: Regular hostnames or IPs are resolved via
lookupNetIPand 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:
- Starts the SOCKS5 listener
- Sets
all_proxy=socks5h://<listen_address>(implemented inclientSOCKSMode, lines 78-84 ofcmd/tailcat/tailcat.go) - 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
clientSOCKSModefunction incmd/tailcat/tailcat.go, using thetailscale.com/net/socks5library - Traffic classification via
classifySOCKSAddrroutes Tailcat tokens to the server and standard hostnames through the tunnel - Automatic environment injection sets
all_proxy=socks5h://<addr>when running commands viatailcat socks - Flexible addressing supports explicit tokens, the
server.tailcatmagic hostname, or DNS TXT record resolution - Local binding defaults to random ports on 127.0.0.1 but supports custom
--listenconfigurations 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →