How to Set Up Tailscale for Mesh Networking Across All Your Devices

Tailscale creates a private WireGuard
-based mesh VPN across all your devices with almost no configuration. You install the client on each machine, authenticate with your identity provider, and every device gets a stable 100.x.y.z IP that works regardless of NAT, firewalls, or network changes. As of early 2026, Tailscale
v1.96 supports ACL tags for device-level policy, exit nodes for routing all traffic through a specific machine, subnet routers for exposing entire LANs, and MagicDNS for hostname resolution. For homelabbers, it is the simplest way to securely connect a homelab server, cloud VPS, phone, and laptop into one unified network.
Below, we walk through how Tailscale differs from raw WireGuard, how to install it on Linux, Docker, NAS, and firewall platforms, how to write ACL policies, and how to go fully independent by self-hosting the control plane with Headscale.
What Tailscale Actually Is (and How It Differs from Raw WireGuard)
Tailscale gets confused with WireGuard itself all the time. They are not the same thing. WireGuard is the transport layer - a fast, modern VPN protocol using ChaCha20-Poly1305 encryption. Every Tailscale connection is a standard WireGuard tunnel under the hood, and the encryption and performance characteristics are identical to what you would get running raw WireGuard. What Tailscale adds is the control plane that WireGuard deliberately leaves out: key exchange, NAT traversal, and peer discovery.
The Coordination Server
Tailscale’s coordination server distributes public keys and endpoint information to all nodes in your network (called a “tailnet”). It never sees your actual traffic - only metadata about which devices exist and their network endpoints. All data flows peer-to-peer via WireGuard. If you are uncomfortable with even that metadata going to Tailscale’s infrastructure, Headscale is an open-source replacement you can self-host (more on that later).
NAT Traversal with DERP
When direct peer-to-peer UDP connections fail - symmetric NAT, restrictive corporate firewalls, CGNAT - traffic relays through DERP (Designated Encrypted Relay for Packets) servers. DERP traffic is encrypted end-to-end, so Tailscale cannot inspect relayed packets. You can check your connection status with tailscale netcheck, which reports latency to each DERP region and whether direct connections are possible.
In practice, most connections end up being direct peer-to-peer. DERP is a fallback, not the norm.
Tailscale vs. Raw WireGuard for Homelabbers
Raw WireGuard requires manually managing keys, endpoints, and AllowedIPs on every peer. Adding a new device means editing configs on all existing peers. With 3 devices this is annoying; with 15 it is a maintenance disaster. Tailscale automates the entire process. The trade-off is a dependency on the coordination server, but Headscale removes that dependency for self-hosters.
Tailscale vs. Nebula vs. ZeroTier
Other mesh VPN options exist. Nebula (originally built at Slack) uses its own encryption protocol and requires running a lighthouse server for peer discovery. ZeroTier provides similar mesh functionality but uses its own virtual network layer rather than WireGuard. In benchmarks, Tailscale and ZeroTier are roughly comparable in throughput, both about twice as fast as Nebula and Tinc. Tailscale wins on simplicity for most users and benefits from WireGuard’s kernel-level performance on Linux.
| Feature | Tailscale | ZeroTier | Nebula |
|---|---|---|---|
| Encryption | WireGuard (ChaCha20-Poly1305) | Custom (ChaCha20-Poly1305) | Custom (Noise protocol) |
| NAT Traversal | DERP relays | Root servers | Lighthouse servers |
| Free Tier | 100 devices, 3 users | 25 devices | Unlimited (self-hosted) |
| Kernel Mode (Linux) | Yes | No | No |
| Self-hostable Control Plane | Yes (Headscale) | Yes (ZeroTier controller) | Yes (built-in) |
Pricing in 2026
Tailscale’s free Personal plan covers 100 devices and 3 users - generous enough for most homelabs. Personal Plus runs $5/month and bumps the user limit to 6. The Starter plan ($6/user/month billed annually) and Premium ($18/user/month) add features like longer log retention, custom OIDC, and SCIM provisioning. There are no bandwidth limits on any tier.
Installing Tailscale on Every Platform
Tailscale supports Linux, macOS, Windows, iOS, Android, and several NAS platforms. Installation is quick on all of them.
Linux (Debian, Ubuntu, Fedora)
The one-liner install script adds the official repository and installs both the tailscale CLI and the tailscaled daemon:
curl -fsSL https://tailscale.com/install.sh | shAuthenticate with:
sudo tailscale upThe client runs as a systemd service (tailscaled.service). After authenticating, your machine gets a 100.x.y.z address and can reach every other device in your tailnet.
Headless Linux Servers
For servers without a browser, use a pre-generated auth key from the Tailscale admin console:
sudo tailscale up --authkey=tskey-auth-XXXX --advertise-tags=tag:serverAuth keys can be reusable (for automated provisioning), ephemeral (device removed when it goes offline), or single-use. The --advertise-tags flag assigns ACL tags at registration time, which matters for policy enforcement.
Docker Containers
Run the official tailscale/tailscale:latest image as a sidecar container:
docker run -d \
--name tailscale \
--cap-add=NET_ADMIN \
--device=/dev/net/tun \
-e TS_AUTHKEY=tskey-auth-XXXX \
tailscale/tailscale:latestFor environments where TUN device access is restricted, set TS_USERSPACE=true to run in userspace networking mode. This is slower but works in unprivileged containers and on platforms like Fly.io.
Synology NAS
Install via the Tailscale package in Synology Package Center (requires DSM 7.0+). Once installed, you can enable subnet routing to expose the NAS’s LAN, making all devices on that network reachable through Tailscale without installing the client on each one. Subnet routes need admin approval in the Tailscale console after advertisement.
Proxmox
You have two approaches on Proxmox. Install directly on the host to access the management web UI (port 8006) remotely over Tailscale. Or install inside individual VMs and LXC containers to give each one its own Tailscale identity. For LXC containers, make sure the container has the TUN device available:
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=fileOPNsense and pfSense
Both OPNsense and pfSense have official Tailscale plugins. As of OPNsense v24.7, the os-tailscale plugin is available directly in the UI without command-line steps. On pfSense, the Tailscale package lets you enable subnet routing so remote tailnet devices can access hosts behind the firewall. Running Tailscale on your router is an alternative to dedicated subnet routers, particularly useful when you want the firewall itself to act as the gateway to the local network.
Mobile and Desktop
macOS, iOS, and Android clients are available from their respective app stores. The macOS client uses a network extension (no kernel module needed). Mobile clients support exit nodes, which is useful for encrypting traffic on public Wi-Fi.
ACLs, Tags, and Policy Configuration
Tailscale’s ACL (Access Control List) system controls which devices can communicate. Instead of writing firewall rules based on IP addresses, you write policies based on device tags and user identities. If you are used to iptables or pf rules, this takes some adjustment.
Where ACLs Live
ACLs are defined in the Tailscale admin console under Access Controls as a HuJSON (human-readable JSON) file. Changes propagate to all nodes within seconds. For version control, copy the ACL file to a Git repository - Tailscale does not track revision history internally.
Tag-Based Access Control
Tags like tag:server, tag:iot, and tag:admin are assigned to devices via auth keys or the admin console. ACL rules reference these tags:
{
"action": "accept",
"src": ["tag:admin"],
"dst": ["tag:server:*"]
}This rule allows any device tagged admin to access any port on devices tagged server.
A Practical Homelab ACL Example
Here is a complete ACL policy for a homelab with three user roles and ten devices:
{
"tagOwners": {
"tag:server": ["autogroup:admin"],
"tag:iot": ["autogroup:admin"],
"tag:admin": ["autogroup:admin"]
},
"acls": [
// Admin devices can reach everything
{"action": "accept", "src": ["tag:admin"], "dst": ["*:*"]},
// Servers can reach each other on specific ports
{"action": "accept", "src": ["tag:server"],
"dst": ["tag:server:5432,6443,8080,443"]},
// IoT devices can only reach Home Assistant
{"action": "accept", "src": ["tag:iot"],
"dst": ["home-assistant:8123"]},
// Family members get access to shared services
{"action": "accept", "src": ["group:family"],
"dst": ["home-assistant:8123", "jellyfin:8096", "nas:445"]}
],
"groups": {
"group:family": ["user1@example.com", "user2@example.com"]
}
}The default-deny behavior means anything not explicitly allowed is blocked. IoT devices are sandboxed to the Home Assistant port. Family members reach media and file sharing but cannot SSH into infrastructure.
Tailscale SSH
Enable Tailscale SSH on target machines with tailscale up --ssh. This lets Tailscale handle SSH authentication through your identity provider - no SSH keys to distribute or rotate. ACLs control who can SSH to which machines, and all access is logged in the admin console. It is particularly useful for shared homelabs where multiple people need occasional server access.
Autogroups
Tailscale includes built-in autogroups: autogroup:internet for exit node traffic, autogroup:self for device-to-self rules, and autogroup:member to reference all human users (as opposed to tagged devices). These simplify common patterns without requiring explicit group definitions.
Exit Nodes, Subnet Routers, and MagicDNS
Beyond basic device-to-device connectivity, Tailscale has three features that handle broader networking tasks: routing all your internet traffic through a chosen machine, bridging entire LANs into the mesh, and resolving hostnames automatically.
Exit Nodes
An exit node routes all of a client’s internet traffic through a specific device. On a VPS or home server:
tailscale up --advertise-exit-nodeOn client devices:
tailscale up --exit-node=<hostname>All internet traffic now flows through that exit node. Use this to encrypt traffic on public Wi-Fi, appear from your home IP while traveling, or route through a specific geographic location.
Mullvad Integration: Tailscale has a partnership with Mullvad VPN that lets you use Mullvad’s global network of servers as exit nodes directly within your tailnet. The add-on costs $5/month per 5 devices. You configure it in the admin console, and Mullvad exit nodes appear alongside your own devices in the exit node picker. This is useful for privacy-focused internet routing without running your own VPS in multiple regions.
Subnet Routers
A subnet router exposes an entire LAN to your tailnet without installing Tailscale on every device in that LAN:
tailscale up --advertise-routes=192.168.1.0/24Approve the route in the admin console, and all Tailscale peers can reach 192.168.1.x devices directly. This is how you make printers, IoT devices, NAS appliances, and IP cameras accessible remotely. The subnet router acts as a gateway - traffic enters the Tailscale mesh, hits the subnet router, and gets forwarded to the local network.
MagicDNS
Enable MagicDNS in the admin console under DNS settings. Every device becomes reachable by hostname:
ssh pi-homelab
# instead of
ssh 100.64.0.5Set a custom search domain so pi-homelab.your-tailnet.ts.net resolves from any device. You can also configure split DNS to forward queries for .home.lan to your local DNS server at 192.168.1.1 via the subnet router, letting Tailscale peers resolve local hostnames even when off-site.
Tailscale Funnel
Tailscale Funnel
exposes a specific port on a Tailscale node to the public internet via a *.ts.net HTTPS URL. No port forwarding or dynamic DNS configuration needed:
tailscale funnel --bg 8080This is useful for sharing a dev server, setting up a webhook endpoint, or exposing Home Assistant to family members who do not have Tailscale installed. Funnel handles TLS termination automatically.
Performance Expectations
Direct peer-to-peer connections add roughly 1ms of latency compared to no VPN. DERP-relayed connections add 10-50ms depending on relay server proximity. On a gigabit LAN, Tailscale’s userspace WireGuard implementation typically achieves 250-300 Mbps in iperf3 tests. With kernel-level optimizations and UDP segmentation offloading on Linux, throughput can exceed 7 Gbps. Run tailscale ping <hostname> to verify whether a connection is direct or relayed.
| Connection Type | Added Latency | Typical Throughput (Gigabit Link) |
|---|---|---|
| Direct P2P | ~1ms | 250-900 Mbps (userspace vs. kernel) |
| DERP Relayed | 10-50ms | Limited by relay bandwidth |
| Subnet Routed | +1 hop | Same as direct minus routing overhead |
| Exit Node | Varies by location | Same as direct to exit node |
Self-Hosting with Headscale
If you want to run everything yourself and avoid depending on Tailscale’s cloud, Headscale is an open-source implementation of the Tailscale coordination server. The latest release as of early 2026 is v0.26.1.
What Headscale Replaces
Headscale implements the Tailscale coordination API. Your devices still run the official Tailscale client but point to your Headscale server instead of controlplane.tailscale.com. Key distribution, peer discovery, and ACL enforcement all happen on your infrastructure. All traffic remains peer-to-peer WireGuard - the coordination server never touches data plane traffic.
Deployment
Run Headscale as a Docker container or systemd service on a VPS with a public IP. It needs a database (SQLite for small deployments, PostgreSQL for larger ones) and TLS, either through a reverse proxy like Caddy or directly via Let’s Encrypt. Expose it on port 443 for client communication.
docker run -d \
--name headscale \
-v /etc/headscale:/etc/headscale \
-v /var/lib/headscale:/var/lib/headscale \
-p 443:443 \
headscale/headscale:0.26 \
serveClient Configuration
Point each device to your Headscale instance:
tailscale up --login-server=https://headscale.example.comGenerate auth keys with the Headscale CLI:
headscale preauthkeys create --user myuserExisting Tailscale users must re-authenticate when switching to Headscale. There is no seamless migration path - each device needs to log out of the Tailscale control plane and re-register with Headscale.
What You Lose with Headscale
Headscale covers the core feature set: MagicDNS, ACLs (via a local acl.yaml file), tagging, and OIDC authentication. What is missing compared to the Tailscale SaaS:
- No Funnel or Serve features
- No built-in admin web UI (use the
headscaleCLI or the community Headscale-UI project) - No Tailscale SSH integration
- DERP relays must be self-hosted (or you can use Tailscale’s public DERP servers, which still work with Headscale)
Running Your Own DERP Relay
Deploy derper (from the Tailscale GitHub repository
) on a VPS in each region you need. Configure Headscale’s derp.yaml to point to your custom DERP servers. This eliminates any dependency on Tailscale infrastructure, giving you a fully self-contained mesh network.
When to Self-Host
Self-host with Headscale if you need full data sovereignty, have compliance requirements, or simply want zero external dependencies. Stick with Tailscale SaaS if you value the web UI, Funnel, Tailscale SSH, and automatic DERP infrastructure. The free tier’s 100-device limit is generous enough for most homelabs, so the decision usually comes down to principle rather than practical limitations.
Troubleshooting Common Issues
A few problems come up regularly when running Tailscale.
Connections Show “Relayed” When They Should Be Direct
Run tailscale netcheck to diagnose. Common causes are UDP port 41641 being blocked by a firewall, symmetric NAT on both ends (direct connection is impossible), or a corporate firewall doing deep packet inspection. Opening UDP 41641 inbound on at least one side usually fixes it.
DNS Resolution Failures with MagicDNS
If MagicDNS names do not resolve, check that your global nameservers in the admin console are accessible from all devices. If you use an exit node, DNS queries route through the exit node, so the exit node must be able to reach the configured nameservers. DNS rebinding protection on some home routers can also interfere - MagicDNS itself is not affected by rebinding protection, but split DNS pointing to local resolvers can trigger it.
Tailscale on Home Assistant
Install the Tailscale add-on from the Home Assistant add-on store. Once connected, your Home Assistant instance is reachable at its 100.x.y.z address on port 8123 from any device in your tailnet. For family members without Tailscale, use Funnel to expose Home Assistant via a public *.ts.net HTTPS URL. Add homeassistant to the trusted_proxies configuration to avoid authentication issues when accessed through Tailscale.
Subnet Routes Not Working
After advertising routes with --advertise-routes, you must approve them in the admin console under the machine’s route settings. On the subnet router machine itself, IP forwarding must be enabled (sysctl net.ipv4.ip_forward=1). If traffic still does not flow, check that the target devices have a route back to the subnet router, or that the subnet router is performing NAT (masquerade) for the Tailscale traffic.