Tailscale VPN Installation and Configuration

Tailscale is a zero-configuration mesh VPN built on WireGuard that connects your devices securely without complex firewall rules or NAT traversal headaches. By authenticating through your identity provider, Tailscale automatically manages keys and routing, making it ideal for connecting VPS servers, home labs, and remote machines into a single private network.

Prerequisites

  • Ubuntu 20.04+, Debian 11+, CentOS 8+, or Rocky Linux 8+
  • Root or sudo access
  • A Tailscale account (free tier supports up to 100 devices)
  • Outbound internet access (TCP 443 for coordination, UDP 41641 for WireGuard)

Installing Tailscale

Ubuntu/Debian:

# Add Tailscale's package repository
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.noarmor.gpg | \
  sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg > /dev/null

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.tailscale-keyring.list | \
  sudo tee /etc/apt/sources.list.d/tailscale.list

sudo apt update && sudo apt install -y tailscale

CentOS/Rocky Linux:

# Add the Tailscale repo and install
sudo dnf config-manager --add-repo https://pkgs.tailscale.com/stable/rhel/9/tailscale.repo
sudo dnf install -y tailscale

# Enable and start the service
sudo systemctl enable --now tailscaled

Enable IP forwarding (required for subnet routing and exit nodes):

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Authentication and Device Authorization

Start Tailscale and authenticate the device:

# Start the Tailscale daemon
sudo systemctl enable --now tailscaled

# Authenticate - this outputs a URL to open in your browser
sudo tailscale up

# For headless servers, use auth keys from the admin console
sudo tailscale up --authkey=tskey-auth-xxxxx

# Check connection status
tailscale status

Creating reusable auth keys:

  1. Go to the Tailscale admin console at https://login.tailscale.com/admin/settings/keys
  2. Click Generate auth key
  3. Choose reusable, pre-authorized, or ephemeral based on your use case
  4. Use the key with --authkey flag for automated deployments
# Check which IP this node received
tailscale ip -4

# Verify connectivity to another node
tailscale ping <node-name>

Subnet Routing

Expose an entire LAN subnet to your Tailscale network without installing Tailscale on every host:

# Advertise your local subnet (e.g., 192.168.1.0/24)
sudo tailscale up --advertise-routes=192.168.1.0/24

# For multiple subnets
sudo tailscale up --advertise-routes=192.168.1.0/24,10.0.0.0/8

Approve the subnet in the admin console under Machines > Edit route settings, then enable it on clients:

# Accept advertised routes on other nodes
sudo tailscale up --accept-routes

Exit Nodes

Route all internet traffic through a Tailscale node (useful for VPS-based secure browsing):

# Advertise this node as an exit node
sudo tailscale up --advertise-exit-node

# Approve in admin console, then use it on a client
sudo tailscale up --exit-node=<node-ip-or-name>

# To only route DNS through the exit node
sudo tailscale up --exit-node=<node-ip-or-name> --exit-node-allow-lan-access

ACL Policies

Tailscale ACLs (Access Control Lists) restrict which devices can communicate. Edit the policy in the admin console under Access Controls:

{
  "acls": [
    {
      "action": "accept",
      "src": ["group:servers"],
      "dst": ["group:servers:22"]
    },
    {
      "action": "accept",
      "src": ["tag:web"],
      "dst": ["*:80,443"]
    }
  ],
  "groups": {
    "group:servers": ["[email protected]"]
  },
  "tagOwners": {
    "tag:web": ["[email protected]"]
  }
}

Apply tags to nodes during authentication:

sudo tailscale up --advertise-tags=tag:web --authkey=tskey-auth-xxxxx

MagicDNS and SSH over Tailscale

MagicDNS assigns human-readable hostnames like my-server.example-org.ts.net:

# Enable MagicDNS in admin console under DNS settings
# Then verify resolution
tailscale status --json | jq '.Peer | to_entries[] | .value.DNSName'

# SSH using MagicDNS hostname
ssh [email protected]

Tailscale SSH replaces traditional SSH key management:

# Enable Tailscale SSH on a node
sudo tailscale up --ssh

# Then SSH without any key configuration
ssh user@my-server

Add SSH ACL rules in the admin console:

{
  "ssh": [
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["tag:servers"],
      "users": ["root", "ubuntu"]
    }
  ]
}

Troubleshooting

Node not connecting:

# Check daemon logs
sudo journalctl -u tailscaled -f

# Force re-authentication
sudo tailscale logout && sudo tailscale up

# Check if UDP port is blocked
sudo tailscale netcheck

Subnet routes not working:

# Verify routes are advertised
tailscale status --json | jq '.Self.AdvertisedRoutes'

# Check IP forwarding is enabled
sysctl net.ipv4.ip_forward

# Ensure routes are approved in the admin console
tailscale status

High latency / DERP relay usage:

# Check which relay is being used
tailscale netcheck

# Ping a specific node
tailscale ping --verbose <node-name>

Firewall blocking direct connections:

# Allow WireGuard UDP traffic
sudo ufw allow 41641/udp

# For firewalld
sudo firewall-cmd --add-port=41641/udp --permanent && sudo firewall-cmd --reload

Conclusion

Tailscale provides a production-ready mesh VPN with minimal configuration, leveraging WireGuard's security while adding centralized access control through ACL policies, MagicDNS, and native SSH support. For VPS deployments, combining subnet routing with exit nodes and granular ACLs creates a robust private network that scales from single-server setups to complex multi-site infrastructures without exposing services to the public internet.