Skip to content

Instantly share code, notes, and snippets.

@da-n
Created August 24, 2019 13:11
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save da-n/4c77d09720f3e5989dd0f6de5fe3cbfb to your computer and use it in GitHub Desktop.
Save da-n/4c77d09720f3e5989dd0f6de5fe3cbfb to your computer and use it in GitHub Desktop.
Unlock LUKS full disk with USB stick

Configuration for passwordless root filesystem

Source: https://www.howtoforge.com/tutorial/passwordless-encryption-of-linux-root-partition/

The process of entering the passphrase at boot time will now be automated using an USB memory stick. Instead of using a passphrase , the secret key on the USB will decrypt the encrypted volumes. Connect an USB stick to the VM and locate it using the dmesg command. It is detected as /dev/sdb in my VM.

The secret key of 8192 random byte is extracted from the usb stick using the dd command.

dd if=/dev/sdb of=/root/secret.key bs=512 skip=4 count=16

The above generated secret key is added to the encrypted volumes using the cryptsetup command. By default, the passphrase is kept in the slot 0. Therefore, slot 1 will be used for the second secret key.

Run blkid command to get details of volume on the disk.

blkid

In this tutorial, the secret key for decryption of the volume is added in /dev/sda3 only. However, it can be added to /dev/sda2 (swap) partition as well.

cryptsetup luksAddKey /dev/sda3 /root/secret.key --key-slot 1

A simple udev rule is created for the USB device in the file /etc/udev/rules.d/99-custom-usb.rules, the symbolic link that we will use is /dev/usbdevice.

SUBSYSTEMS=="usb", DRIVERS=="usb",SYMLINK+="usbdevice%n"

Reload rules using the following command.

udevadm control --reload-rules

Insert the USB device to verify the custom rule.

A shell script is required to read the secret key from the USB device and provide it to cryptsetup at boot time. The script is created as /usr/local/sbin/openluksdevices.sh and taken from the http://www.oxygenimpaired.com/ site.

#!/bin/sh
############taken from following link#########
###http://www.oxygenimpaired.com/debian-lenny-luks-encrypted-root-hidden-usb-keyfile

TRUE=0
FALSE=1

# flag tracking key-file availability
OPENED=$FALSE

if [ -b /dev/usbdevice ]; then
# if device exists then output the keyfile from the usb key 
dd if=/dev/usbdevice bs=512 skip=4 count=16 | cat
OPENED=$TRUE
fi

if [ $OPENED -ne $TRUE ]; then
echo "FAILED to get USB key file ..." >&2
/lib/cryptsetup/askpass "Try LUKS password: "
else
echo "Success loading key file for Root . Moving on." >&2
fi

sleep 2

Set the permissions of script so that it can be executed.

chmod a+x /usr/local/sbin/openluksdevices.sh

Similar to the fstab configuration file, the crypttab file contains the information about encyrpted volumes on the Linux platfrom. Add a shell script for the sda3_crypt encrypted partition. The content of configuration file /etc/crypttab for encrypted volume is given below.

sda3_crypt /dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc none luks,keyscript=/usr/local/sbin/openluksdevices.sh

Add the following line in the /etc/initramfs-tools/conf.d/cryptroot file.

CRYPTROOT=target=sda3_crypt,source=/dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc
add line to cryptroot

Make sure the usb_storage is added in /etc/initramfs-tools/modules file.

The following shell script (/etc/initramfs-tools/hooks/udevusbkey.sh) is also taken from an external source. It is used to add a custom udev rule in the temporary file system initrd.

#!/bin/sh
# udev-usbkey script
###taken from
###http://www.oxygenimpaired.com/ubuntu-with-grub2-luks-encrypted-lvm-root-hidden-usb-keyfile
PREREQ="udev"
prereqs()
{
echo "$PREREQ"
}

case $1 in
prereqs)
prereqs
exit 0
;;
esac

. /usr/share/initramfs-tools/hook-functions

# Copy across relevant rules

cp /etc/udev/rules.d/99-custom-usb.rules ${DESTDIR}/lib/udev/rules.d/

exit 0

Change the permission of the script.

chmod a+x /etc/initramfs-tools/hooks/udevusbkey.sh

Some changes are required in the GRUB2 boot loader configuation. However, direct changes in the configuration file /boot/grub/grub.cfg are not allowed. Therefore, change GRUB_CMDLINE_LINUX_DEFAULT parameter in the /etc/default/grub configuration file. As shown below, rootdelay and cryptopts are included in the GRUB_CMDLINE_LINUX_DEFAULT parameter.

GRUB_CMDLINE_LINUX_DEFAULT="rootdelay=20 cryptopts=target=sda3_crypt,source=/dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc,keyscript=/lib/cryptsetup/scripts/openluksdevices.sh"
GRUB_CMDLINE_LINUX=""

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtainsConclusion

Run the update-grub command to apply above changes in the /boot/grub/grub.cfg configuration file.

update-grub

After above command, the following changes got applied in the /boot/grub/grub.cfg configuration file.

echo    'Loading Linux 3.16.0-4-686-pae ...'
linux   /vmlinuz-3.16.0-4-686-pae root=UUID=b30cdb22-8e3c-4ffd-a0c7-af96b90ba016 ro  rootdelay=20 cryptopts=target=sda3_crypt,source=/dev/disk/by-uuid/c37a8128-5ea9-45c6-8890-d52f3d452ccc,keyscript=/lib/cryptsetup/scripts/openluksdevices.sh
echo    'Loading initial ramdisk ...'
initrd  /initrd.img-3.16.0-4-686-pae

Run update-initramfs -u to update the temporary file system file for all kernels.

update-initramfs -u

Before reboot, unpack the newley generated initrd.img and verify that the keyscript has been copied to the lib/cryptsetup/scripts directory and the custom udev rule into lib/udev/rules.d/ directory.

cd /tmp/
zcat /boot/initrd.img-3.16.0-4-686-pae | cpio -iv
@githlp
Copy link

githlp commented Oct 15, 2022

Does not work at all:
cryptsetup: ERROR: dm_crypt-0: invalid value for "keyscript" option, skipping
mdadm: No arrays found in config file or automatically
...

i wonder if there is a way to decrypt a freshly installed ubuntu22.04 server headless with an usb stick

@seanbo
Copy link

seanbo commented Nov 15, 2022

cryptsetup: ERROR: dm_crypt-0: invalid value for "keyscript" option, skipping

I just bumped into this. I have not tried it yet.
https://askubuntu.com/questions/906870/luks-keyscript-being-ignored-asks-for-password

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment