Mesh VPN Server

    Deploy Headscale on RamNode VPS

    Self-hosted Tailscale coordination server with WireGuard-based mesh VPN. Complete control over your mesh network with no device limits or subscription fees.

    Ubuntu 24.04 LTS
    WireGuard
    ⏱️ 15-20 minutes

    Why Self-Host with Headscale?

    • Complete data sovereignty: Your server, your control
    • No device limits: Connect unlimited devices
    • No subscription fees: Just your VPS cost
    • Full customization: ACLs, DNS, network policies
    • Compatible clients: Works with official Tailscale apps
    • WireGuard-based: Modern, fast, secure VPN protocol

    Prerequisites

    Before starting, ensure you have:

    VPS Requirements

    • • Ubuntu 24.04 LTS or Debian 12+
    • • 1GB RAM minimum
    • • 1 vCPU
    • • 10GB+ SSD storage

    Additional Requirements

    • • Domain pointing to VPS IP
    • • (e.g., headscale.yourdomain.com)
    • • SSH root or sudo access
    • • Basic Linux knowledge
    RequirementSpecification
    RamNode VPS1GB RAM, 1 vCPU, 10GB storage
    Operating SystemUbuntu 24.04 LTS or Debian 12+
    Domain NameSubdomain pointing to VPS IP
    SSH AccessRoot or sudo access
    2

    System Preparation

    Connect to your RamNode VPS via SSH and update the system:

    Update and Upgrade System
    sudo apt update && sudo apt upgrade -y
    Install Essential Dependencies
    sudo apt install -y curl wget gnupg apt-transport-https
    3

    Install Headscale

    Headscale provides official .deb packages for Debian-based systems:

    Get Latest Version & Download
    # Get latest version
    VERSION=$(curl -s "https://api.github.com/repos/juanfont/headscale/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/v//')
    echo "Installing Headscale v${VERSION}"
    
    # Download the .deb package
    wget -O headscale.deb "https://github.com/juanfont/headscale/releases/download/v${VERSION}/headscale_${VERSION}_linux_amd64.deb"
    Install the Package
    sudo apt install -f ./headscale.deb

    What the Package Creates:

    • A dedicated headscale user
    • Configuration directory at /etc/headscale/
    • A systemd service file for automatic startup
    4

    Configure Headscale

    Edit the main configuration file:

    Open Configuration File
    sudo nano /etc/headscale/config.yaml
    SettingValue
    server_urlhttps://headscale.yourdomain.com
    listen_addr0.0.0.0:8080
    metrics_listen_addr127.0.0.1:9090
    database.typesqlite (recommended)
    database.path/var/lib/headscale/db.sqlite
    Example Minimal Configuration
    server_url: https://headscale.yourdomain.com
    listen_addr: 0.0.0.0:8080
    metrics_listen_addr: 127.0.0.1:9090
    
    database:
      type: sqlite
      path: /var/lib/headscale/db.sqlite
    
    prefixes:
      v4: 100.64.0.0/10
      v6: fd7a:115c:a1e0::/48
    
    dns:
      magic_dns: true
      base_domain: ts.yourdomain.com
      nameservers:
        global:
          - 1.1.1.1
          - 8.8.8.8
    5

    Set Up Reverse Proxy with Caddy

    Caddy provides automatic HTTPS with Let's Encrypt certificates:

    Install Caddy
    sudo apt install -y debian-keyring debian-archive-keyring
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
    sudo apt update
    sudo apt install caddy
    Configure Caddy
    sudo nano /etc/caddy/Caddyfile
    Caddyfile Configuration
    headscale.yourdomain.com {
        reverse_proxy localhost:8080
    }
    Restart Caddy
    sudo systemctl restart caddy
    6

    Configure Firewall

    Open the necessary ports using UFW:

    Open Firewall Ports
    sudo ufw allow 80/tcp      # HTTP (for Let's Encrypt)
    sudo ufw allow 443/tcp     # HTTPS
    sudo ufw allow 22/tcp      # SSH (don't lock yourself out!)
    sudo ufw enable

    ⚠️ Important: Make sure you allow SSH (port 22) before enabling UFW to avoid locking yourself out of your server.

    7

    Start Headscale

    Enable and start the Headscale service:

    Enable and Start Service
    sudo systemctl enable headscale
    sudo systemctl start headscale
    Verify Service Status
    sudo systemctl status headscale

    Verify Web Accessibility:

    Visit https://headscale.yourdomain.com/windows in your browser—this should show client setup instructions.

    8

    Create Users and Pre-Auth Keys

    In Headscale, 'users' are equivalent to Tailscale's 'tailnets':

    Create a User
    sudo headscale users create myuser
    List Existing Users
    sudo headscale users list
    Generate Pre-Authentication Key
    sudo headscale preauthkeys create --user myuser --reusable --expiration 24h

    Pre-Auth Key Options

    • --reusable: Key can be used for multiple devices
    • --expiration: Set key validity period (e.g., 24h, 7d)
    • --ephemeral: Nodes will be removed when they go offline
    9

    Connect Clients

    Install the official Tailscale client and connect to your Headscale server:

    Linux

    Install Tailscale Client
    curl -fsSL https://tailscale.com/install.sh | sh
    Connect with Pre-Auth Key
    sudo tailscale up --login-server=https://headscale.yourdomain.com --authkey=YOUR_PREAUTH_KEY

    Interactive Registration (Without Pre-Auth Key)

    Connect Interactively
    sudo tailscale up --login-server=https://headscale.yourdomain.com

    This opens a browser with a registration URL containing your machine key. On your Headscale server, approve the registration:

    Approve Registration
    sudo headscale nodes register --user myuser --key YOUR_MACHINE_KEY

    Windows / macOS / iOS / Android

    Download the official Tailscale client from tailscale.com/download. When prompted to log in, use your Headscale server URL or configure the --login-server parameter.

    10

    Verify Connectivity

    Confirm your mesh network is working:

    List All Registered Nodes
    sudo headscale nodes list
    Check Client Status
    tailscale status

    Test Connectivity

    Ping another device on your tailnet using its Tailscale IP (e.g., 100.64.x.x) or MagicDNS hostname.

    Optional

    Install Headscale-UI

    For a graphical management interface, deploy the community-maintained Headscale-UI:

    Generate API Key
    sudo headscale apikeys create
    Deploy Headscale-UI with Docker
    docker run -d \
      --name headscale-ui \
      -p 8443:443 \
      ghcr.io/gurucomputing/headscale-ui:latest

    ⚠️ Note: Headscale-UI must be served on the same subdomain as Headscale (or use CORS headers via reverse proxy) to function properly.

    Troubleshooting

    Service Won't Start

    Check Logs
    sudo journalctl -u headscale -f

    Configuration Validation

    Validate Config
    sudo headscale configtest

    Client Won't Connect

    • Ensure your domain's DNS A record points to your VPS IP
    • Verify Caddy obtained SSL certificates (check /var/log/caddy/)
    • Check that ports 80 and 443 are open
    • Confirm the server_url in config.yaml matches your actual domain

    Maintenance and Backups

    Regular backups ensure you can recover your network configuration:

    Backup Database and Configuration
    # Backup the database
    sudo cp /var/lib/headscale/db.sqlite /backup/headscale-$(date +%Y%m%d).sqlite
    
    # Backup configuration
    sudo cp /etc/headscale/config.yaml /backup/

    Upgrading Headscale

    To upgrade, download the new .deb package and install it, then restart the service. Always check the release notes for breaking changes between versions.

    Deployment Complete!

    You now have a fully functional Headscale server running on your RamNode VPS, providing complete control over your mesh VPN infrastructure. Your devices can securely communicate with each other regardless of their physical location, without relying on third-party coordination services.

    For advanced configurations including ACL policies, subnet routing, exit nodes, and OIDC authentication, refer to the official Headscale documentation.