This document descrives the process of setting up headscale with swag, using letsencrypt certs.
This assumes you have a subdomain (e.g. wg.example.com) pointing to your SWAG instance and want to use it as a reverse proxy.
Add the subdomain for your desired headscale domain to your .env
file.
For example:
SWAG_EXTRA_DOMAINS=wg.example.com
We have to create the headscale configuration files and directories.
mkdir -p ./headscale/config
cd ./headscale
touch ./config/db.sqlite
You can copy the example configuration from the headscale repository.
curl https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -o ./config/config.yaml
Set the following on values inside your config/config.yaml
file:
This is assuming you want your clients to hit your headscale instance at https://wg.example.com:443
server_url: https://wg.example.com:443
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 0.0.0.0:50443
grpc_allow_insecure: false
tls_cert_path: ""
tls_key_path: ""
Comment out the following stanzas inside config/config.yaml
file:
# tls_letsencrypt_listen: ":http"
# tls_letsencrypt_cache_dir: ./cache
# tls_letsencrypt_hostname: ""
# acme_email: ""
# acme_url: https://acme-v02.api.letsencrypt.org/directory
You can configure the rest of the options as you wish.
Create the headscale proxy-conf
:
touch config/nginx/proxy-confs/headscale.subdomain.conf
Assuming your container name is going to be wg
, put the following in that file:
map $http_upgrade $connection_upgrade {
default keep-alive;
'websocket' upgrade;
'' close;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name wg.*;
include /config/nginx/ssl.conf;
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app wg;
set $upstream_port 8080;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
}
Finally, we'll add the headscale service to our docker-compose.yml
file where SWAG runs:
wg:
image: headscale/headscale:latest
container_name: wg
hostname: wg
restart: always
ports:
- "8080:8080"
- "9090:9090"
volumes:
- ./headscale/config:/etc/headscale/
command: headscale serve
You only have to add the ports:
stanza if you want to expose that on the server running the containers.
Finally, run docker compose up -d --force-recreate
and your headscale container will be ready to run.
You can run headscale commands with docker exec wg headscale $HEADSCALE_ARGS
This seciton describes setting up an exit node to route all traffic through on a Linux machine. The machine used for this demo is an Ubuntu 20.04 server, but commands should be general enough to apply to most setups.
Install tailscale on the linux host by following the official documentation. At the time of writing, this simply requires:
curl -fsSL https://tailscale.com/install.sh | sh
Now that tailscale is installed, we need to set up ip forwarding:
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
Finally, we can start the node, advertise it as an exit node, and advertise routes. You can set whatever subnets you want, but we'll just use all traffic for the sake of this document. The routes we will publish are 0.0.0.0/0
and ::0
.
Replace $LOGIN_SERVER
with the hostname that you configured for your headscale host, e.g. wg.example.com
.
sudo tailscale up --advertise-exit-node --login-server https://$LOGIN_SERVER --advertise-routes=0.0.0.0/0,::/0 --force-reauth
Now the node we just set up can be used as an exit node, and all traffic will be routed through it. Your client can use it to access local resources on the network. However this setup doesn't route mDNS traffic to wireguard nodes. In order to do that, you have to enable multicast on the tailscale interface. By default, the tailscale interface will be tailscale0
, change this as appropriate for your environment.
ip link set multicast on dev tailscale0
Running this command will forward mDNS traffic to your wireguard hosts, allowing you to use applications like Chromecast, IGMP, etc.