- Published on
Tailscale 101: Complete Developer Reference Guide for Mesh VPN Networking
Tailscale 101: Complete Developer Reference Guide for Mesh VPN Networking
Tailscale is a WireGuard-based mesh VPN that makes secure networking dead simple. Instead of configuring firewall rules, managing VPN servers, or distributing SSH keys, Tailscale creates encrypted peer-to-peer connections between your devices with zero configuration. Whether you're connecting to a homelab from a coffee shop, linking cloud VMs across providers, or giving your CI/CD runners access to internal services — Tailscale handles the networking so you can focus on building.
This guide is a complete reference covering everything from Tailscale's architecture and full CLI reference to advanced features like ACLs, Tailscale SSH, Serve & Funnel, Docker integration, and troubleshooting. All information current as of February 2026.
Check out Starmorph Kit — starter kits and templates for building your next project faster.
Table of Contents
- What is Tailscale?
- Complete CLI Reference
- Installation
- MagicDNS
- ACLs (Access Control Lists)
- Tailscale SSH
- Tailscale Serve & Funnel
- Subnet Routers & Exit Nodes
- Taildrop (File Sharing)
- Tailscale on Proxmox
- Auth Keys
- Tailscale API
- Docker Integration
- Common Patterns
- Pricing Tiers
- Troubleshooting
What is Tailscale?
Tailscale is a WireGuard-based mesh VPN built to favor direct peer-to-peer (P2P) connections whenever possible. The architecture separates the control plane from the data plane:
- Control Plane: Hub-and-spoke design that carries virtually no traffic, only exchanging tiny encryption keys and policies. The coordination server is part of the control plane, not the data plane.
- Data Plane: Nearly all data is sent P2P over end-to-end encrypted WireGuard tunnels, not through any central server.
Coordination Server (Control Plane)
The coordination server manages authentication, node authorization, peer discovery, ACL enforcement, network map distribution, and encryption key exchange. It works as an exchange point of WireGuard public keys for nodes in the Tailscale network.
Communication Protocol: Modern clients use the Noise protocol (Noise_IK) for authenticated encryption. The control server advertises its own curve25519 public key, and client/server communicate via ECDH using small NaCl crypto_box messages.
Resilience: If the coordination server goes down, every Tailscale node caches its state in memory — all existing connections keep working.
Data Plane: WireGuard, DERP, NAT Traversal
Tailscale's base layer is the userspace Go variant of WireGuard (wireguard-go). Device private encryption keys never leave their respective nodes — the coordination server only collects and exchanges public keys.
DERP (Designated Encrypted Relay for Packets) is a TCP-based relay operating over TLS on port 443 that forwards encrypted packets when peers can't reach each other directly. Every connection technically begins via DERP, then upgrades to a direct link if possible. Internal metrics show >90% success rates for direct NAT traversal.
NAT Traversal combines STUN discovery, the Disco protocol for peer-to-peer discovery, racing strategy to find the fastest path, and adaptive heartbeats to maintain connections.
Peer Relays (October 2025)
Peer Relays let you designate your own nodes as dedicated traffic relays within your tailnet. Benefits include full control over capacity, no QoS throttling, and performance rivaling direct connections. Real-world improvements show ~150ms latency reduction and 12.5x throughput increase.
Routing preference order:
- Direct connection (NAT traversal succeeds)
- Peer relay connection (dedicated capacity)
- DERP relayed connection (shared infrastructure)
Complete CLI Reference
The Tailscale CLI uses the format: tailscale [flags] <subcommand> [command flags]
The CLI is a standalone binary acting as a LocalAPI client — all operations are performed by sending HTTP requests to the tailscaled daemon's LocalAPI endpoint.
Core Commands
tailscale up
Connect to Tailscale and join your tailnet.
tailscale up [flags]
Authentication & Identity:
--authkey=KEY— Use a pre-generated authentication key--hostname=NAME— Set device hostname
Networking:
--accept-routes— Accept subnet routes advertised by other nodes--advertise-routes=CIDR1,CIDR2— Advertise specific IP routes--advertise-exit-node— Advertise this node as an exit node--exit-node=IP|HOSTNAME— Route all non-Tailscale traffic through specified exit node--exit-node-allow-lan-access— Allow LAN access when using exit node--accept-dns— Accept DNS configurations from tailnet
Security:
--shields-up— Block all incoming connections over Tailscale--ssh— Enable Tailscale SSH on this device
Tags:
--advertise-tags=tag:server,tag:prod— Apply ACL tags
tailscale down
Disconnect from Tailscale without logging out.
tailscale down
tailscale set
Configure options persistently (survives restarts). Modern alternative to passing options to tailscale up — only updates explicitly specified fields.
tailscale set --accept-routes
tailscale set --advertise-exit-node
tailscale set --hostname myserver
tailscale set --ssh
tailscale status
Show state of tailscaled and its connections.
tailscale status # Table format
tailscale status --json # JSON output
tailscale status --active # Active connections only
Network Diagnostics
tailscale ip # Show Tailscale IPs (both IPv4/IPv6)
tailscale ip -4 # IPv4 only
tailscale ip -6 # IPv6 only
tailscale ping <host> # Ping at the Tailscale layer
tailscale netcheck # Analyze local network conditions
tailscale whois <IP> # Show machine/user for a Tailscale IP
tailscale ssh
SSH to a Tailscale machine using WireGuard authentication (no SSH keys needed).
tailscale ssh <hostname>
tailscale ssh user@hostname
tailscale nc
Netcat-like TCP connection through Tailscale.
tailscale nc <hostname> <port>
ssh -o ProxyCommand='tailscale nc %h %p' user@hostname.tailnet.ts.net
File Transfer & Sharing
tailscale file cp <file> <hostname>: # Send files via Taildrop
sudo tailscale file get # Receive files (Linux)
sudo tailscale file get --loop # Continuous receive mode
tailscale drive share <name> <path> # Share directory (Taildrive)
Service Exposure
tailscale serve 8080 # Serve on tailnet only
tailscale serve ~/public # Serve a directory
tailscale funnel 8080 # Expose to public internet
tailscale cert myserver.tailnet.ts.net # Get TLS certificate
Account & Maintenance
tailscale login # Log in
tailscale logout # Log out and expire node key
tailscale switch # Switch between accounts
sudo tailscale update # Update to latest version
tailscale version # Print version
tailscale bugreport # Generate shareable bug report ID
Installation
macOS
Three options:
- Download from Tailscale (recommended): Download the standalone variant from tailscale.com/download
- Mac App Store: Search for "Tailscale"
- CLI-only: Download from GitHub releases
Ubuntu / Debian
# Quick install (all versions)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Manual install:
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.gpg | sudo apt-key add -
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update
sudo apt-get install tailscale
sudo tailscale up
Supports Ubuntu 16.04 through 25.04 and Debian 9 through 12.
Raspberry Pi
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Supports Raspberry Pi OS (32-bit and 64-bit), Stretch, Buster, and Bullseye.
Docker
Official image: tailscale/tailscale (Docker Hub and GitHub Packages). See the Docker Integration section for usage patterns.
Post-Installation
After installing, connect to your tailnet:
sudo tailscale up
Follow the authentication URL to log in with your identity provider.
MagicDNS
MagicDNS automatically assigns DNS names to all devices in your tailnet — no need to track IP addresses.
- Enabled by default
- Local DNS resolution at 100.100.100.100
- Routes queries to appropriate upstream resolvers by domain suffix
Naming Convention
Tailnet name format: tail<hex>.ts.net
Nodes get automatic DNS names based on their hostnames with numeric suffixes for conflicts:
myserver.tail12abc.ts.net
laptop.tail12abc.ts.net
pi.tail12abc.ts.net
Custom Domains
You can use custom domains (e.g., app.example.com) for services, though this currently requires third-party DNS solutions or manual DNS configuration. Native naming uses the *.ts.net structure.
ACLs (Access Control Lists)
Tailscale ACLs are JSON-formatted rules controlling who can access what within your network. Default deny — access must be explicitly granted.
Core Components
- Groups — Collections of users
- Tags — Labels assigned to devices
- ACLs — Rules defining access
- SSH — SSH-specific rules
- Auto-approvers — Pre-grant permissions
Example ACL Policy
{
"groups": {
"group:engineering": ["user1@example.com", "user2@example.com"],
"group:ops": ["admin@example.com"]
},
"tagOwners": {
"tag:server": ["group:ops"],
"tag:database": ["group:ops"]
},
"acls": [
{
"action": "accept",
"src": ["group:engineering"],
"dst": ["tag:server:*"]
},
{
"action": "accept",
"src": ["group:ops"],
"dst": ["tag:database:5432"]
}
],
"ssh": [
{
"action": "accept",
"src": ["group:ops"],
"dst": ["tag:server"],
"users": ["ubuntu", "root"]
}
],
"autoApprovers": {
"routes": {
"10.0.0.0/8": ["ops@example.com"],
"192.168.0.0/24": ["tag:router"]
},
"exitNode": ["group:ops"]
}
}
Best Practices
- Use groups rather than individual users for easier onboarding/offboarding
- Tag servers by role —
tag:production,tag:staging,tag:database - Be specific — only grant the access needed
- Default deny — nothing is allowed unless explicitly granted
Tailscale SSH
Tailscale SSH establishes SSH connections between devices without managing SSH keys. It authenticates using WireGuard instead of passwords or SSH keys.
Setup
1. Enable on the target machine:
tailscale set --ssh
2. Configure ACL rules (see ACLs section for SSH rule examples).
3. Connect:
tailscale ssh hostname
tailscale ssh user@hostname
# Or use traditional SSH:
ssh user@hostname.tailnet.ts.net
Key Features
- SSO and MFA enforcement tied to your identity provider
- Session recording for compliance and forensics
- Centralized ACLs for access management
- No key management — no distributing, rotating, or revoking SSH keys
Tailscale Serve & Funnel
Tailscale Serve
Makes a local service accessible to devices in your tailnet only.
Prerequisites: Enable HTTPS Certificates in admin console, then run tailscale cert.
tailscale serve 8080 # Serve localhost:8080 on tailnet
tailscale serve https:443 / localhost:8080 # HTTPS on port 443
tailscale serve ~/public # Serve a directory
Tailscale Funnel
Makes a local service accessible to the entire internet.
When you turn on Funnel, Tailscale creates public DNS records for your node.tailnet.ts.net name, pointing to worldwide ingress servers.
tailscale funnel 8080 # Expose to public internet
Use cases: Testing OAuth callbacks, receiving webhooks, sharing dev environments temporarily.
Benefits: Public IP, DNS, TLS cert, and HTTPS server — all automatic.
Subnet Routers & Exit Nodes
Subnet Routers
Access resources on a remote network through your Tailscale connection.
Setup:
# 1. Enable IP forwarding (Linux)
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 2. Advertise routes
tailscale up --advertise-routes=192.168.1.0/24,10.0.0.0/8
# 3. Approve routes in admin console
# 4. Accept routes on client devices
tailscale set --accept-routes
Exit Nodes
Route all non-Tailscale internet traffic through a specific device.
# On the exit node:
tailscale up --advertise-exit-node
# On the client:
tailscale set --exit-node=<IP|hostname>
tailscale up --exit-node=<IP|hostname> --exit-node-allow-lan-access
Use cases: Encrypting traffic on public Wi-Fi, browsing from a different location, securing traffic through a trusted device.
Taildrop (File Sharing)
Transfer files between devices via encrypted P2P connections. Only sending and receiving devices have access.
CLI Usage
# Send
tailscale file cp myfile.txt myserver:
tailscale file cp document.pdf 100.64.0.5:
# Receive (Linux — must manually run)
sudo tailscale file get
sudo tailscale file get --loop # Continuous mode
macOS/Windows: Files automatically appear in Downloads folder. Mobile: Use the share menu and select Tailscale.
Interrupted transfers can resume where they left off for up to one hour.
Tailscale on Proxmox
Tailscale can run on the Proxmox host, VMs (straightforward), or LXC containers (requires special config).
LXC Container Setup
Tailscale needs /dev/net/tun, which is not allowed in LXC by default:
- Go to container Resources tab
- Select Add → Device Passthrough
- Enter
dev/net/tunin the Device Path field
Then install normally:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
VM Setup
Standard installation — no special configuration needed.
Auth Keys
Auth keys allow devices to join your tailnet automatically without interactive authentication.
| Type | Description | Use Case |
|---|---|---|
| Reusable | Can authenticate multiple servers | Batch server deployments |
| Ephemeral | Devices auto-removed when offline | Containers, serverless, CI/CD |
| Pre-authorized | Devices automatically approved | Automated deployments |
| Tagged | Device identity is the tag, not a user | Service accounts, IaC |
Using Auth Keys
tailscale up --authkey=tskey-auth-XXXXX
Create auth keys in Settings → Keys in the admin console, or via API with an OAuth client.
Tailscale API
Base URL: https://api.tailscale.com/api/v2
OAuth Scopes
devices:core— Read/write devices, authorize, manage tagsdns:read— Read DNS settingsacls:read/acls:write— Access control policiesroutes:read/routes:write— Subnet routes
Tokens expire after one hour.
Key Endpoints
# Get access token
curl -X POST https://api.tailscale.com/api/v2/oauth/token \
-u "client_id:client_secret" \
-d "grant_type=client_credentials"
# List devices
curl -H "Authorization: Bearer tstoken-XXXXX" \
https://api.tailscale.com/api/v2/tailnet/example.com/devices
Terraform Integration
Tailscale has an official Terraform provider:
resource "tailscale_acl" "example" {
acl = jsonencode({
acls = [
{
action = "accept"
src = ["group:engineering"]
dst = ["tag:server:*"]
}
]
})
}
Docker Integration
Tailscale runs in Docker using the sidecar pattern.
Docker Compose Example
version: '3.8'
services:
tailscale:
image: tailscale/tailscale:latest
hostname: myapp
environment:
- TS_AUTHKEY=${TS_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
volumes:
- tailscale-state:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
cap_add:
- NET_ADMIN
- SYS_MODULE
restart: unless-stopped
myapp:
image: myapp:latest
network_mode: service:tailscale
depends_on:
- tailscale
volumes:
tailscale-state:
The network_mode: service:tailscale setting routes all traffic for myapp through the Tailscale container. Each container becomes a fully-fledged node on your tailnet with its own DNS name.
Common Patterns
Homelab Networking
- Install Tailscale on your firewall (OPNsense, pfSense) as a subnet router
- Use sidecar containers to connect Docker services directly
- Combine with cloud instances for hybrid setups
Site-to-Site Networking
Connect two subnets using subnet routers on each side. Devices in the subnets don't need Tailscale installed.
CI/CD Integration
# GitHub Actions
- name: Connect to Tailscale
uses: tailscale/github-action@v4
with:
authkey: ${{ secrets.TAILSCALE_AUTHKEY }}
Tag runners by repository, team, or job type and define granular ACL policies.
Pricing Tiers
| Plan | Price | Devices | Best For |
|---|---|---|---|
| Free | $0 | Up to 100 | Personal use |
| Starter | $6/user/mo | 100 + (users x 10) | Small teams |
| Premium | $18/user/mo | 100 + (users x 10) | Growing teams |
| Enterprise | Contact | Custom | Organizations |
Free plan for qualifying open source GitHub organizations is also available.
Troubleshooting
Network Diagnostics
tailscale netcheck # Check UDP, DERP latency, NAT traversal
tailscale status --json # Detailed connection state
tailscale ping <hostname> # Test Tailscale-layer connectivity
DNS Issues
dns-forward-failinghealth warning: Check upstream resolver configuration- After WiFi changes: Tailscale may fail to set DNS resolvers — restart tailscaled
- Docker environments: In-container resolver needs upstream configured or returns SERVFAIL
Logs & Debugging
# Linux
sudo journalctl -u tailscaled
# Bug reports
tailscale bugreport
# Advanced debugging
tailscale debug localapi # Direct HTTP calls to LocalAPI
Firewall
In most cases, no firewall rules needed. If allowlisting is required, log.tailscale.com resolves to 199.165.136.0/24 (IPv4) and 2606:B740:1::/48 (IPv6).
Additional Security: Tailnet Lock
Tailnet lock verifies public keys distributed by the coordination server before trusting them. Nodes must be signed by a trusted tailnet lock key. This mitigates the risk of the coordination server being compromised.
tailscale lock [subcommand]
Shields Up
Block all incoming Tailscale connections while keeping outgoing connections functional:
tailscale set --shields-up
Tailscale eliminates the complexity of traditional VPN setups while providing enterprise-grade security through WireGuard encryption. Whether you're running a homelab, connecting cloud infrastructure, or securing CI/CD pipelines, Tailscale's zero-config mesh networking gets you connected in minutes. The free tier supports up to 100 devices — more than enough for most developers and small teams to build a complete private network.