Introduction to Tailscale VPN
Tailscale is a modern, zero-config VPN built on top of WireGuard that creates secure, peer-to-peer connections between your devices. Unlike traditional VPNs that route all traffic through a central server, Tailscale establishes direct encrypted tunnels between nodes, creating what it calls a "tailnet" โ your own private network overlay on top of the public internet.
What Makes Tailscale Different
Traditional VPNs require complex configuration, certificate management, and often suffer from performance bottlenecks because all traffic funnels through a single gateway. Tailscale takes a fundamentally different approach by leveraging WireGuard's lightweight protocol and automating key exchange, peer discovery, and connection negotiation.
- Zero configuration: No manual key management or firewall rules required
- Peer-to-peer connections: Direct device-to-device tunnels when possible
- Identity-based access: Integrates with OAuth providers like Google, GitHub, and Microsoft
- NAT traversal: Automatically punches through most NAT and firewall configurations
- Mesh networking: Every device can talk directly to every other device
Why Tailscale Matters for Developers
For development teams, Tailscale solves several persistent infrastructure problems. Whether you need to access a staging database from your local machine, share a localhost development server with a colleague, or securely connect to cloud resources without exposing them publicly, Tailscale provides a clean solution.
Common Use Cases
- Accessing private cloud databases and services without bastion hosts
- Sharing local development environments with team members
- Connecting to on-premises infrastructure from remote locations
- Securing CI/CD pipelines with private network access
- Managing IoT devices and edge computing infrastructure
- Replacing traditional site-to-site VPNs for distributed teams
Installing Tailscale
Tailscale supports all major operating systems. The installation process varies by platform but the core experience remains consistent.
Installing on Linux
For most Linux distributions, use the official installation script:
curl -fsSL https://tailscale.com/install.sh | sh
For Ubuntu or Debian specifically, you can add the repository manually:
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update
sudo apt-get install tailscale
Installing on macOS
On macOS, you can install via Homebrew or download the app directly:
brew install tailscale
Alternatively, download the standalone app from the Mac App Store for a GUI-based experience.
Installing on Windows
Download the installer from the Tailscale website or use winget:
winget install tailscale.tailscale
Installing via Docker
For containerized environments, run Tailscale with the official image:
docker run -d --name=tailscale \
-v /var/lib/tailscale:/var/lib/tailscale \
-v /dev/net/tun:/dev/net/tun \
--network=host \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
tailscale/tailscale:latest
Initial Setup and Authentication
Once installed, start Tailscale and authenticate your device. This process links the machine to your tailnet using your identity provider.
Starting Tailscale on Linux
sudo tailscale up
This command outputs a URL. Open it in your browser to authenticate using your configured identity provider (Google, GitHub, Microsoft, etc.). Once authenticated, the device joins your tailnet and receives a stable IP address.
Authenticating with an Auth Key
For headless servers or automated deployments, use a pre-generated auth key instead of interactive browser authentication:
sudo tailscale up --authkey=tskey-auth-xxxxxxxxxxxxxxxxxxxxxxxx
Generate auth keys from the Tailscale admin console at https://login.tailscale.com/admin/settings/keys. You can create reusable keys, single-use keys, or ephemeral keys for temporary nodes.
Verifying Your Connection
tailscale status
This command displays all devices on your tailnet, their IP addresses, online status, and connection type. You should see your current device listed along with any other connected nodes.
# Example output
100.64.1.12 dev-laptop user@example.com linux -
100.64.1.45 prod-server user@example.com linux idle
100.64.2.10 macbook user@example.com macOS active
Core Configuration
Enabling SSH
Tailscale SSH allows you to connect to machines without managing SSH keys. The authentication happens through your Tailscale identity:
sudo tailscale up --ssh
Once enabled on a node, you can SSH into it from any other authenticated device:
ssh user@prod-server
ssh user@100.64.1.45
You can use either the machine name or its Tailscale IP address.
Exit Nodes
An exit node routes all your internet traffic through another Tailscale device, similar to a traditional VPN. This is useful for accessing region-restricted content or securing traffic on untrusted networks.
To configure a device as an exit node:
sudo tailscale up --advertise-exit-node
Then, from another device, use that exit node:
sudo tailscale up --exit-node=prod-server
Approve the exit node in the admin console before it becomes available for use.
Subnet Routers
Subnet routers expose entire network subnets to your tailnet, allowing access to non-Tailscale devices on a local network:
sudo tailscale up --advertise-routes=192.168.1.0/24,10.0.0.0/16
On the client side, accept the advertised routes:
sudo tailscale up --accept-routes
This is particularly useful for accessing on-premises infrastructure, cloud VPCs, or home networks without installing Tailscale on every device.
Access Control Lists (ACLs)
Tailscale ACLs define which devices can communicate with each other and on which ports. You configure them in the admin console as a JSON document.
Default ACL Configuration
By default, Tailscale allows all traffic between all devices. Here is a basic ACL that restricts access:
{
"tagOwners": {
"tag:server": ["user@example.com"],
"tag:dev": ["group:developers"]
},
"groups": {
"group:developers": ["alice@example.com", "bob@example.com"]
},
"acls": [
{
"action": "accept",
"src": ["group:developers"],
"dst": ["tag:server:22", "tag:server:443"]
},
{
"action": "accept",
"src": ["tag:server"],
"dst": ["tag:server:*"]
},
{
"action": "deny",
"src": ["*"],
"dst": ["tag:server:3306"]
}
]
}
Using Tags for Device Classification
Tags simplify ACL management by grouping devices by role rather than individual identity. Apply tags when bringing a device online:
sudo tailscale up --advertise-tags=tag:server
Tags are particularly powerful for production environments where individual users may change but the server roles remain constant.
Advanced Features
Tailscale Funnel
Tailscale Funnel exposes a local service to the public internet through Tailscale's relay servers, with automatic TLS certificates:
sudo tailscale funnel 8080
This makes your local port 8080 accessible via a public HTTPS URL. It is useful for testing webhooks or sharing a local development server temporarily.
Tailscale Serve
Tailscale Serve shares a local service with other devices on your tailnet without exposing it publicly:
sudo tailscale serve 3000
Other tailnet members can access the service at https://dev-laptop.tailnet-name.ts.net with automatic HTTPS.
DNS Configuration
Tailscale provides MagicDNS, which lets you refer to devices by name instead of IP. Enable it in the admin console under DNS settings. You can also configure custom DNS servers:
{
"dns": {
"nameservers": ["1.1.1.1", "8.8.8.8"],
"searchDomains": ["internal.example.com"],
"overrideLocalDNS": true
}
}
Node Attributes for Conditional Access
You can use node attributes in ACLs for more granular control:
{
"acls": [
{
"action": "accept",
"src": ["autogroup:members"],
"dst": ["autogroup:internet:*"]
},
{
"action": "accept",
"src": ["autogroup:members"],
"dst": ["autogroup:self:*"]
}
]
}
Autogroups like autogroup:members, autogroup:self, and autogroup:internet simplify common access patterns.
Automation and Infrastructure as Code
Using the Tailscale API
The Tailscale API lets you manage devices, ACLs, and settings programmatically. Here is an example of listing devices using curl:
curl -s https://api.tailscale.com/api/v2/tailnet/example.com/devices \
-H "Authorization: Bearer tskey-api-xxxxxxxxxxxx" | jq .
To remove a device from the tailnet:
curl -s -X DELETE \
https://api.tailscale.com/api/v2/device/nodeId12345 \
-H "Authorization: Bearer tskey-api-xxxxxxxxxxxx"
Terraform Integration
Use the Tailscale Terraform provider to manage your tailnet infrastructure:
terraform {
required_providers {
tailscale = {
source = "tailscale/tailscale"
version = "~> 0.13"
}
}
}
provider "tailscale" {
api_key = var.tailscale_api_key
tailnet = "example.com"
}
resource "tailscale_acl" "main" {
acl = jsonencode({
tagOwners = {
"tag:server" = ["user@example.com"]
}
acls = [
{
action = "accept"
src = ["tag:server"]
dst = ["tag:server:*"]
}
]
})
}
resource "tailscale_device_key" "server" {
reusable = false
ephemeral = false
preauthorized = true
tags = ["tag:server"]
}
Provisioning with Cloud-Init
For cloud instances, use cloud-init to automatically join the tailnet on first boot:
#cloud-config
runcmd:
- curl -fsSL https://tailscale.com/install.sh | sh
- tailscale up --authkey=tskey-auth-xxxxxxxx --advertise-tags=tag:server --accept-routes
Monitoring and Troubleshooting
Checking Connection Status
tailscale status
tailscale netcheck
The netcheck command provides detailed information about your network conditions, including NAT type, latency to relay servers, and whether direct connections are possible.
Debugging Connectivity Issues
tailscale ping prod-server
tailscale ping --until-direct=false prod-server
The ping command shows whether traffic flows directly or through a DERP relay server. If connections route through relays, check firewall settings or NAT configurations.
Viewing Logs
# Linux (systemd)
sudo journalctl -u tailscaled -f
# macOS
log stream --predicate 'process == "tailscaled"' --style compact
Common Issues and Solutions
- Devices cannot connect directly: Check for restrictive NATs or firewalls blocking UDP traffic. Tailscale will fall back to DERP relays, which are slower but functional.
- ACL changes not taking effect: ACLs apply immediately, but existing connections may persist. Restart Tailscale on affected devices if needed.
- Subnet routes not working: Ensure
--accept-routesis set on the client and the routes are approved in the admin console. - DNS resolution failures: Verify MagicDNS is enabled and check custom DNS server configurations in the admin console.
Best Practices
Security
- Use ACLs from day one โ never rely on the default allow-all policy in production
- Apply tags to devices for role-based access control instead of per-user rules
- Use ephemeral auth keys for temporary or CI/CD nodes to prevent stale credentials
- Enable Tailscale SSH to eliminate SSH key management overhead
- Regularly review device lists and remove inactive or decommissioned nodes
- Use device approval requirements so new nodes need manual authorization before joining
Performance
- Prefer direct connections by ensuring UDP traffic is allowed through firewalls
- Use subnet routers strategically to minimize the number of Tailscale client installations
- Monitor DERP relay usage โ heavy relay traffic indicates network configuration issues
- Consider geographic placement of exit nodes for latency-sensitive workloads
Operational Excellence
- Manage ACLs through version control and deploy via the API or Terraform
- Document your tailnet topology, including subnet routers and exit nodes
- Set up monitoring for critical Tailscale nodes using the API
- Create separate tailnets for different environments (development, staging, production)
- Use machine-based auth keys for servers and user-based authentication for personal devices
Conclusion
Tailscale represents a significant evolution in VPN technology, replacing complex configuration and brittle infrastructure with a clean, identity-driven approach to network connectivity. By building on WireGuard and automating the hard parts of peer-to-peer networking, it lets developers focus on building applications rather than managing network plumbing. Whether you are connecting a single developer laptop to a cloud database or building a mesh network across dozens of servers and locations, Tailscale provides the tools to do it securely and efficiently. Start with a simple two-device setup, gradually incorporate ACLs and tags as your needs grow, and leverage advanced features like subnet routers, exit nodes, and Funnel to build a private network that scales with your infrastructure. With proper planning around access control, key management, and monitoring, Tailscale can serve as the backbone of your development and production networking strategy for years to come.