Skip to content

Instantly share code, notes, and snippets.

@amritanshu-pandey
Forked from da-n/usb-unlock-luks.md
Created May 17, 2021 06:03
Show Gist options
  • Save amritanshu-pandey/2cfc53269b4c35f85de5daade3275a32 to your computer and use it in GitHub Desktop.
Save amritanshu-pandey/2cfc53269b4c35f85de5daade3275a32 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment