Tailscale: WireGuard Mesh Networking for the Rest of Us
So you’re at a coffee shop, you need to SSH into your home server, and your roommate’s printer needs to reach your NAS across two different apartments.
Three different networks. Three different NAT boxes. The classic VPN setup would route everything through one central server — and that server would become the bottleneck, lag-wise and bandwidth-wise, the moment you actually need to move files around.
Tailscale exists because someone looked at that setup and said: what if the nodes just talked to each other directly, and only fell back to a relay when they absolutely had to?
That’s the pitch. The reality is a tight little bundle of WireGuard, a userspace networking stack, STUN/TURN-style NAT traversal, and a custom relay protocol called DERP. Once you see how the pieces fit together, the magic stops being magic.
What Tailscale Actually Does
Tailscale is a mesh VPN built on top of WireGuard. Install the client on a device, sign in, and that device shows up on every other device you own with a stable IP in the 100.x.x.x range.
What you get out of the box:
- No firewall configuration. The client punches through NAT automatically.
- No central hub for normal traffic. Devices talk to each other directly when they can.
- Automatic key rotation. WireGuard keys rotate in the background.
- SSO login. Sign in with Google, GitHub, or any OIDC provider — your work identity becomes your network identity.
- End-to-end encryption. DERP relays only see encrypted blobs; they can’t read your traffic.
The interesting part is how the direct connection actually happens. That’s where NAT traversal comes in.
The WireGuard Foundation
WireGuard is the cryptographic layer. Every Tailscale node runs a WireGuard implementation in userspace, not in the kernel.
Why userspace? Kernel-mode WireGuard is faster, but it requires root privileges and special kernel headers. Userspace WireGuard trades a small amount of throughput for the ability to run on any device without admin access — including locked-down corporate laptops and IoT devices.
The cryptographic operations are still real WireGuard. Curve25519 for key exchange, ChaCha20 for symmetric encryption, Poly1305 for MACs. The packets on the wire are valid WireGuard packets. Tailscale just handles the part where packets reach the right endpoint despite NAT.
If you only need encryption without the fancy NAT stuff, plain WireGuard is still fine for site-to-site links. Tailscale is built on top of it, not as a replacement.
NAT: Why Direct Connections Are Hard
Your home router does NAT. The coffee shop’s NAT is different. Your phone carrier’s NAT is yet another configuration. Each one has rules about which inbound packets it’s willing to accept.
The relevant distinction for NAT traversal:
Easy NAT (Endpoint-Independent Mapping, EIM). Once your laptop sends a packet to some server, the router opens a mapping that allows inbound packets from any source. Most consumer routers work this way. NAT traversal is mostly a matter of finding your public IP and port.
Hard NAT (Endpoint-Dependent Mapping, EDM). The router opens a mapping tied to a specific destination. Inbound packets from other destinations are dropped. Corporate firewalls and “carrier-grade” NATs work this way. Punching a hole in this kind of NAT is much harder.
STUN is the protocol that solves the easy case. Your laptop asks a STUN server, “what’s my public IP:port as you see it?” STUN tells you. You share that with the peer you’re trying to reach. If both sides have Easy NAT, the connection works.
When STUN fails — Hard NAT on either side — Tailscale falls back to a relay.
DERP: The Relay That’s Actually Smart
The old-school relay protocol is TURN: client authenticates to a public TURN server, gets an allocated IP:port, hands that address to the peer. Simple client-server model. Works, but not great.
Tailscale uses DERP (Detoured Encrypted Routing Protocol) instead. Three things make it interesting:
- It runs over HTTP. Most networks allow outbound HTTP even when they block UDP or arbitrary TCP. DERP gets through restrictive firewalls because it looks like regular web traffic.
- It relays by destination public key. DERP doesn’t decrypt your traffic. It just forwards encrypted blobs to the right node based on WireGuard’s destination pubkey.
- Auto-selects the nearest DERP. Tailscale picks the geographically closest DERP server for the path. If you’re in Shanghai, your traffic relays through a Hong Kong or Tokyo DERP, not one in Virginia.
The clever bit is the connection upgrade. Every Tailscale connection starts as DERP — instant, always works, terrible priority. Then in parallel, the client tries to find a direct path using STUN, ICE, and various NAT punching tricks. A few seconds later, if a direct path is found, the connection silently upgrades to peer-to-peer.
So DERP isn’t just a fallback. It’s the bootstrap layer that makes the magic trick possible. Without DERP, you’d have to wait a few seconds for NAT traversal before any traffic flowed. With DERP, traffic flows immediately, then gets faster when a better path appears.
Headscale: The Open-Source Control Server
Here’s the catch with Tailscale proper: the control server — the part that hands out ACLs, knows which nodes exist, issues WireGuard keys, manages user identities — is closed source. Free tier gives you 3 users and 100 devices. Beyond that, you’re paying.
Headscale (github.com/juanfont/headscale) is the open-source reimplementation of that control server. It’s API-compatible with the official Tailscale clients. You run it on your own VPS, register nodes to it instead of controlplane.tailscale.com, and you own the whole stack.
The deployment story is straightforward Docker Compose. You’ll want:
- PostgreSQL as the metadata store (Headscale dropped SQLite support in favor of Postgres for multi-node setups).
- Headscale container with
cap_add: NET_ADMINandNET_RAWfor IP forwarding inside the container. - Headplane (optional but recommended) — a web UI for managing users, nodes, and ACLs without touching the CLI.
The full docker-compose.yml is available in the Headscale repo. The one I tested pulls Headscale 0.23 or newer, Postgres 16, and Headplane 0.4+. Resource footprint is modest — the whole stack runs comfortably on a $5 VPS.
Where Mesh Beats Hub-and-Spoke
Traditional VPN gives every remote node one path: through the central server. Bandwidth is shared across all users. Latency is bounded by the speed of light to the hub and back.
Mesh VPN gives every pair of nodes a direct path. Bandwidth is bounded by the slowest link in the pair — typically the home upload speed of the slower side. Latency is the actual round-trip between the two endpoints, nothing else.
In practice, this matters most when you have:
- Multiple remote sites that need to talk to each other (home, parents’ house, friend’s apartment, work laptop).
- Symmetric-ish workloads where peer A is a heavy client of peer B (file syncing, backup, screen sharing).
- A small number of nodes where the O(n²) connection count is still tractable (Tailscale works great up to 100ish nodes per network; beyond that, the key distribution gets chatty).
For asymmetric workloads — most things going through one server anyway — the savings are smaller. Still better than star topology, but the difference is incremental.
What You Trade Off
Mesh isn’t free. Every node stores every other node’s keys and keeps a session for each. 10 nodes means 45 sessions. 100 nodes means 4,950. Tailscale scales to a few hundred reasonably well; beyond that, you’re looking at a tiered architecture.
The relay fallback also matters here. If your mesh network can’t find a direct path for 80% of pairs, you end up paying for DERP bandwidth even though you “have mesh.” Most home networks solve this by being mostly Easy NAT, but enterprise firewalls often force the relay.
There’s also a trust model decision. The official Tailscale control server sees your node IPs, user identities, and ACL policy. That metadata sits on Tailscale Inc.’s infrastructure. Running Headscale gives you metadata control in exchange for operational overhead.
Getting Started: Five Minutes
If you want to feel the difference, this works:
# Install on Linux
curl -fsSL https://tailscale.com/install.sh | sh
# Authenticate (opens browser)
sudo tailscale up
# Check status
tailscale statusThat gets you into the official Tailscale network. Headscale is the same dance but pointing the client at your own control server with --login-server=https://headscale.yourdomain.com.
For most developers, Tailscale’s free tier is plenty. For anyone running a homelab or self-hosting more than a handful of services, Headscale is a serious option worth evaluating before you outgrow the SaaS.
The Take
Tailscale isn’t magic. It’s WireGuard with a really good NAT-traversal story and a relay protocol that knows when to get out of the way. The control server part is closed source, but Headscale keeps the door open if you ever want to self-host.
If you find yourself reaching for SSH tunnels, port forwarding, or “is the NAS on a VPN right now?” — give it a try. The 5-minute setup is real.
Resources:
Comments