How do I automatically decrypt an encrypted filesystem on the next reboot?

Goal

I am looking for non interactive way to decrypt a root file partition and a swap partition encrypted with LUKS the next time the system reboots. As well as this, I need a way to undo it after the reboot so that it after one more reboot will require the password again (or even a new password).

The system uses LVM.

I don't want to have to type the password on the system, or use a different system to unlock it, it has to unlock itself that one time.

I have the password it is encrypted with, and would be willing to save it in cleartext on the harddrive. I am not concerned with security at this step.

Background

I have a flow for deploying Ubuntu that is based on an Ubuntu server installation with a custom preseed and kickstart file, kickstart installs a service that run after the first reboot (and only the first reboot) and then reboots again. I am trying to implement LUKS disc encryption in this flow, but I need it to remain non interactive, so it has to be able to restart the first time without a password.

The password set during installation is temporary and will be changed by the service that runs after the first reboot, so the first password can be stored in clear text.

Things I have looked into before posting this question

I have done my fair bit of Googling to try and figure this one out, and most of what I find point towards a solution that swaps out the initramfs file.

I have found multiple resources that explain how to use this to allow for remote unlocking the system, but I need to do it without interaction. Here is one such resource: https://hamy.io/post/0005/remote-unlocking-of-luks-encrypted-root-in-ubuntu-debian/

The closest thing to a solution I think I have found, is this resource which is supposedly a way of accomplishing what I want for a VPS solution, but it is just a bunch of commands with no explanation, and I don't know how to adapt it: https://dradisframework.com/pro/support/guides/customization/auto-unlock-luks-encrypted-drive.html

I also found this resource for ArchLinux https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration#cryptkey, and I have tried adding the kernel parameters, but I have not had any luck with that either. I don't know if it is because LUKS does not support these kernel parameters.


Solution 1:

The solution seems to be rather simple, and is sort of described in How to configure LVM & LUKS to autodecrypt partition?

Here is how I managed to do it

My /boot partition is /dev/sda1

My LVM volume that I want to decrypt is /dev/sda3

I was root, but if you're not append sudo to all the commands.

Start by making a keyfile with a password (I generate a pseudorandom one)

dd if=/dev/urandom of=/boot/keyfile bs=1024 count=4

Then set read permission for root and nothing for anyone else

chmod 0400 /boot/keyfile

Then add the keyfile as an unlock key

cryptsetup -v luksAddKey /dev/sda3 /boot/keyfile

(You will then be prompted to type the encryption password)

Find the uuid of the /boot partition with (this one doesn't require you be root)

ls -l /dev/disk/by-uuid/

Here's an example of what the looks like (it's not the actual output as I grabbed this from another machine)

test@test:~$ ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 Jan 15 03:36 025c66a2-c683-42c5-b17c-322c2188fe3f -> ../../sda2
lrwxrwxrwx 1 root root 10 Jan 15 03:36 9e7a7336-3b81-4bbe-9f1a-d43415df1ccb -> ../../sda1

Then edit /etc/crypttab with your favourite editor

nano /etc/crypttab

The content will look something like (again, this is from another machine)

sda3_crypt UUID=025c66a2-c683-42c5-b17c-322c2188fe3f none luks,discard

What you want to do, is you want to replace none with /dev/disk/by-uuid/[the uuid of the /boot partition]:/keyfile and you want to replace discard with keyscript=/lib/cryptsetup/scripts/passdev

The result should look something like this

sda3_crypt UUID=025c66a2-c683-42c5-b17c-322c2188fe3f /dev/disk/by-uuid/9e7a7336-3b81-4bbe-9f1a-d43415df1ccb:/keyfile luks,keyscript=/lib/cryptsetup/scripts/passdev

Save the file and proceed with updating the initramfs

update-initramfs -u

That's it, you can now reboot.

reboot

To remove it again (as I wanted to)

First I confirm that there are only two keys to the system (the original one and the new keyfile)

cryptsetup luksDump /dev/sda3 | grep BLED

This will generate an output similar to this

Key Slot 0: ENABLED
Key Slot 1: ENABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

To delete the key in key slot 1 (the keyfile)

cryptsetup luksKillSlot /dev/sda3 1

You're then prompted to type the encryption password (the original one, not the one in the keyfile)

Then delete the actual keyfile

rm /boot/keyfile

Update the initramfs again

update-initramfs -u

Now when you reboot you will be prompted for a password again. You're done.

reboot