remote-unlocking full system encryption with arch linux
I recently needed to set up a server with full system encryption and was faced with the conundrum: if I need to reboot, the keys are either (a) on the server, and thus not actually secure, or (b) need to be entered at boot, which typically means (I thought) that one needs to actually enter a password. However! I searched around a bit and saw that people used the dropbear ssh server in their initramfs images to log in remotely and thereby allow for a genuinely headless full-disk encrypted system. Unfortunately, almost all of the resources I could find on this was for Debian-based systems, and I had a hell of a time getting it to work on Arch.
So, to spare others the pain I went through getting this to work, here is sanine's guide to remote-unlocking encrypted Arch systems.
1. set up arch with full system encryption
The Arch wiki has fairly complete guides on how to do this! I used the installation guide and encrypting an entire system guide to get my initial installs set up.
A note on the bootloader steps, because this was not made clear to me the first time I did it: the kernel parameters are passed as command-line parameters. If you're using GRUB, for instance, they should be put in the GRUB_CMDLINE_LINUX
variable, not as config variables in their own right.
2. install the needed packages
This should be a pretty easy step. On your lovely fresh install, just do
pacman -S mkinitcpio-netconf mkinitcpio-dropbear
The netconf
hook will set up networking for us; the dropbear
hook sets up an ssh server for us.
3. write a completely new initcpio hook
Yeah, sorry, this is where it got weird for me and I spent several days just reading the man pages convinced I had done something wrong. Nope! As it is now, if we set up the hooks, the dropbear server would run just fine but wouldn't actually accept any logins because there's no /etc/passwd
file in the initramfs image for it to check if a user is valid. Luckily, it's pretty easy to create a hook that adds one for us. Create the file /usr/lib/initcpio/install/rootpasswd
and write in it
#!/bin/bash
build ()
{
echo "root::0:0::/root:/bin/sh" > /tmp/rootpasswd
add_file /tmp/rootpasswd /etc/passwd
}
You can change the user if you want to, though you'll have to go modify the dropbear install file so that it sets up the root_key
in the correct folder.
4. hack the encrypt hook
(If you're using the sd-encrypt hook: I have no idea how applicable any of this section will be to you. Try it and let me know!)
Okay, now it's possible to log in to the ssh server so what's the problem? Well, the default encrypt hook only checks if the target volume is present at the beginning. If you unlock it halfway through, when it's already prompted you for a password (say, for instance, by sshing in and decrypting it) it will just break. So we need to write another new hook. We still need the encrypt hook's install file though, so do
cd /usr/lib/initcpio/install
cp encrypt remote-encrypt
In your favorite text editor, enter the following into /usr/lib/initcpio/hooks/remote-encrypt
:
#!/bin/sh
run_hook ()
{
echo "waiting for ${root} to be available..."
while ! [ -e "${root}" ]; do
sleep 2;
done
}
Okay, now you're finished writing hooks. Time to bring everything together.
5. bring everything together
Edit your /etc/mkinitcpio.conf
HOOKS line so that it looks a little like this:
HOOKS=(base udev rootpasswd keyboard keymap consolefont
autodetect modconf block netconf dropbear remote-encrypt
lvm2 filesystems fsck)
Remember that the order of your hooks is important! When you're done, run mkinitcpio -P
to regenerate your initramfs images.
Now, edit your chosen bootloader to add the kernel parameter ip=dhcp
so that the netconf
hook will work correctly. (If you're using GRUB, don't forget to regenerate your grub.cfg
.)
Last but not least, make sure the ssh keys you want to use for unlocking are stored like an authorized_keys file in /etc/dropbear/root_key
.
6. unlock remotely
If all went well, you should now be able to reboot and ssh into your machine before disk decryption. Decryption will be different based on how you set up your machine, but if you did LVM on LUKS like me, you can do
cryptsetup open [cryptdevice] [target] && exit
The "&& exit" isn't critical, but it does lead to some weird effects because for some reason you won't get booted out when dropbear is supposed to die? And this triggered some ugly segfault error messages when I actually did exit after the machine fully booted. Oh well.