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