Good day or night to everyone! This post will be useful for those who use LUKS data encryption and want to perform disk decryption on Linux (Debian, Ubuntu) in the root partition decryption stage.I could not find this information on the internet.
Recently, with the increasing number of disks in the shelves, I faced the problem of decrypting disks using the well-known method through /etc/crypttab. I personally identify several issues with this method, namely that the file is read only after booting (mounting) the root partition,which negatively affects ZFS import, especially if they were built from partitions on *_crypt devices, or mdadm raids also built from partitions. We all know that you can use parted on LUKS containers? There's also the issue of early startup of other services, when the arrays are still not available, but to use something is already needed (I work with clustered Proxmox VE 5.x and ZFS over iSCSI).
A bit about ZFS over iSCSI.iSCSI works for me through LIO, and when the iSCSI target starts and does not see the ZVOL devices, it simply removes them from the configuration, which prevents guest systems from booting. This leads to either restoring the backup json file or manually adding devices with identifiers for each VM, which is simply terrible when there are dozens of such machines and each configuration has more than one disk.
The second question I will consider is what to use for decryption (this is a key point of the article). We will talk about this below, so stay tuned!
Most often, on the internet, a key file is used (of course, added to the slot beforehand using the command — cryptsetup luksAddKey), or, in rare exceptions (there is very little information in Russian-language sources) — the decrypt_derived script located in /lib/cryptsetup/script/ (of course, there are other methods, but I specifically used these two, which form the basis of the article). I also aimed for complete autonomous startup after reboots, without any additional commands in the console, so that everything would "take off" right away. So, why wait? —
Let's get started!
We assume a system, for example, Debian, installed on the crypto partition sda3_crypt and a dozen disks ready for encryption and creating whatever is desired. We have a passphrase for unlocking sda3_crypt and it is from this partition that we will generate a hash from the password on the running (decrypted) system and add it to the other disks. It's elementary, we execute in the console:
/lib/cryptsetup/scripts/decrypt_derived sda3_crypt | cryptsetup luksFormat /dev/sdXwhere X represents our disks, partitions, etc.
After encrypting the disks with the hash from our passphrase, it is necessary to find out the UUID or ID — depending on what one is used to. We take the data from /dev/disk/by-uuid and by-id respectively.
The next step is to prepare the files and mini-scripts for the functions we need to operate, let's proceed:
cp -p /usr/share/initramfs-tools/hooks/cryptroot /etc/initramfs-tools/hooks/
cp -p /usr/share/initramfs-tools/scripts/local-top/cryptroot /etc/initramfs-tools/scripts/local-top/next
touch /etc/initramfs-tools/hooks/decrypt && chmod +x /etc/initramfs-tools/hooks/decryptContents of ../decrypt
#!/bin/sh
cp -p /lib/cryptsetup/scripts/decrypt_derived "$DESTDIR/bin/decrypt_derived"next
touch /etc/initramfs-tools/hooks/partcopy && chmod +x /etc/initramfs-tools/hooks/partcopyContents of ../partcopy
#!/bin/sh
cp -p /sbin/partprobe "$DESTDIR/bin/partprobe"
cp -p /lib/x86_64-linux-gnu/libparted.so.2 "$DESTDIR/lib/x86_64-linux-gnu/libparted.so.2"
cp -p /lib/x86_64-linux-gnu/libreadline.so.7 "$DESTDIR/lib/x86_64-linux-gnu/libreadline.so.7"a little more
touch /etc/initramfs-tools/scripts/local-bottom/partprobe && chmod +x /etc/initramfs-tools/scripts/local-bottom/partprobeContents of ../partprobe
#!/bin/sh
$DESTDIR/bin/partprobeand lastly, before update-initramfs, you need to edit the file /etc/initramfs-tools/scripts/local-top/cryptroot, starting from line ~360, the snippet of code below
Original
# decrease $count by 1, apparently last try was successful.
count=$(( $count - 1 ))
message "cryptsetup ($crypttarget): set up successfully"
break
and bring it to this form
Edited
# decrease $count by 1, apparently last try was successful.
count=$(( $count - 1 ))
/bin/decrypt_derived $crypttarget | cryptsetup luksOpen /dev/disk/by-uuid/ *CRYPT_MAP*
/bin/decrypt_derived $crypttarget | cryptsetup luksOpen /dev/disk/by-id/ *CRYPT_MAP*
message "cryptsetup ($crypttarget): set up successfully"
breakNote that you can use either UUID or ID here. The main thing is that the necessary drivers for the HDD/SSD devices are added to /etc/initramfs-tools/modules. You can find out the driver being used with the command udevadm info -a -n /dev/sdX | egrep 'looking|DRIVER'.
Now, when we have finished and all files are in place, we run update-initramfs -u -k all -v, in the logging there should be no execution errors of our scripts. We reboot, enter the passphrase, and wait a bit, depending on the number of disks. Then the system will start and at the final stage of boot, specifically after mounting the root partition, the command partprobe will be executed — it will find and attach all created partitions on LUKS devices and any arrays, whether ZFS or mdadm, will assemble without problems! And all of this before the booting of the main services that need these disks/arrays.
update1: As , this method only works for LUKS1.
Source: habr.com
