[From sandbox] LUKS container decryption at system boot time

[From sandbox] LUKS container decryption at system boot time

Good day, all night! This post will be useful to those who use LUKS data encryption and want to perform decrypt disk decryption for Linux (Debian, Ubuntu) at the root decryption stage . And I could not find such information on the Internet.

More recently, with an increase in the number of disks in the shelves, I encountered the problem of decrypting disks using a more than well-known method through/etc/crypttab. Personally, I single out a few problems of using this method, namely that the file is read only after loading (mount) the root partition , which adversely affects the import of ZFS, in particular if they were assembled from sections on * _crypt device, or mdadm raids collected from sections as well. We all know that you can use parted on LUKS containers? And also the problem of early start of other services when there are no arrays yet, and to use something is needed already (I work with clustered Proxmox VE 5.x and ZFS over iSCSI).

A bit about ZFSoverISCSI
iSCSI works for me through LIO, and actually when iscsi-target starts and does not see ZVOL devices , it simply removes them from the configuration, which makes it impossible for the guest systems to boot. From here either restore json file backup or manually add devices with identifiers of each VM, which is terrible when there are dozens of such machines and there are more than 1 disk in each configuration.

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

Most often, a key file is used on the Internet (self-added before it to the slot with the command - cryptsetup luksAddKey), or in rare exceptions (very little information in the Russian-language Internet) - the script decrypt_derived, which is located in/lib/cryptsetup/script/ (Of course, there are more ways, but I used these two, which formed the basis of the article). I also wanted to be fully autonomous after reboots, without any additional commands in the console, so that everything would “fly up” right away. So why wait? -

Let's get down!

We assume a system, for example, Debian, installed on the sda3_crypt crypto partition and a dozen disks ready to encrypt and create anything your heart desires. We have a passphrase for unlocking sda3_crypt and it is from this section that we will remove the password hash on the running (decrypted) system and add it to other disks. 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 disks with the “hash” from our key phrase, you need to know the UUID, or ID - depending on who got used to it. 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 work we need the functions, 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/ 


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

Content ../decrypt

 cp -p/lib/cryptsetup/scripts/decrypt_derived "$ DESTDIR/bin/decrypt_derived"  


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

Content ../partcopy

 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"  

some more

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

Content ../partprobe

 $ DESTDIR/bin/partprobe  

and last, before update-initramfs, you need to edit the/etc/initramfs-tools/scripts/local-top/cryptroot file, starting with the line ~ 360, a piece of code below

  # decrease $ count by 1, apparently try it was successful.
  count = $ (($ count - 1))
  message "cryptsetup ($ crypttarget): set up successfully"

and lead to this kind of

  # decrease $ count by 1, apparently try it 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"

Please note that you can use either a UUID or an ID here. The main thing is that the necessary drivers for HDD/SSD devices were added to/etc/initramfs-tools/modules. You can find out which driver is used with the command udevadm info -a -n/dev/sdX | egrep 'looking | DRIVER' .

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

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

Source text: [From sandbox] LUKS container decryption at system boot time