
Headscale is an open-source, self-hosted implementation of the Tailscale control plane. It provides a private WireGuard-based mesh VPN that connects devices and services across different environments. Unlike traditional VPNs that force traffic through a central gateway, Headscale with Tailscale establishes peer-to-peer tunnels for secure, low-latency communication.
This guide shows how to extend a Vultr based Headscale mesh to include on-premises servers. By enrolling a local server or workstation (for example, macOS or Linux on your LAN), you can advertise your private subnet and make it accessible to Vultr workloads. The result is a hybrid mesh network where Vultr VPCs and your local network operate as a single secure environment.
Before you begin, you need to:
You will first deploy the Headscale control server and provision a multi-region Vultr mesh using Terraform and Ansible. This provides the foundation on which you can extend the network to your on-premises.
Clone the Vultr code samples repository and navigate into the VPC peering project directory.
Open the terraform.tfvars file and add your Vultr API Key. You can also adjust regions, instance plans, or subnets as needed.
Example variables:
The following command uses curl to fetch all Vultr regions along with their identifiers using the public API.
Initialize the Terraform working directory.
Apply the manifests to create the infrastructure. When prompted, type yes to approve.
This may take several minutes. When finished, Terraform displays output with the public and private IPs of the provisioned instances and the Headscale control server.
Your output should be similar to the one below:
Navigate to the Ansible directory.
Run the playbook to configure the Headscale server and enroll the Vultr gateways into the mesh.
To manually add more clients to the mesh network through VPC, select the VPC network and Startup Script named headscale-mesh-init-script while provisioning a new instance.
The script currently supports only Debian and RHEL based distributions. For other distributions, you can manually configure FRR or add static routes to integrate them into the private mesh network.
At this stage, your Vultr VPCs are connected through a private WireGuard-based mesh coordinated by Headscale. You can now extend this mesh to include your on-premises servers and services.
To connect an on-premises machine to your Headscale mesh, you first need to create a Headscale user and generate a reusable authentication key.
SSH into the Headscale control server.
Replace <headscale_ip> with the public IP of the headscale server from the Terraform output.
Create a new Headscale user. You can replace on-prem with any username you prefer.
Generate a pre-authentication key for the user. This allows the on-premises client to join without an interactive login. The following example creates a key valid for 24 hours.
Copy the generated key and store it securely for later use.
Pre-authentication keys are shown only once at creation time. If you lose the key, generate a new one.
On your on-premises Ubuntu server, run a single script that installs Tailscale, FRR, enables IP forwarding, configures OSPF, and syncs Tailscale routes into the main table. Then connect it to Headscale and advertise your local subnet.
Download and run the on-prem router script.
Connect the router to Headscale. Replace the placeholders with your actual values.
<headscale_ip>: The public IP of your Headscale server (from Terraform output).<AUTHKEY>: The pre-authentication key you created earlier.<LOCAL_SUBNET>: The local subnet to advertise (for example, 192.168.1.0/24).When a new peer advertises a local subnet (for example, your on-premises LAN 192.168.1.0/24), Headscale requires an administrator to approve the route before it is enabled. This prevents unauthorized clients from injecting routes into your mesh.
Return to the Headscale control server terminal.
List all routes advertised by peers.
Your output should be similar to the one below:
Here, the on-premises server (on-prem-server) is advertising 192.168.1.0/24 but the route is not yet enabled.
Approve the new route by referencing its ID.
Replace 3 with the actual route ID from your environment.
Verify the route is now active.
Output should show the Enabled column as true:
At this point, the on-premises LAN (192.168.1.0/24) is fully reachable across your Vultr Headscale mesh.
After deployment, verify that all regions and your on-premises server are connected through the WireGuard-based mesh managed by Headscale. Use the included Ansible playbook (network_tests.yml) to run automated ping and iperf3 benchmarks across all peers, including the local on-premises system.
Make sure you're in ansible directory and edit your inventory.yml file.
Add your on-premises server to the Ansible inventory:
Save and exit the file.
You only need to choose one authentication method, either ansible_ssh_pass or ansible_ssh_private_key_file depending on your environment and security preference.
Run the playbook from your Ansible control node:
The playbook may take 5–10 minutes depending on how many regions and peers (including on-premises) are enrolled. It automatically retries failed tests and aggregates the results into tables.
After completion, the playbook creates a network_test_results/ directory with:
network_results.txt: Combined output of all tests.public_results_table.txt: Tabular summary of region-to-region performance over the public internet.private_results_table.txt: Tabular summary of performance across the Headscale private mesh, including your on-premises subnet.Review the public internet results.
Your output should be similar to the one below:
Review the private mesh results, which now include your on-premises node.
Your output should be similar to the one below:
Public tests usually show higher speeds due to direct internet routing and optimized infrastructure. Private mesh tests use encrypted WireGuard tunnels, which add overhead and may slightly reduce throughput.
In this guide, you extended a Vultr-based Headscale deployment to include an on-premises server, created and approved routes, and validated connectivity with benchmarks. Your local subnet now securely integrates into the Vultr mesh, enabling hybrid networking across cloud and on-premises environments through encrypted WireGuard tunnels.
0 Comments
Be the first to comment and share your perspective with the community.