This is an n+1 th guide on setting up a Raspberry Pi to boot on an encrypted external disk, to complement n other guides, including:
- https://rr-developer.github.io/LUKS-on-Raspberry-Pi/
- https://askubuntu.com/a/1296450
- https://github.com/ViRb3/pi-encrypted-boot-ssh
Enabling boot on USB
Either use the official Raspberry Pi Imager utility or do
# echo "program_usb_boot_mode=1" >> /boot/config.txt
on an existing installation, and reboot.
Installing cryptsetup
on the disk image
Get a disk image of Raspberry Pi OS on https://www.raspberrypi.com/software/operating-systems. The Lite version will also work fine.
Restore it on the destination disk, and boot the Pi.
Install cryptsetup
, which is not present in the original image:
# apt install cryptsetup cryptsetup-initramfs
# shutdown -h now
Encrypting the volume
In the previous step, the root partition got expanded to the size of the disk by the installer. We have to undo that to avoid spending a day encrypting a large mostly empty partition.
This is most easily done with gparted and its very good support for encrypted volumes.
Once the partition is resized, encrypt it, replacing sdb2
by the name of the root partition you just resized:
# lsblk -f # Note the partition name and its UUID
# cryptsetup-reencrypt --new --reduce-device-size=16M --type=luks2 \
-c xchacha12,aes-adiantum-plain64 -s 256 -h sha512 --use-urandom /dev/sdb2
This should take roughly 30 minutes.
After that, you can expand again the now-encrypted partition with gparted.
Configuring crypttab
and fstab
With the partition mounted, set /etc/crypttab
to
rootfs UUID=XXX none
replacing XXX
by the UUID of the encrypted root partition (with FSTYPE
equal to crypto_LU
).
Change the /etc/fstab
line about the rootfs
partition to
/dev/mapper/rootfs / ext4 defaults,noatime 0 0
On the boot partition, add the following to the kernel parameters in cmdline.txt
:
cryptdevice=UUID=XXX:rootfs
replacing again XXX
by the partition UUID above.
Unattended decrypt with key on an external device (optional)
The following step is optional; it allows reading the decryption key from an external medium (USB key, SD card) rather than using an interactive prompt.
Mount your external medium, label the partition, generate a key, and add it to the encrypted partition
# sudo e2label /dev/sdc2 sd # Label the device
# dd if=/dev/urandom of=/mnt/sd/key bs=4096 count=1
# cryptsetup luksAddKey /dev/sdc2 /mnt/sd/key
replacing sdc2
by the partition name of your external medium.
To your cmdline.txt
, add
cryptkey=/dev/disk/by-label/sd:ext4:/key.txt
At boot, the partition will automatically be mounted to read the key. If this fails, decrypting the root partition will fallback to a prompt.
Boot and update initramfs
Finally, boot again the Pi with the disk attached.
On this first boot, decrypting the volume will fail and an initramfs
prompt will be open (possibly after a minute or so of retries). Open the volume manually:
# lsblk # Note partition name
# cryptsetup luksOpen /dev/sba2 rootfs
# exit
This should allow booting normally, after which you can execute
# update-initramfs -u
The next reboot should then work properly, with or without password prompt depending on whether you followed the optional step.