tailscale account switching (further fumblings)

So, I’ve been using headscale for the last few months, combined with a cheap low spec VM from MythicBeasts.com (as my VPN “server” or at least exit node).

Recently, we decided to ditch using bastion ssh (jump) hosts at work, and move to use a VPN instead. This saves us from having a VM running ssh from listening for inbound connections.

Then I wondered how I could access both the work and my home tailscale networks from my laptop etc.

Initially I came across a blog/article discussing how to access two tailscale networks at once, which involved using linux network namespaces and adding various iptables rules etc. I sort of had a go, but it didn’t seem to want to work and it felt like it was going cause me trouble.

So I thought I’d probably have to keep switching tailscale networks somehow (e.g. tailscale down ; tailscale up ….–server … etc ). But this means I need to keep approving the it on the headscale side etc.

Then I saw there’s a ‘tailscale switch’ command ….

# tailscale switch --list
ID Tailnet Account
0101 my.headscale.server david*
1010 some-label david.goodwin@work.corp

and switching is just a “tailscale switch some-label” or “tailscale switch my.headscale.server

That’s a bit easier than having to reauthenticate with the appropriate tailscale network etc.

A little over ten years ago ….

A little over 10 years ago, in a previous role/company, I designed and implemented a website hosting environment (with a catchy name of “w 3 p cloud”) to ….

  • support WordPress/LAMP like environments
  • have some sort of process/file isolation between sites, so a malware infection in one shouldn’t be able to spread/reach other sites
  • have resource limits in place (the business also liked the idea of charging for more “firepower”, I just wanted to try and stop one site from doing a denial of service on others)
  • be hosted in AWS (EC2) because it was cool to be moving to the cloud (despite the cost)

Eventually, I settled on using LXC containers with a Varnish server as a HTTP frontend router. Hosting within AWS (EC2) was basically a non-negotiable requirement and there weren’t many alternatives either.

A crude web UI was added for managing sites, which was quickly adapted to have a JSON API on top. Then background tasks were added – involving a job queue (originally gearman, later on beanstalk) and some management of iptables rules.

Fast forward to 2026, and it’s still (just about) in use.

As a programmer/developer, we often don’t think too much about the distant future when creating something. We’ve got immediate deadlines, and thinking more than 2-3 years is difficult. There are plenty of uncertainties in life afterall!

Over the years, there have been multiple upgrades of various bits (Varnish, PHP, Debian release, Linux kernels etc).

I think it had between 5-8k sites at it’s peak, and I often found it amusing when I realised I was ordering/using a website hosted on it as a member of the public.

Anyway, all good things come to an end, I guess …. and finally a migration to something bigger/better/faster/shinier has begun, as this count of sites being hosted in it shows:

graph of number of sites being hosted over time, showing a recent decline

Trying out headscale (tailscale vpn stuff)

For sometime, I’ve been using Wireguard for a VPN to use when I’m out and about etc.

As I’m fairly stupid, I used wg-quick to generate the config – however when the config looks a bit like this –


[Peer]
PublicKey = cm+t2u0giNynMkcX1+afPu6SlKyLMeTe8iWKhT1FsDk=
AllowedIPs = 10.0.0.13/32
Endpoint = 192.168.122.13:51820
....

I began to find management became a problem – i.e which computer is that exactly ?

wg show does give you something a bit like this –


...
peer: cm+t2u0giNynMkcX1+afPu6SlKyLMeTe8iWKhT1FsDk=
endpoint: 192.168.122.13:51820
allowed ips: 10.0.0.13/32
...

which is sort of useful, but it still doesn’t tell me a human name. I’ve tried leaving comments in the config before, but they just get wiped out.

I’ve often thought about using TailScale, but wasn’t overly happy with the idea of some third party being involved. Eventually I came across headscale – which offers a self-hosted option for the backend (so your devices use the tailscale frontend).

After a bit of poking around over the weekend I now have this: headscale nodes list

which is a bit nicer –

I’m still pretty new to using Tailscale for a VPN, but I did at least eventually get my phone to join the network, and everything seems to work.

It’s sort of interesting that tailscale doesn’t add an entry into your routing table – but instead adds a few iptables rules in (nat) to mess around with things.

Initial foray into Terraform / OpenTofu

So over the last couple of weeks at work, I’ve been learning to use Terraform (well OpenTofu) to help us manage multiple deployments in Azure and AWS.

The thought being that we can have a single ‘plan’ of what a deployment should look like, and deviations will be spotted / can be alerted on.

I was tempted to try and write a contrived article showing how you could create a VM in AWS (or Azure) using Terraform, but I’m not sure I’ve got anything to add over the 101 other articles on the internet.

Vaguely useful things :

  • The tofu configuration is much quicker to write than e.g. trying to talk to AWS using it’s SDK (something I did do about 7-8 years ago)
  • You can split the config up into multiple .tf files within your working directory, the tool just merges them all together at run time
  • Having auto-complete in an editor is pretty much necessary (in my case, PHPStorm)
  • tofu is quite quick to run – it doesn’t take all that long to check the state of the known resources and the config files, which is good; unfortunately Azure often takes sometime to do something on its end…
  • I’ve yet to see any point in writing a module to try and encapsulate any of our configuration as I can’t see any need to re-use bits anywhere

I’m not sure how we’re going to go about reconciling our legacy (production) environment with a newer / shiny one built with tofu though.

New Computer Time? Perhaps not quite yet

Well, I almost went ahead and bought a Beelink SER8 – after my current desktop (Beelink SER6 Max) kept crashing at random intervals (normally between 3 and 6 days apart).

Of course, since I threatened to replace the SER6 with something else, it’s behaved itself…. typical hardware

ALMOST as annoying as a printer.

Animal Licensing – Paws On the Doors

Last Monday saw the launch of Paws On the Doors – Animal Licensing – which aims to have animal licensing data for England – providing the public with a single place to lookup animal licensing inspections / data.

Under the hood it’s using PHP/Laravel, TypeSense and some magic fairy dust.

It’s kind of related to ScoresOnTheDoors – UK Food Hygiene Ratings – but with a refreshed code base (we felt it was time to move on from a code base that’s probably 20 something years old and start from a cleaner slate without legacy baggage).

atuin – console shell history search

As a random, useful, console tool … try atuin for some magical shell history searching.

I’m too lazy to try and record a semi-useful demo of it, but it’s replaced my ‘ctrl+r’ lookup thingy and has a good search interface.