Last time, I explained how I was embarking on a server migration. My goal is to move multiple, independent cloud services to a single home server. The box I chose is a Beelink Mini PC. It has a half-gig of SSD storage, 16GB of RAM, and a fast 4-core processor. It also supports 4K graphics, but I primarily use the machine in a headless state leveraging SSH to talk to the device. At the time of this writing, it was priced at $199 (before a $40 coupon) on Amazon.
Before I dive deep into the applications themselves, it makes sense to detail how the server is configured for (secure) remote access.
Operating System
Early in my career I was all-in on Windows. I’ve been using Mac machines professionally for the past 9 or so years. At the same time, all of my personal machines run Linux. My main machine is a Thelio desktop running Pop!_OS, and my primary remote machine is a Lemur Pro running the same OS.
Given my familiarity with Linux and desire to keep my primary machines equivalent, I opted to leverage Pop!_OS on the new rig as well. This meant creating a live boot USB and installing Linux over top of the default Windows that came with the machine. I had a moment of doubt as I elected to forfeit my Windows license, but only for a moment.
Once the installer started up I opted to encrypt the drive as well. I don’t anticipate anything remarkably valuable will live on this machine, but it felt like a good idea. Even if someone takes it out of my house, the machine will be useless without my decryption key!
The fact that Pop!_OS is based on Debian also makes it familiar for me having managed Ubuntu servers in the cloud for the past dozen or so years.
Remote Access
Given how often I travel, I need a reliable way to access my home server while on the road. My new ISP likes to rotate my residential IP address frequently, so I can’t rely on having things written down. Last time I mentioned an older approach at running a cron job to write a public DNS record with my home IP address, but again this is not something I want the rest of the world to see.
Instead, I’ve started leveraging Tailscale to network all of my devices together. This includes my desktop machine, my phone, my few remaining cloud servers, etc. Every device I personally use that’s capable of networking is joined to my Tailnet so I can manage them remotely. This allows me to connect to remote machines via SSH without exposing an SSH port to the internet in the first place!
Adding the Beelink Mini to my Tailnet was relatively easy. Once it was connected, I also exposed it as an exit node. This allows me to route all traffic from my phone through my home network as well! It’s nice to know an extra benefit of this project is that I have a fast, secure, always-on VPN connection through my home network even when I’m on the other side of the world.
Overcoming Limitations
Keen readers might have already seen the first and largest issue with this setup. I’m remotely accessing the server via Tailscale, but I also configured full disk encryption. When a Linux machine boots, it does so with an “initial RAM disk” (initramfs
) before the filesystem is decrypted and you can boot as an actual user. With an interactive system like a desktop or laptop, you’re asked to enter the encryption password before the machine boots in its entirety.
By default, this means I’d need physical access to decrypt the drive in the event of a reboot!
In order to still connect to my machine after a reboot, I needed to configure initramfs
system to connect to my Tailnet. Then I could connect, decrypt the primary drive, and move on with my day. As I’m not a full-time system administrator, this seemed to be an impossible task. Until I found a fork of tailscale-initramfs
that did exactly what I needed!
Now, upon any reboot, the Beelink Mini will connect with a temporary hostname to my Tailnet. This gives me the opportunity to SSH in and unlock the rest of the filesystem. All of my services and apps then start normally and I’m right where I want to be:
- Self-hosted server sitting on my desk
- Full disk encryption for security
- No public visibility to my residential IP address
- VPN connectivity to the machine from anywhere in the world
- Remote access during the entire boot process
All that’s left is to begin adding the applications I need migrated from the public cloud!