Raspberry Pi – Linux Unified Key Setup part 1

In this post, I will be going over the steps on how to setup full-disk encryption on your Raspberry Pi device by using the Linux Unified Key Setup tool suite while running the latest version of the Raspbian operating system.

Prerequisites

For this project, you will need a basic understanding of the Linux operating system, and some familiarity with the Linux command line. We will be working with the initramfs system so we can store the required packages and scripts needed to unlock our device. We will need a host machine (laptop/desktop) running Linux, and we will also need a Raspberry Pi device and a Micro SD card running the latest Raspbian operating system. If you are not sure how to install the Raspbian operating system, please refer to the official documentation.

*NOTE: We are going to make the assumption that the SD card block device ID is /dev/mmcblk01 on the Raspberry Pi.  This is according to the way Raspbian (Debian) handles device ID names, but this block ID for the SD card may differ depending on Linux operating system.

**NOTE: We will also assume you are using a Debian/Ubuntu Linux operating system on your host machine where apt is the package management tool.  If you are using a different Linux distribution, use your default package management tool instead.

Directions

 ⭢  on your host machine

1.) Create SSH key pair

This will generate a new SSH key pair using RSA that we will need for a later step.  Copy the public key to your clipboard for later.

ssh-keygen -t rsa -b 4096 

2.) Install required packages

This will install the cryptsetup suite of tools on your host machine for later use.

sudo apt install cryptsetup 

 ⭢  on your Raspberry Pi device

*NOTE: We are going to assume you are running these commands as the root user.  If not, each command will require root permissions via sudo.

1.) Update and install required packages

After booting into our Raspberry Pi running Raspbian, we need to update and install a few packages…

  • cryptsetup –setup cryptographic volumes for dm-crypt (including LUKS extension)
  • lvm2 – LVM is a Logical Volume Manager for the Linux operating system.
  • busybox – BusyBox combines tiny versions of many common UNIX utilities into a single small executable.

apt update
apt install cryptsetup lvm2 busybox -y
reboot

2.) Modify the /boot/config.txt file

After reboot, we need to tell the config.txt that we want to use initramfs.gz which we create in a later step.

echo "initramfs initramfs.gz followkernel" >> /boot/config.txt

3.) Modify the /boot/cmdline.txt file

The following commands will fix your /boot/cmdline.txt variables. It modifies the root variable, and adds the new cryptdevice variable which is required for mapping your encrypted device.

sed -i 's/ root=/ root=\/dev\/mapper\/crypt cryptdevice=/g' /boot/cmdline.txt
TEMP_VAR=$(grep -oP -e "cryptdevice=\S*" /boot/cmdline.txt);
sed -i "s/$TEMP_VAR/$TEMP_VAR:crypt/g" /boot/cmdline.txt

4.) Modify the /etc/fstab file

The following commands will fix your /etc/fstab file. It modifies the /etc/fstab to show our new encrypted device location using the device mapper.

TEMP_VAR=$(grep " / " /etc/fstab | cut -d ' ' -f1)
sed -i "s/$TEMP_VAR/\/dev\/mapper\/crypt/g" /etc/fstab

5.) Modify the /etc/crypttab file

The following commands will setup your /etc/crypttab file.

TEMP_VAR=$(findfs $TEMP_VAR)
echo -e "crypt\t$TEMP_VAR\tnone\tluks" | sudo tee --append /etc/crypttab

6.) Install the Dropbear SSH Server package using port 65500

We are going to setup the dropbear-initramfs packages so we can setup a SSH server to assist us in unlocking the encrypted file system over the network.

apt install dropbear dropbear-initramfs -y
echo 'DROPBEAR_OPTIONS="-p 65500"' >> /etc/dropbear-initramfs/config

7.)  Add your host machine’s SSH pubkey to Dropbear

This is where we use the SSH key pair we created earlier on your host machine.  This command will send your public key into the Dropbear SSH configuration.

echo "your key here" >> /etc/dropbear-initramfs/authorized_keys

8.) Create temporary LUKS filesystem so we can include cryptsetup into initramfs

Make sure you follow the prompts after running cryptsetup.

dd if=/dev/zero of=/tmp/fakeroot.img bs=1M count=20
cryptsetup luksFormat /tmp/fakeroot.img
cryptsetup luksOpen /tmp/fakeroot.img crypt
mkfs.ext4 /dev/mapper/crypt

9.) Create/update initramfs

We are going to create a new initramfs using the mkinitramfs command, which should include our cryptsetup and dropbear configuration.

mkinitramfs -o /boot/initramfs.gz
lsinitramfs /boot/initramfs.gz | grep 'dropbear\|cryptsetup'

10.) Shutdown system

Now we need to shutdown the system, so we can move our SD card to our host machine to finish setup.

shutdown -t 0

 ⭢  back on your host machine

1.) Insert SD card, and mount to backup and create LUKS volume.

After inserting the SD card, you should have a new device show up in your block devices, check to make sure with lsblk. On my system it was /dev/sdc, but yours may be different. If the new device does not show up, try refreshing the device list with the command partprobe.

Here we are going to create some folders on the host machine to store our mounted data so we can move it to our new encrypted partition.

rm -rf /mnt/{chroot,backup,encrypted}
mkdir -p /mnt/{chroot,backup,encrypted}

2.) Mount and copy the data for future restoration.

Here we mount and copy the contents to our newly created locations.

mount /dev/sdc2 /mnt/chroot/
rsync -avh /mnt/chroot/* /mnt/backup/
umount /mnt/chroot

3.) Delete and create rootfs partition

Once that is done, we delete the existing 2nd partition on the SD card and recreate an empty one, which we set up for LUKS encryption.

echo -e "d\n2\nw" | fdisk /dev/sdc
echo -e "n\np\n2\n\n\nw" | fdisk /dev/sdc

*NOTE: Depending on the way the raspbian.img was burned, you may need 1 more step to this process due to the partition spacing before the boot partition.  This fix will make sure the new root partition will be created with the correct size.

TEMP_START_VAR=$(cat /sys/block/sdc/sdc1/start)
TEMP_SIZE_VAR=$(cat /sys/block/sdc/sdc1/size)
TEMP_VAR=$((${TEMP_START_VAR} + ${TEMP_SIZE_VAR}))
echo -e "n\np\n2\n${TEMP_VAR}\n\nw" | fdisk /dev/sdc

4.) Create our new LUKS encrypted partition

With the partitions updated, we reload them by running partprobe and then configure LUKS on the new partition.

cryptsetup -v -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sdc2
cryptsetup -v luksOpen /dev/sdc2 crypt
mkfs.ext4 /dev/mapper/crypt

5.) Restore the root file system backup to the now encrypted partition.

mount /dev/mapper/crypt /mnt/encrypted/
rsync -avh /mnt/backup/* /mnt/encrypted/
sync
umount /mnt/encrypted/
cryptsetup luksClose /dev/mapper/crypt

6.) Done.  Put the SD card back into your Raspberry Pi and boot up.

Conclusion

At this point, you should be able to boot your Raspberry Pi device to a screen asking for your password to unlock system.  If you have a display on your Raspberry Pi device, you can enter the password right into the console.  If you have a network connection, you should be able to SSH to port 65500 using the SSH key pair we created in step 1, which will get you to the same password prompt asking for unlock password.  Enter the password you created in the previous steps, and enjoy.

In the next post, we are going to take what we already have here, and setup wireless unlocking to the list, by adding our wireless device drivers into the initramfs.

Leave a Reply

Your email address will not be published.