As the Raspberry Pi boots from the SD card by default and there are no other boot options, the r/w speed on the SD card is quite limited.
Therefore, this tutorial covers full disk encryption with LUKS and configuring the rootfs on a different drive.
Initial Encryption
First of all, install cryptsetup:
sudo apt install cryptsetup
With the GitHub tutorial mentioned in [1] the initial encryption is setup on another host PC. If you are planning to move your rootfs from e.g. mmcblk0p2 on another drive, this is not needed.
Instead, download the raspberry pi image of your choice (I used Ubuntu for this) and let the Pi boot from the SD card. Then attach your external drive (e.g. SSD with USB3.0 to SATA adapter).
This is easier, as cryptsetup on the Pi will use the correct encryption which has hardware support. Otherwise, check out the tutorial in [1] for the suggested encryption flags for the Pi.
Now, encrypt and partition the drive:
sudo cryptsetup luksFormat /dev/sda
sudo cryptsetup open /dev/sda crypted
sudo mkfs.ext4 /dev/mapper/crypted
Copy system files
It should be sufficient to sync all existing data to the new drive. You can do this also on another PC. Use sudo to keep all permissions the same. If you do this while the system is running, make sure to exclude the mountpoint of the external drive.
sudo rsync --archive --hard-links --acls --xattrs --one-file-system --numeric-ids --info="progress2" /mnt/original/* /mnt/chroot/
Update Boot Configuration
Edit /etc/fstab with the new root entry for your drive:
/dev/mapper/crypted / ext4 discard,errors=remount-ro 0 1
LABEL=system-boot /boot/firmware vfat defaults 0 1
Check the UUID of your partitions (crypted and decrypted):
$ blkid
/dev/mapper/crypted: UUID="aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" TYPE="ext4"
/dev/mmcblk0p1: LABEL_FATBOOT="system-boot" LABEL="system-boot" UUID="aaaa-aaaa" TYPE="vfat" PARTUUID="aaaaaaaa-aa"
/dev/sda1: UUID="aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" TYPE="crypto_LUKS" PARTUUID="aaaaaaaa-aa"
Add an entry for your encrypted partition in /etc/crypttab.
crypted UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa none luks,initramfs
Update the root entry in the U-Boot configuration /boot/cmdline.txt. Keep all other configurations in this file as you need.
root=/dev/mapper/crypted cryptdevice=UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:crypted
Dropbear Configuration
First, install Dropbear. Unfortunately for Ubuntu 20.04 LTS the dropbear packages are not up to date and are missing the latest security updates. However, they are available in the Debian repositories or in the newer, non LTS Ubuntu repositories. You can find the Debian dropbear package under [6].
There should be no problem installing the newer version of dropbear as the dependencies are the same.
The following packages need to be installed. For reference, the apt command is included here. Replace it with dpkg -i <deb file> ... to install the manually downloaded packages.
sudo apt install dropbear dropbear-bin dropbear-initramfs
All dropbear needs to know are your authorized keys, so it is possible to just copy the file:
sudo cp ~/.ssh/authorized_keys /etc/dropbear/initramfs/
With the latest dropbear version, dropbear also accepts the ed25519 keytype.
Dropbear generates a new host key by default, so if you do not want to change it with the dropbearkey command (see its manpage [5]) add a special host configuration for your SSH client like:
Host box-initramfs
Hostname 192.168.0.30
User root
UserKnownHostsFile ~/.ssh/known_hosts.initramfs
To get the key format of your dropbear key for your known_hosts file run:
sudo dropbearkey -y -f /etc/dropbear-initramfs/dropbear_ed25519_host_key
If you only want to allow the unlocking of the boot volume, change the dropbear options in /etc/dropbear-initramfs/dropbear.conf like:
DROPBEAR_OPTIONS="-sjk -c cryptroot-unlock"
Update the initramfs afterwards:
sudo update-initramfs -u
For more options see the dropbear manpage [4].
References and further information
[1] Github ViRb3/pi-encrypted-boot-ssh
[2] Decrypting boot drives remotely using dropbear
[3] Cyberciti - How to unlock LUKS using Dropbear SSH keys remotely in Linux
[4] Dropbear Manpage