Introduction
When managing 5 VPS, 2 workstations, 1 NAS and 3 Raspberry Pis spread across multiple networks, configuring a classic VPN (OpenVPN, manual WireGuard) becomes hell: keys, NAT, port forwarding, hub-and-spoke...
Tailscale radically simplifies:
- You install an agent on each machine
- You log in with your Google/Microsoft/Github account
- All your machines appear in a virtual private network
- Each machine has a stable private IP (100.x.x.x or Tailnet IPv6)
- Automatic NAT traversal (WebRTC-style)
- No central server to manage (Tailscale hosts the control plane)
Architecture: peer-to-peer mesh. Each machine establishes a direct WireGuard tunnel with others. Tailscale is just the "ID card" that lets them find each other.
Prerequisites
- Free Tailscale account (up to 100 machines, 3 users)
- Linux/Windows/macOS/iOS/Android machines to connect
- Admin/root access on each machine
Step 1: Create a Tailscale account
- Sign up at https://tailscale.com (free for personal/small-pro use)
- You get a tailnet (personal network): e.g.
mathys.github.ts.net - Log in with Google, Microsoft, GitHub, or Okta
Step 2: Install Tailscale on a Linux VPS
curl -fsSL https://tailscale.com/install.sh | sh
Start and authenticate:
sudo tailscale up
A URL appears: open it in your browser, validate. Machine appears in your tailnet.
Check:
sudo tailscale status
Typical output:
100.64.0.1 srv-web-01 mathys@ linux -
100.64.0.2 srv-db-01 mathys@ linux -
100.64.0.3 laptop mathys@ macos active; direct...
Step 3: Connect other machines
Windows
Download installer: https://tailscale.com/download
macOS
Mac App Store or: brew install --cask tailscale
iOS / Android
App Store / Play Store → "Tailscale"
On each machine, log in with the same account (otherwise they don't see each other).
Step 4: Communication between machines
Once two machines are in the tailnet:
# From srv-web-01
ping 100.64.0.2
# SSH connection
ssh [email protected]
You can also use MagicDNS (enabled by default):
ping srv-db-01
ssh user@srv-db-01
Names are Tailscale hostnames, accessible from any tailnet machine.
Step 5: Disable periodic auth (personal keys)
By default, machines must re-authenticate every 180 days. For servers, you want permanent:
- In Tailscale admin → Machines
- Click the machine → Disable key expiry
Or in CLI:
sudo tailscale up --advertise-tags=tag:server
Combined with reusable auth keys (see step 6).
Step 6: Auth Keys (to automate deployment)
To install Tailscale on 20 VPS without clicking 20 auth links:
- In Tailscale → Settings → Keys → Generate auth key
- Check:
- Reusable (usable on multiple machines)
- Ephemeral: no (otherwise machine deleted on disconnect)
- Pre-authorized: yes
- Expiration: 90 days for example
- Tags:
tag:server
You get tskey-auth-XXXXXX.
On each new VPS:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --authkey=tskey-auth-XXXXXX --advertise-tags=tag:server
Machine auto-appears in your tailnet, no interaction.
Step 7: ACLs (who can access who)
In Tailscale admin → Access controls. Language is JSON.
Example: isolate servers from clients
{
"tagOwners": {
"tag:server": ["mathys@github"],
"tag:client": ["mathys@github"]
},
"acls": [
// Mathys (admin) accesses everything
{
"action": "accept",
"src": ["mathys@github"],
"dst": ["*:*"]
},
// Servers can see each other
{
"action": "accept",
"src": ["tag:server"],
"dst": ["tag:server:*"]
},
// Clients do NOT see servers (default deny)
]
}
Click Save. ACLs applied in <10 seconds.
Step 8: Subnet Router (extend access to a site's LAN)
You have a home VPN with a NAS at 192.168.1.50. You want all your tailnet to access the NAS without installing Tailscale on the NAS itself.
On a LAN machine (e.g. Raspberry Pi at 192.168.1.10):
sudo tailscale up --advertise-routes=192.168.1.0/24
Enable IP forwarding:
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
In Tailscale admin → Machines → Raspberry Pi → Edit route settings → check 192.168.1.0/24.
Now all your other tailnet machines can reach 192.168.1.50 directly.
Step 9: Exit Node (route all your traffic via a VPS)
To use a VPS as internet exit (like a classic VPN):
On VPS:
sudo tailscale up --advertise-exit-node
Enable in admin → Edit → Use as exit node.
On a client (laptop, mobile):
sudo tailscale up --exit-node=srv-web-01
All your traffic now goes through the VPS. Ideal for bypassing wifi restrictions or anonymizing.
Step 10: Tailscale SSH (replaces SSH keys)
Tailscale can act as an SSH bastion: no key management.
On servers:
sudo tailscale up --ssh
Now, from your tailnet laptop:
ssh root@srv-web-01
No password, no key: Tailscale auto-authenticates with your identity (Google/Microsoft).
ACLs for SSH
{
"ssh": [
{
"action": "check",
"src": ["mathys@github"],
"dst": ["tag:server"],
"users": ["root", "ubuntu", "mathys"]
}
]
}
"check" requires auth re-validation every 12h. "accept" allows without check.
Step 11: Funnel (expose a service to internet via Tailscale)
Tailscale Funnel exposes a tailnet service to internet (like Cloudflare Tunnel):
# Activate on machine
sudo tailscale serve --bg --https=443 http://localhost:3000
# Expose to internet
sudo tailscale funnel 443 on
Your service is accessible at https://srv-web-01.mathys.github.ts.net. SSL cert auto-managed by Tailscale.
⚠️ Funnel is limited to ports 443, 8443, 10000. Not for exposing everything in prod.
Step 12: Stats and monitoring
# Detailed status
sudo tailscale status
# Network stats (latency, throughput, direct peer or via DERP relay)
sudo tailscale netcheck
# Machine's Tailscale IPs
sudo tailscale ip -4
sudo tailscale ip -6
# Verify connectivity with a peer
sudo tailscale ping srv-db-01
# Detailed logs
sudo journalctl -u tailscaled -f
Step 13: Tailnet config backup
To export your config (ACLs, machines, tags):
- Settings → Tailnet policy file → Export button
- Download the JSON
To automate (via Tailscale API):
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://api.tailscale.com/api/v2/tailnet/mathys.github.ts.net/acl > acl-backup.json
Troubleshooting
"no route to host" between 2 tailnet machines
Check status:
sudo tailscale status
If you see idle; relay "derp...", NAT traversal failed → traffic goes through Tailscale relays (DERP), slower but works. To force direct, open UDP 41641 on firewall.
"tailscaled.service failed to start"
sudo systemctl status tailscaled
sudo journalctl -u tailscaled -n 50
Often an initial network issue. Reset:
sudo tailscale down
sudo tailscale up
Machine appears expired
Go to admin → Disable key expiry on the machine.
IP conflicts with your local LAN
Tailscale uses 100.64.0.0/10 by default. If your LAN uses this range, conflict. Solution: change Tailscale range (Settings → Network) or change your LAN.
Degraded performance
sudo tailscale netcheck
If JustOK or Bad, no direct peering is possible. Causes: double symmetric NAT, firewall, MTU mismatch.
Useful commands
# Up / Down
sudo tailscale up
sudo tailscale down
# Status
sudo tailscale status
sudo tailscale status --json
# Detailed info
sudo tailscale netcheck
# List peers
sudo tailscale status --peers
# Disable DNS (if conflict)
sudo tailscale up --accept-dns=false
# Set custom hostname
sudo tailscale up --hostname=my-custom-name
# Full reset
sudo tailscale logout
sudo tailscale up
# Remove Tailscale
sudo apt purge tailscale -y
Conclusion
Tailscale eliminates VPN complexity:
- Setup: 1 command to join the tailnet
- Security: WireGuard + enterprise SSO auth
- Performance: direct peer-to-peer when possible
- ACLs: fine control by tag/user
- Free tier: 100 machines, 3 users
Ideal for:
- Multi-VPS fleet administration
- Lab access from anywhere
- Inter-site/client connection
- Replacement of corporate OpenVPN
Going further:
- Headscale: open-source implementation of Tailscale control plane (self-hosted, free unlimited)
- NetBird: similar alternative, open-source mesh
- Pure WireGuard: if you want 100% self-hosted without agent (see dedicated guide)
Resources
- Headscale (self-host alternative): https://github.com/juanfont/headscale
- VeryCloud guide — WireGuard VPN:
/docs/article/wireguard - VeryCloud guide — Reverse SSH:
/docs/article/reverse-ssh - VeryCloud guide — SSH hardening:
/docs/article/ssh-hardening

















