Have you seen this tweet? It's not the only one, and it got me thinking. Tailscale is amazing. Like others, I've been happily using it forever, but its brain is still SaaS. So why don't I take control over it, especially when its open source counterpart is one of the most popular projects on GitHub? Beyond the fact that I'll be able to get unlimited users, unlimited policies from other resources, which are all capped unless you pay, I'll be the one controlling the gateway. Not a closed source server on a company I just blindly trust. When it comes to the most sensitive pieces I have, my internal home services, it feels even more sensible. Now I have nothing against Telescale on the contrary. A fantastic service built on top of the amazing WireGuard and given away for basically free,
but it's not all about money. For me, it's about latency and control and a bit of nerd spice that forces me to self host and run services on my own just for fun. By the end of this one, you'll have the tools to run your own mesh network and access private services using a tunnel you dug yourself.
Let's get into it.
Headscale does exactly that, and it's directly aimed at replacing the Tailscale control center while you can keep enjoying their open source client. Now both of these are based on the same technology, WireGuard. And, sure, you can set up WireGuard yourself, but let's just say there's a good reason why people use Tailscale in the first place. WireGuard is hard. Tailscale makes it unbelievably easy. But why not a VPN, you may ask? Well, to put simply,
this is a VPN. Clients use a gateway to get access to a bunch of servers. This can be incredibly inefficient if you're accessing a local machine while you're physically not far from it while your VPN server lives far, far away. And if you think that's a joke, think about companies running their sensitive infra like VPNs on AWS US East or West while having on prem infrastructure
in their building, either across the country or on the other side of the globe. And that was my situation at home. Why would I travel across continents to have my laptop and phone securely access my security cameras? Well, WireGuard isn't forming a gateway, but rather a mesh network of nodes. You're a machine that joined the system. You're now part of the network infra running lightweight WireGuard tunnels between every available pair of nodes, making the system not only faster but also fault tolerant. For Tailscale, building on top of that, there's a main service,
that's the server, helping coordinate,
store private keys, etcetera. Enough theory. You can read more about it in the link below. Let's get this thing running. Now I've mentioned I have a home lab setup with k three s, so that's where it's going to live. You can set it up any way you like. It doesn't really change much. There are two important bits to the infra, the configuration and the server itself. Starting from the first, the server URL is actually not going to stay like that. I'm going to give it a real publicly available DNS, and we're solving the security risk here in a really cool way. Wait for the end for that. There's an address to listen on for connections and another one for metrics.
This is pretty much all you need to get started. The head scale server is a container from their official Docker Hub release,
and the command is simply head scale serve. Ports are configured to match the config we've shown earlier.
An extra word about the configure. Head Headscale implements almost all Tailscale features. There's a long list right there. One of those features is Magic DNS, which basically gives you automatic internal DNS entries for different machines. And while this is cool, and I did configure it to play around, it's very problematic.
DNS is simple but also complicated. If you play around with it like setting your own AadGuard or just use the magic DNS by head scale, you'll quickly realize not all devices are happy to route you to seemingly suspicious nonpublic entries.
IPs work great, but who can work with these? There's a good reason DNS was ever created. So I've mentioned I'm using public records for mine, but in a way that keeps the service private.
More on that later.
As for caddy, which is the main HomeLab reverse proxy, we'll add a simple line that sends traffic from my public domain to the local case three s head scale service.
So our server is up. Looks like it's running and listening,
we can start working. Time to install the Telescale client. We mentioned this bit is open source and saves us the trouble of using anything different to create a node in the mesh network. Once it's ready, we'll probably want to add a small UI. And while Headscale doesn't come with one, there are plenty of options on GitHub. I went with head plane, the most popular option. Back to the server, head scale is actually its own CLI for different operations. And since it's running inside a container, I'll run a small trick to execute in it just to fire the command. And since I'm not gonna run this type of command every single time I want something,
an alias can be helpful.
Okay. Let's do this. Headscale users list comes up empty, of course. Users create with my name is pretty much enough at this point, and there I am. So you're setting up head scale as an alternative to tail scale which is great if you want more control over your own network. But once you start self hosting more of your infra, there's one thing you very quickly realize. Local is not the same thing as backed up. Your configs, keys, secrets, manifests, home lab notes, exported settings, all of these become part of the system. And if it only leaves on one machine or one NAS or one cluster, it's still a single point of failure. That's where Internxt fits in nicely. Internxt is a privacy first cloud storage platform that works really well as an off-site backup target.
It's open source, end to end encrypted with zero knowledge protection, GDPR compliant so much like the self hosted tools we talk about in this channel, the idea is that you stay in control of your data. Internets can store it, but they can't rid it. For DevOps workflows, the big thing is Rclone support. You can reconnect Internets drive natively or through webDAB,
which means the same automation patterns you already use still apply. Scheduled backups, syncing config exports,
pushing important files from remote machines or just keeping a copy of your home lab setup somewhere off-site. They've also added file versioning which is exactly the kind of thing you don't care about until the day you actually need it. The plan I think you should be focusing on right now is the lifetime ultimate plan. Five terabytes, one time payment, no monthly subscription.
For an off-site backup target that's supposed to quietly exist in the background, that model makes a lot of sense. Use the link in the description to check it out. The offer through that link gives you 87%
off the lifetime ultimate plan, which is higher than what's currently available directly on the website. Now back to the video. Admin panel is ready, and it needs a key to start operating, extract it from the container using our alias, feed it to head plane, and there we go. No machines in the network just yet. My user is in place. Time to add the first node. Tailscale up with a custom login server, which accepts the routes and DNS entries as we've mentioned earlier for the Magic DNS. We get a URL to visit, which in turn generates a node registration command with a user and a key. Back to the server, register the node with our user, and boom. Node MacBook Pro two is registered.
Headplane is also happy,
and we've been given a special new IP of an internal new network formed right now with one device. Tailscale status from my machine and just a reminder, this is a node on the network, not the control server itself. It shows my machine as the only one in the mesh. Now here's my idea. I know I have my laptop as a single node, and my control plane is my home server. That's cool, but now I want to add what's known in the networking jargon as a leg in my home lab. Again, not the control server that isn't part of the game, but rather add another node. So I went ahead and deployed a very simple tail scale container. I called it subnet router with hopes it's one day going to literally allow some access to some devices, but I think that's pushing the envelope of what I'm doing here.
Same process. This is a long line that gives Tailskill a command to register with the network using our domain. Okay. The node is trying to register. Now we need to visit the path in the control server. There's our command, and we're in. K three s router is ready. Over at head plane, I've added some subnets to make sure we can actually access Kubernetes internal pod network from remote. This is our way of exposing additional physical networks to Tailscale as well, and this requires approval,
which is conveniently available here on the UI. Okay. Money time. I want to access Dozle, my log service, which is also an amazing open source, and I've covered it before in a video recently on the channel. For now, let's grab the internal k three s service and take our log view cluster internal IP that points at Dozzle. If we did everything right, I should be able to access this IP. Boom. Dozzle is up and accessible
from outside the k three s cluster. All my application logs and monitoring is right there. Just to be extra certain, Tailscale down to kill the service and see if we can still access Dozzle. Nothing works. Fantastic.
Tailscale back up and we're back in.
Okay. Accessing Dozzle through the IP is going to be impossible. In comes DNS.
Now one option I love is my local AdGuard, which is also, by the way, accessible now with ease through head scale where I can rewrite DNS entries like logs.domain
and get there fairly quickly.
There's a bit of a problem with Home DNS, which is why I'm reconsidering that setup. AdGuard is fantastic for blocking crappy ads, but when you add non standard fishy looking entries, browsers don't tend to trust or resolve these at all. And we're not even talking about HTTPS that adds another layer of annoyances if you want that. So I found something better.
I went ahead and added another public IP, but one that resolves to a private address.
If you have access, it works. But if you don't, and you shouldn't because it's inside my k three s cluster or at least I hope that's the case, you have nothing to do with it. Once that's propagated properly, my logs domain translates to Dozzle. Happy days. I gotta be honest here and say that first, DNS is way more trickier than this, and there are other options, especially for home labbers, which I'll explore on another video. But regardless, I now have a direct link to my cluster applications.
I do want to add, however, that setting up a single leg in the cluster and exposing everything is a bit of a new VPN problem.
The better architecture would be to deploy a small Tailscale sidecar next to the applications I actually want exposed. Let me know if that's of interest in the comments. In the meantime, to see the basics of this HomeLab cluster and how I made everything play together, check this video next. Thank you for watching. I'll see you on the next