Remote Access to ZFSBootMenu via Tailscale

523 words

When booting computers with ZFS as the root filesystem, I like to use ZFSBootMenu as bootloader. Because it runs in a Linux ramdisk, it is possible to set up networking and an SSH server and connect remotely to, for example, allow unlocking of an encrypted ZFS pool. This is great when I have access to the local network in question (either directly or via a jump host), but I don't always have that kind of access. To ensure I always have access, I set about integrating ZFSBootMenu's remote access capability with my Tailnet.

My ZFSBootMenu images are already generated with mkinitcpio, so I created a simple, modular mkinitcpio hook that connects to Tailscale. Tailscale makes it very hard to do this in the most secure way (ephemeral auth key), as auth keys and API keys (to create more auth keys) are capped at 90 days expiration. As a compromise, I chose to use Tailscale's ACL tags to ensure the Tailscale state and private keys are fairly useless if somehow stolen. I've gone into this in more detail in the README.

Using this hook with ZFSBootMenu is fairly straightforward. First, set up remote access (following the mkinitcpio-specific instructions) and set up Tailscale ACLs as you see fit. I've gone with a setup like this:

// Example ACLs for mkinitcpio-tailscale and ZFSBootMenu
{
	"tagOwners": {
		"tag:zfsbootmenu": ["autogroup:admin"],
		"tag:server":     ["autogroup:admin"],
		"tag:local":      ["autogroup:admin"],
	},

	"acls": [
		{"action": "accept", "src": ["tag:local"], "dst": ["*:*"]},
		{"action": "accept", "src": ["tag:server"], "dst": ["tag:server:*"]},
	],
}

Because there is no listed ACL with tag:zfsbootmenu in the src field, it cannot initiate any connections to other parts of the Tailnet.

Then, generate an auth key and save it somewhere like /tmp/mk-ts-authkey. I recommend creating the key as not reusable, 1 day expiration, not ephemeral, and tagged with the relevant ACL tag.

Tailscale auth key generation dialog, with settings shown as described

Next, install mkinitcpio-tailscale (it's packaged for Void Linux and maybe other distros) and use the provided script to authenticate to Tailscale:

# mkinitcpio-tailscale-setup -k /tmp/mk-ts-authkey

Once it runs successfully, you should see something like this in the Tailscale admin console:

Tailscale admin console machine entry for 'void-zbm-test-mkinitcpio' with the tag 'zfsbootmenu' and expiry disabled

Add the hook to the HOOKS array (HOOKS+=(tailscale)) in /etc/zfsbootmenu/mkinitcpio.conf after any network setup hooks and run generate-zbm to regenerate the ZFSBootMenu image with Tailscale support.

You should now be able to reboot and ssh into ZFSBootMenu using the Tailscale IP or hostname.

terminal window SSH'd into a test VM over tailscale, showing the ZFSBootMenu interface