Headscale
Headscale is an open source, self-hosted implementation of the Tailscale control server.
It allows you to create your own private mesh VPN using the WireGuard protocol, providing secure connectivity between your devices without relying on a third-party service.
Note
For this guide you should be familiar with the basic concepts of
License
Headscale is released under the BSD-3-Clause License.
All relevant legal information can be found in the LICENSE file in the repository of the project.
Prerequisites
If you want to use Headscale with your own domain you need to add it first:
[isabell@stardust ~]$ uberspace web domain list
isabell.uber.space
[isabell@stardust ~]$
Installation
Download the latest Headscale binary from the official GitHub releases page. Replace 0.26.1 with the latest version:
[isabell@stardust ~]$ wget -O ~/bin/headscale \
https://github.com/juanfont/headscale/releases/download/v0.26.1/headscale_0.26.1_linux_amd64
[isabell@stardust ~]$ chmod +x ~/bin/headscale
By default, Headscale loads the configuration from $HOME/.headscale/config.yaml, so we continue with creating the directory:
[isabell@stardust ~]$ mkdir -p ~/.headscale
Then download the example configuration file:
[isabell@stardust ~]$ wget -O ~/.headscale/config.yaml \
https://github.com/juanfont/headscale/raw/v0.26.1/config-example.yaml
Configuration
Configure Headscale for Uberspace web backend
To run Headscale behind Uberspace’s native web backend (reverse proxy), you need to:
Set Headscale to listen on interface
0.0.0.0:8080by settinglisten_addrto0.0.0.0:8080.Disable TLS in Headscale (let Uberspace handle HTTPS) by setting
tls_cert_pathandtls_key_pathto empty strings.Set the correct
server_url(your public domain, with https) by settingserver_urltohttps://isabell.uber.space:443.Set a encryption key for the Headscale connection by setting the
private_key_pathtoprivate.key(will be generated after configuration).
Edit ~.headscale/config.yaml with your favourite editor and make the following adjustments:
Warning
Review and adjust the configuration to suit your environment. At minimum, set the server_url, private_key_path, and database.sqlite.
Note
TLS is handled by Uberspace’s web backend, do not set tls_cert_path or tls_key_path in your Headscale config. See Headscale’s TLS documentation for more information.
For a simple and minimal setup, set the following values:
server_url: "https://isabell.uber.space:443"
listen_addr: "0.0.0.0:8080"
tls_cert_path: ""
tls_key_path: ""
unix_socket: "headscale.sock"
noise:
private_key_path: "noise_private.key"
database:
type: "sqlite"
sqlite:
path: "db.sqlite"
Generate a private key (required for WireGuard):
[isabell@stardust ~]$ headscale generate private-key > ~/.headscale/private.key
Note
For further configuration options, see Headscale’s Configuration documentation.
To validate your configuration, run:
[isabell@stardust ~]$ headscale configtest
If you see no errors, you can continue with the next step.
Test daemon
Test the daemon by running headscale serve in a terminal.
If it’s not in state running without errors, check the shell output for errors.
Setup daemon
Create ~/etc/services.d/headscale.ini with the following content:
[program:headscale]
command=%(ENV_HOME)s/bin/headscale serve
directory=%(ENV_HOME)s/.headscale
stderr_logfile=%(ENV_HOME)s/logs/headscale.err.log
stdout_logfile=%(ENV_HOME)s/logs/headscale.out.log
autostart=true
autorestart=true
stopsignal=INT
startsecs=5
After creating the configuration, tell supervisord to refresh its configuration and start the service:
[isabell@stardust ~]$ supervisorctl reread
SERVICE: available
[isabell@stardust ~]$ supervisorctl update
SERVICE: added process group
[isabell@stardust ~]$ supervisorctl status
SERVICE RUNNING pid 26020, uptime 0:03:14
[isabell@stardust ~]$
If it’s not in state RUNNING, check your configuration and the logs using supervisorctl maintail or tail -f ~/logs/headscale.out.log.
Configure Uberspace web backend
Now, connect the Uberspace web backend to your running Headscale instance (use the port configured in your configuration file, like 8080):
To make the application accessible from the outside, configure a web backend:
[isabell@stardust ~]$ uberspace web backend set / --http --port <port>
Set backend for / to port <port>; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
[isabell@stardust ~]$
Note
Uberspace’s web backend will handle HTTPS and proxy all requests (including WebSockets) to your Headscale service.
Usage
Once Headscale is running, you can begin managing users and nodes.
Create a user:
[isabell@stardust ~]$ headscale users create <USER>
Generate a preauth key for device registration:
[isabell@stardust ~]$ headscale preauthkeys create --user <USER>
Use the preauth key with the Tailscale client on your device:
[isabell@stardust ~]$ tailscale up --login-server https://isabell.uber.space --authkey <PREAUTHKEY>
For more commands, see headscale help or the official documentation.
Updates
Note
Check the releases page regularly to stay informed about the newest version.
To update Headscale, download the new binary and replace the old one. Then restart the service:
After creating the configuration, tell supervisord to refresh its configuration and start the service:
[isabell@stardust ~]$ supervisorctl reread
SERVICE: available
[isabell@stardust ~]$ supervisorctl update
SERVICE: added process group
[isabell@stardust ~]$ supervisorctl status
SERVICE RUNNING pid 26020, uptime 0:03:14
[isabell@stardust ~]$
Tested with Headscale 0.26.1, Uberspace 7.16.7
Written by: Lukas Wolfsteiner <https://lukas.wolfsteiner.media>