⚠️ Update 2023-09-12
I would like to stress that this is just an example setup to showcase the general idea on how to put an encryption key into the initramfs. If you want to do this, you probably want to have the /boot partition on a USB drive, such that the disks will be protected when decommissioned without having to overwrite the boot partition on disk.
🚨 This guide is not safe on SSDs unless you put /boot on a separate USB stick, since you cannot safely erase specific data on SSDs (you have no control on where blocks are written).
🚨 If you really want to protect your server data, even from entire physical takeovers and not just HDD decommissions, you want to follow my other guide that requires manual unlocking over SSH.
This guide is known to work with Ubuntu 18.04, 20.04 and 22.04. You should be doing this setup as root, which is why I omitted sudo.
The idea here is that we’ll be copying the keyfile to the initramfs to automatically unlock the system drive, and once we want to destroy the data, instead of overwriting the entire drive, we’ll simply overwrite the boot partition multiple times. However, this does not work with flash storage!
In a default Ubuntu (encrypted) setup the main drive is encrypted using dm-crypt/luks and only the UEFI and boot partitions are clear.
By default, after installation you will be asked for your encryption passphrase which is of course the secure way to do things, especially on a laptop. But on a server this might be inconvenient, and if you’re still using an HDD you can simply overwrite the boot partition multiple times before decommissioning the drive. On flash storage, however, you do not have control over where files are written to internally so overwriting a single partition is meaningless and won’t guarantee destruction of the encryption key. Therefore, only do this with HDD drives!
Generating the key
First, we’ll create our folders and files and set up permissions:
mkdir /etc/luks chmod 700 /etc/luks touch /etc/luks/system.key chmod 400 /etc/luks/system.key
Now we’ll generate a new key with:
dd if=/dev/urandom of=/etc/luks/system.key bs=4096 count=1
Note that using
/dev/random would be safer, but is blocking and could potentially take infinite time to generate the key, which is why I am using
/dev/urandom here. If you insist on using
/dev/random instead you should probably also add
iflag=fullblock to the command (to avoid skips).
Verify that only root can read the key:
ls -l /etc/luks/system.key
If you others can see the key, do:
chmod 400 /etc/luks/system.key
No other user should be able to read the encryption key!
Adding the key to LUKS
Now we’ll add the key to LUKS so that it can actually unlock the partition.
Replace /dev/sdX with the encrypted partition. You can figure this out by running:
lsblk -o +FSTYPE
And look for the partition of type
crypto_LUKS and then add the key to it with:
cryptsetup luksAddKey /dev/sdX /etc/luks/system.key
It will ask to enter any existing passphrase, do so and hit enter.
Setting up auto-unlock (initramfs)
First make sure you have
apt install cryptsetup-initramfs
/etc/cryptsetup-initramfs/conf-hook with your favourite editor like nano:
KEYFILE_PATTERN= and replace it with:
Save the file and exit. This will make sure all *.key files in /etc/luks/ will be copied to the initramfs.
echo "UMASK=0077" >> /etc/initramfs-tools/initramfs.conf
This will make sure the correct permissions are set when creating the initramfs.
Now edit /etc/crypttab with your favourite editor like nano:
Where you might see an entry like:
dm_crypt-0 UUID=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee none luks
Replace “none” with the path of your key so it would be something like:
dm_crypt-0 UUID=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee /etc/luks/system.key luks
And then finally, we recreate the initramfs with:
update-initramfs -u -k all
You can now reboot and it should automatically unlock the drive!