3 minutes
Headscale
Headscale is the open source, self-hosted implementation of Tailscale’s control node. It lets users take advantage of the tailscale client - available on all platforms - and create a mesh network. One of the major advantages of using headscale (and tailscale) is the subnet router and exit node feature. The subnet routing grants access to machines on the same subnet as the connected client. The exit node feature allows us to route traffic through a given node like a traditional VPN. Overall it’s one of the best self-hosting technologies, and the clear choice for remote access to the hackerspace network.
Luckily, the Proxmox Community Scripts has a script to install headscale in an LXC container. We combine this with ddclient and our virtual WAN bridge port and we have a self-hosted headscale instance for accessing our network. I considered hosting this server in the cloud given it’s essential nature to the hackerspace, but keeping costs low and knowing that Proxmox downtime would prevent access to production systems anyway led me to host it on-premises
Here’s the link to the headscale Proxmox VE helper script. All we have to do is run the command on that page on our blackelk server and configure headscale. We also need to create a DNS entry in our provider so we can actually reach the server. If your provider has an option to proxy (like CloudFlare does), then that will need to be disabled.
The setup for headscale isn’t too painful if you take the time to consider what’s necessary to configure, what you can leave alone, and what you’d like to customize. Essentially you need a server_url, TLS configuration, and DNS configuration (for split tunneling).
All in all this was one of the easier deployments to do (especially since it was one of the first machines deployed and we don’t have a reverse proxy for it). There are good resources available online for different configuration setups of headscale. If you’d like more information on the hackerspace setup, reach out to trashpanda@sodakhacker.space and I’d be happy to help or discuss more in depth about why I chose what I did.
ddclient
One of the downsides of the network setup for the hackerspace is that any VMs or LXCs deployed with Public IPs result in dynamic public IPs, meaning that over time or after shutdowns that are too long, our public IP will change. Not great for DNS entries which expect the server to keep the same IP. Enter ddclient. ddclient allows for the ability to query your DNS provider every so often (in our case, 5min but you can set that to be longer or shorter) and match the IP of a system interface. This means that the most amount of downtime we can have on systems is 5min between when an IP changes.
The key is to minimize the blast radius if the server gets comped and an attacker can read your configuration file and grab that key. Luckily Cloudflare allows for you to create API keys limited by zone. In this case Cloudflare will let you create an API key that limits permissions to the sodakhacker.space zone and ddclient will only look for the configured entry to update. Configure the client to use that key in /etc/ddclient.conf by setting the username to token and then the password to the API key.
# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf
protocol=cloudflare \
use=if, if=eth0 \
login=token \
password='<API-KEY-HERE>' \
zone=sodakhacker.space \
fqdn.sodakhacker.space
This will update the DNS entry to fqdn.sodakhacker.space to whatever the IP is of the eth0 interface. An attacker with this access could change entries in that zone which admittedly would be really unfortunate, but it wouldn’t lead to full compromise of my CloudFlare account which would be far worse. More information on ddclient can be found here.