
Tailscale: a mesh network on top of WireGuard, without hand-wiring tunnels
You’ve got a working WireGuard tunnel between two servers, but now you need to add a third node, then a colleague’s laptop from another country, then someone’s phone that’s permanently behind an annoying NAT that won’t accept inbound connections. Suddenly the public-key matrix you were tracking by hand becomes a 20-row spreadsheet, and one wrong AllowedIPs entry breaks everything. That’s exactly the problem Tailscale was built to solve.
Tailscale is a mesh VPN network built on top of the WireGuard protocol. The clients are open source (BSD-3 license), but the control plane that coordinates nodes is a proprietary SaaS service. At DreamServer we run plain WireGuard with wg-easy for our own needs; we evaluated Tailscale as an alternative for teams that want zero-config and don’t want to manage keys by hand.
What Tailscale actually is
Under the hood, every data packet still travels over WireGuard: the same cryptography, Curve25519 and ChaCha20-Poly1305, the same point-to-point tunnel principles. The difference is what happens around that core. Tailscale runs a coordination server (control plane) that knows the identity of every device, automatically exchanges and refreshes public keys between nodes, and decides which nodes are allowed to talk to each other based on the policies you define.
Actual data traffic tries to stay peer-to-peer, direct between the two endpoints, even if both are behind different NATs. When a direct connection can’t be established (strict symmetric NATs, aggressive corporate firewalls), Tailscale falls back to its own relays called DERP (Designated Encrypted Relay for Packets), which route end-to-end encrypted traffic without being able to read it.
Why this approach matters
The real problem Tailscale solves isn’t encryption, it’s coordination. Plain WireGuard requires every peer to know the other’s public key and IP/port in advance. In a static network of 2-3 servers, that’s trivial. In a dynamic network with users connecting from different networks every day, it becomes an operational nightmare. Tailscale moves that problem to a central server that handles auto-discovery and key distribution, and users authenticate via SSO (Google, GitHub, Okta, Microsoft) instead of receiving a config file over Slack.
What you get out of the box
- MagicDNS: every device on the network gets a stable DNS name (
server1.tail-scale.ts.net), no more editing/etc/hosts. - Declarative ACLs: a JSON/HuJSON file defines who can talk to whom, on which ports, far more granular than
AllowedIPs. - Native SSO: login through the identity providers you already use, with instant revocation when an employee leaves the organization.
- Automatic NAT traversal: no more manual port forwarding on a router for every new node.
- Exit nodes and subnet routers: a single node can expose an entire subnet or act as an exit gateway for all traffic, without reconfiguring the rest of the fleet.
- Clients on every platform, including mobile, with a simple GUI.
Installing Tailscale on a VPS
Installing the client is minimal regardless of distro:
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --ssh --accept-routes
The tailscale up command opens an authentication link in a browser (or prints one in the terminal for headless servers), where you log in with your identity and authorize the node. For a server that needs to expose an internal subnet to other nodes on the network:
tailscale up --advertise-routes=10.0.0.0/24 --advertise-exit-node
The tailscale0 interface automatically gets an address from the 100.x.x.x space (CGNAT range, reserved by Tailscale). You don’t need a publicly exposed admin port, but if you run an additional local daemon or an exit node with extra services, lock them down explicitly:
ufw default deny incoming
ufw allow in on tailscale0
For a stable coordination node (subnet router, exit node) you need a VPS with predictable uptime; check our VPS plans if you want to run it on our infrastructure.
Configuration patterns worth knowing
ACLs actually need to be written, not just enabled
Without explicit policies in the ACL file, Tailscale defaults to permissive (every node on the tailnet can talk to every other node). For any production environment, write explicit policies like “group X can only reach tag Y on port Z” before adding real users to the network.
Tag devices, don’t rely on user identity
Authorize servers based on tags (tag:prod-db, tag:ci-runner), not on the account of the user who originally enrolled them. If that user leaves the organization and you revoke their access, tagged servers stay functional.
Keep exit node separate from subnet router
Don’t combine, without reason, the exit-node role (all of a client’s internet traffic routes through that node) with the subnet-router role (exposes an internal subnet). They’re different use cases, and enabling them on separate nodes avoids a single point through which everything flows.
Check DERP if latency seems high
If you notice unexpectedly high latency between two nodes, check tailscale netcheck to see whether the connection fell back to a DERP relay instead of going direct. That’s a sign NAT traversal failed, usually because of an aggressive corporate firewall on one side.
Where Tailscale is not the right answer
The most important trade-off, stated plainly: Tailscale’s control plane is proprietary. If your internal policy requires all network infrastructure to be fully self-hosted, or you operate in an environment where you can’t accept an external dependency for access coordination, plain Tailscale doesn’t qualify. Headscale exists, an open-source reimplementation of the control plane compatible with official Tailscale clients, but it requires you to operate and maintain that server yourself.
For very small, static networks (2 servers that never change), it’s also not worth the added complexity: plain WireGuard stays easier to understand end to end.
Alternatives we considered
- Plain WireGuard (with wg-easy for a UI): no external dependency, ideal for small or static networks where you want full control.
- Headscale : open-source control plane, compatible with Tailscale clients, for anyone who wants the functionality without the SaaS.
- ZeroTier : alternative with native Layer 2 support, its own protocol, its own control-plane model (partially self-hostable via “moons” and self-hosted controllers).
So, should you run it?
If you have a distributed team, devices connecting from different networks every day, and you want to avoid manually maintaining WireGuard keys and configs, Tailscale is worth trying: the free tier for personal use is generous, and setup is, literally, a tailscale up and a login. Just be aware of the trade-off: the control plane is SaaS, not yours, and if that’s a problem, Headscale or plain WireGuard remain the options that give you full control.
Need a stable node for an exit node or subnet router? Start from a VPS with us, or let our team configure it through server administration .