So I have decided to go Void Linux on all my machines. One of the advantages for me was the absence of systemd and the presence of musl libc, my admiration for which I shared in a recent blog post about Alpine Linux. I was trying to find a tutorial on how to make an encrypted root partition work with Raspberry Pi. I have a strong belief that all offline storage should be encrypted today. I found multiple tutorials, which I made work together in this one.
You can skip the first step if you have Void Linux already running on your Raspberry Pi.
Configuring dracut and modules
Install Void Linux like you normally would by following
on an existing Linux machine. Alternatively, you can follow the commands I used
below. Remember to replace
sdX with your SD card’s path in
/dev which you
can look up with the command
# parted /dev/sdX (parted) mktable msdos (parted) mkpart primary fat32 2048s 256MB (parted) toggle 1 boot (parted) mkpart primary ext4 256MB -1 (parted) quit # mkfs.vfat -F32 /dev/sdX1 # mkfs.ext4 -O ^has_journal /dev/sdX2 # mkdir rootfs # mount /dev/sdX2 rootfs/ # mkdir rootfs/boot # mount /dev/sdX1 rootfs/boot # tar xvfJp void-rpi-rootfs-latest.tar.xz -C rootfs # echo '/dev/mmcblk0p1 /boot vfat defaults 0 0' >> rootfs/etc/fstab
Insert the SD card to your Raspberry Pi and boot it up.
Connect via ssh (user: root, password: voidlinux).
Set your hostname with the command
hostname your-hostname and also put this hostname in
Void Linux wiki also tells you to start ntpd with
sv start ntpd for https certificates to work (required for xbps to download packages).
It was enabled by default on my system, so just check that it is running with
sv status ntpd.
Configuring dracut and modules
You should now be logged in as root. Install the required packages for LUKS and ssh in initrd, as well as the crypt-ssh module:
# xbps-install -S cryptsetup dropbear dracut-crypt-ssh busybox
Let’s configure dracut now following the tutorial at the project’s github site. Change the values in crypt-ssh module’s configuration file /etc/dracut.conf.d/crypt-ssh.conf:
dropbear_port="22" dropbear_rsa_key="/root/.dracut/ssh_dracut_rsa_key" dropbear_ecdsa_key="/root/.dracut/ssh_dracut_ecdsa_key" dropbear_acl="/root/.dracut/authorized_keys"
I also changed the port to 22, you can leave the default 222.
dropbear_acl can be left as is, but I strongly recommend creating a separate
authorized_keys file because these can be easily extracted from initrd later on.
We generate ssh keys like so:
# umask 0077 # mkdir /root/.dracut # ssh-keygen -t rsa -f /root/.dracut/ssh_dracut_rsa_key # ssh-keygen -t ecdsa -f /root/.dracut/ssh_dracut_ecdsa_key
Using passphrases made
dropbear_convert fail for me, so do not use them. I do not think they are needed here.
Now add the key(s) to authorized keys:
# touch /root/.dracut/authorized_keys # chmod 700 /root/.dracut/authorized_keys # cat /root/.dracut/ssh_dracut_rsa_key.pub >> /root/.dracut/authorized_keys # cat /root/.dracut/ssh_dracut_ecdsa_key.pub >> /root/.dracut/authorized_keys
I also used the following dracut configuration, which you can place in 05-custom.conf:
omit_dracutmodules+="bash dash btrfs" add_dracutmodules+="busybox" install_items+=/etc/crypttab
I blacklisted bash and dash because I prefer busybox so why have them. We shouldn’t even need a shell in dracut, because there will only be one command to execute over ssh. I blacklisted btrfs because it was spamming my dmesg log.
Before you generate a dracut image, we need to adjust fstab for this change. Put the following into /etc/fstab:
/dev/mapper/crypt / ext4 defaults,noatime 0 1
While /etc/crypttab says that you should not have the root partition listed, it is needed for crypt-ssh module to work:
crypt /dev/mmcblk0p2 none luks
Now let’s update the files on boot partition to reflect the changes: add this to cmdline.txt
And change the value of root and add a
cryptdevice entry before it. I am not sure if the order matters or not.
add this to config.txt:
initramfs initrd.img followkernel
You can finally generate a dracut image:
dracut /boot/initrd.img --force
Now poweroff the Raspberry Pi and insert the SD card into another Linux machine. We are going to backup the SD card, create the LUKS volume and then put the files back on the SD card. You will also need to have cryptsetup installed on this Linux machine.
# mount /dev/sdX2 rootfs # mkdir backup # cp -a rootfs/* backup # umount rootfs # wipefs -a /dev/sdX2 # cryptsetup luksFormat /dev/sdX2 # cryptsetup luksOpen /dev/sdX2 raspi # mkfs.ext4 /dev/mapper/raspi # mount /dev/mapper/raspi /rootfs # cp -a backup/* rootfs
Now, after booting Raspberry Pi, wait a few seconds and then connect to it via
ssh using the dracut-specific ssh key and run the
ssh -p 22 email@example.com -i /path/to/ssh_dracut_rsa_key unlock < your_luks_passphrase
It may show a warning but as long as it boots, it’s fine.
If it doesn’t, open a ssh shell and kill all
Problems may occur when upgrading the kernel.
I will update this article if such thing happens and I figure out how to fix the problem.