In a previous post: Headscale, how to self-host tailscale, I explained how to configure headscale in server; now it is outdated. At that time the only way to install it was using the .deb or binary file, but now we can use a simpler method. This time we will focus on: Docker, headscale and SWAG.
SWAG (Secure Web Application Gateway) sets up an Nginx reverse proxy with built-in cerbot for SSL certificates using Let's Encrypt. I already wrote a litter bit about it here.
Headscale configuration
Create a directory named docker and inside it make the headscale/config directory.
Then copy the headscale config example in headscale/config:
| |
Edit the following values:
| |
And comment the following (since SWAG will be the instance that will get the SSL certificate):
| |
Docker compose file
The docker-compose file was done following SWAG and headscale documentations, as well as this gist.
Inside the previously created directory: docker, put the docker-compose.yml.
In this case I am using duckdns as the dns validation method to get the SSL certificate. I am also getting a wildcard certificate, so I can run more services (like filebrowser) in the same sever using the same SSL cert. SWAG will get the wildcard cert as: *.subdomain.duckdns.org
According to the docs, the first run will give errors during validation due to wrong credentials. We need to update our duckdns API token in the file located in swag/config/dns-conf/duckdns.ini then restart the swag container.
| |
Optionally, if your server does not have a fixed IP address, you can uncomment the duckdns service in the compose file to automatically update the server IP in duckdns.org; just add your SUBDOMAINS={subdomain} and your TOKEN={your-token}
Headscale SWAG proxy configuration
SWAG does not provide a proxy *.subdomain.conf.sample, but luckly the one provided in the gist works like charm.
Save the following as headscale.subdomain.conf inside swag/config/nginx/proxy-confs/, assuming the headscale container name is headscale and restart swag container:
| |
That's it, your headscale sever should be available in https://headscale.subdomain.duckdns.org
Now you can create your user and add clients/nodes.
Headscale commands
Finally, use the headscale commands to create the users and add clients (you might need sudo):
| |
Join devices
In order to join your devices, you can use the official tailscale app and run:
Linux and OpenWrt
Login can be done with:
| |
To expose your local subnet (devices connected to your OpenWrt router) you should add the flag --advertise-routes=192.168.1.0/24.
If you are running OpenWrt 22.03, you need to add the flag --netfilter-mode=off and configure the firewall rules, due to tailscale uses still iptables and latest versions of OpenWrt switched to nftables. See issue here.
This was fixed in version 23.0.5 and later the --netfilter-mode=off flag is no longer needed.
Android
Set the custom server in the official tailscale android app.
And now enjoy the SWAG!

If you found this content useful, please support me:
BTC: 1E2YjL6ysiPxRF4AEdXChpzpesRuyzgE1y