Reverse proxying headscale using nginx is extremly simple. You don’t need any special config.
Here is my config with Let’s Encrypt enabled (part of the config is auto-generated using certbot --nginx
).
Ensure to set the port (27896
) to match the one mapped to the Headscale port.
server { server_name headscale.mydomain.com; location / { proxy_pass http://localhost:27896/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_redirect http:// https://; proxy_buffering off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; } listen [::]:443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/mydomain-wildcard/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mydomain-wildcard/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot } server { if ($host = headscale.mydomain.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name headscale.mydomain.com; listen [::]:80; # managed by Certbot return 404; # managed by Certbot }
The proxy_… upgrade stuff is for proxying websockets. I have no idea if it’s required or not because I have not tried, but it doesn’t really hurt to keep in in there.