Decoding LUKS container at boot time

Good day, night! This post will be useful to those who use LUKS data encryption and want to decrypt decrypt disks under Linux (Debian, Ubuntu) at the stage of decrypting the root partition . And I could not find such information on the Internet.

More recently, with the increase in the number of disks in the shelves, I encountered the problem of decrypting disks using the more than well-known method via / etc / crypttab. Personally, I highlight several problems using this method, namely, that the file is read only after the root partition is mounted (mount) , which negatively affects the ZFS import, in particular if they were collected from partitions on the * _crypt device, or mdadm raids collected also from sections.We all know that you can use parted on LUKS containers? And also the problem of early start of other services, when arrays do not have, and use is something you have to (I'm working with a clustered Proxmox VE 5.x and ZFS over iSCSI).

A bit about ZFSoverISCSI
iSCSI works for me through LIO, and actually when the iscsi target starts and does not see the ZVOL devices, it simply removes them from the configuration, which prevents the guest systems from loading. Hence, either restoring a json file backup, or manually adding devices with the identifiers of each VM, which is just awful when there are dozens of such machines and there are more than 1 disk in the configuration of each.

And the second question that I will consider is how to decrypt (this is the key point of the article). And we’ll talk about this below, go under the cut!

Most often, on the Internet, they use a key file (the cryptsetup luksAddKey command added to the slot by itself before it), or in rare exceptions (the Russian-language Internet is very scarce information) - the decrypt_derived script, which is in / lib / cryptsetup / script / (of course, there are still ways, but I used these two, which formed the basis of the article). I also strove for full autonomous inclusion after reboots, without any additional commands in the console, so that everything would “take off” at once. 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 anything you like. We have a passphrase for unlocking sda3_crypt and it is from this section that we will remove the "hash" from the password on the running (decrypted) system and add it to the other drives. Everything is elementary, in the console we execute:

/lib/cryptsetup/scripts/decrypt_derived sda3_crypt | cryptsetup luksFormat /dev/sdX

where X is our disks, partitions, etc.

After encrypting the drives with a "hash" from our passphrase, you need to find out the UUID or ID - depending on who and what you are used to. We take the data from / dev / disk / by-uuid and by-id, respectively.

The next stage is the preparation of files and mini-scripts for the necessary functions to work, we 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/

Further

touch /etc/initramfs-tools/hooks/decrypt && chmod +x /etc/initramfs-tools/hooks/decrypt

Content ../decrypt
#!/bin/sh
cp -p /lib/cryptsetup/scripts/decrypt_derived "$DESTDIR/bin/decrypt_derived"


Further

touch /etc/initramfs-tools/hooks/partcopy && chmod +x /etc/initramfs-tools/hooks/partcopy

Content ../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 bit more

touch /etc/initramfs-tools/scripts/local-bottom/partprobe && chmod +x /etc/initramfs-tools/scripts/local-bottom/partprobe

Content ../partprobe
#!/bin/sh
$DESTDIR/bin/partprobe


and last, before update-initramfs, you need to edit the file / etc / initramfs-tools / scripts / local-top / cryptroot, starting at line ~ 360, a piece 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 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"
                break


Please note that either UUID or ID can be used 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 which driver to use by udevadm info -a -n / dev / sdX | egrep 'looking | DRIVER' .

Now that we have finished and all the files are in place, run update-initramfs -u -k all -v , there should be no loggingerrors in the execution of our scripts. We reboot, enter the passphrase and wait a bit, depending on the number of disks. Next, the system will start and at the final stage of startup, namely, after “mounting” the root partition, the partprobe command will be executed - it will find and pick up all the created partitions on LUKS devices and any arrays, whether ZFS or mdadm, will assemble without problems! And all this before loading the basic services and services that need these disks / arrays.

update1 : As AEP noted , this method only works for LUKS1.

Also popular now: