Skip to content


Virtual Private Networks (VPN) are a fantastic technology. They let us build out our private infrastructure in a secure and encrypted fashion. For people who don’t want to brave the dangers of exposing services to the web, they are an invaluable tool.

One of the most well known VPNs out there is wireguard. Wireguard lets us create VPNs in a simple, incredibly resource efficient manner. In fact, some of you might already use wireguard as a site to site vpn. Fantastic! However this guide isn’t about wireguard.

Something wireguard is less known for, but is far more impressive, is its capability to be a building block for large scale networks. Smart VPNs that utilise wireguard internally have exploded lately. Here’s a fun list:

That’s nowhere near a comprehensive list, but it’s a good start. This guide is going to delve into making our own smart VPN with Headscale.


In this series of guides, we will:

  • Set up a Headscale server
  • Configure headscale via reverse proxies (using Caddy)
  • Configure a site-to-site VPN inside headscale
  • Set up a UI for headscale (with headscale-ui)


Expect to see some more articles in the future on: OIDC integration with keycloak ACL management


Getting headscale operational is not too difficult. What you do need is:

  • A linux server (this guide will be using docker on a debian 11 instance)
  • A domain (this guide will be using a domain registered at cloudflare)
  • A router (this guide will be configuring openwrt)

Getting Started

Enough chit chat! Let’s get started with “Setting Up Headscale”.