Cheatsheet: encrypt the root filesystem on an existing Arch Linux install

Worried that your notebook might fall into the wrong hands, but you didn’t encrypt / when you set it up? This will fix it.

This cheatsheet makes a few assumptions:

  1. Your computer uses EFI, not legacy BIOS.
  2. You’re using an EFI boot stub to boot, not GRUB or some other bootloader.
  3. You are not using a unified kernel image.
  4. You’re using a busybox-based initramfs, not a systemd-based initramfs.
  5. Your root filesystem is btrfs-formatted and doesn’t use subvolumes.

The boot device in my computer is /dev/nvme0n1. /dev/nvme0n1p1 is the EFI system partition, which gets mounted as /boot. /dev/nvme0n1p3 is the btrfs root filesystem for my Arch Linux install; its label is arch_root and /etc/fstab is set to mount by label. Substitute appropriate values for your system wherever you see these.

  1. Boot from an Arch ISO. Current versions of SystemRescueCD are based on Arch and should also work.
  2. Mount the root filesystem: mkdir /mnt/arch && mount /dev/nvme0n1p3 /mnt/arch
  3. Shrink the root filesystem. This will be an iterative process. First, examine the output of btrfs filesystem usage -b /mnt/arch. There should be a line with something like “(min: some-number)” in it. Resize the filesystem with the negative of that number: btrfs filesystem resize -some-number /mnt/arch. Repeat both commands until the second one returns an error; at this point, the root filesystem is shrunk to its minimal size, which ought to speed up the encryption step.
  4. Unmount the filesystem: umount /mnt/arch
  5. Encrypt the filesystem: cryptsetup reencrypt --encrypt --reduce-device-size 32M /dev/nvme0n1p3. You’ll be prompted for a passphrase. This will need to be entered every time you boot your computer, so a long random string from a password manager, while secure, is probably not a good idea from a usability standpoint. Also, this phase will probably take a while. I shrunk the root filesystem down to about 90 GB, and with the Core i7-1165G7 in my Framework 13, encryption took about a half-hour.
  6. Mount the encrypted filesystem: cryptsetup open /dev/nvme0n1p3 recrypt && mount /dev/mapper/recrypt /mnt/arch
  7. Expand the filesystem back to use the rest of the partition: btrfs filesystem resize max /mnt/arch
  8. Mount the EFI partition and chroot into your Arch install: mount /dev/nvme0n1p1 /mnt/arch/boot && arch-chroot /mnt/arch
  9. Edit /etc/mkinitcpio.conf. There’s a line that starts with HOOKS=. Look for block within that line, and add encrypt after it.
  10. Regenerate the initramfs: mkinitcpio -P
  11. Get the UUIDs of the encrypted container and the decrypted filesystem: ls -l /dev/disk/by-uuid. This directory has symlinks to the actual device nodes, so the one pointing to /dev/mapper/recrypt is the decrypted filesystem UUID (we’ll call it fs_UUID) and the one pointing to /dev/nvme0n1p3 is the encrypted container UUID (we’ll call it enc_UUID).
  12. Update the EFI boot config. First, use efibootmgr --unicode to find your existing Arch boot entry. Make note of any existing kernel command-line options, then delete it with something like efibootmgr -b 1 -B (if your boot entry was labeled Boot0001). Then, create the updated entry with something like this: efibootmgr --disk /dev/nvme0n1 --part 1 --create --label "Arch Linux" --loader /vmlinuz-linux --unicode 'initrd=\initramfs-linux.img cryptdevice=UUID=enc_UUID:recrypt:allow-discards root=UUID=fs_UUID rootflags=rw zswap.enabled=0 rw rootfstype=btrfs'
  13. Exit the chroot and reboot. Enter your passphrase (from step 5) when asked.

References

Arch Linux Wiki: dm-crypt: Encrypt an existing unencrypted file system
Arch Linux Wiki: dm-crypt: Unlocking in early userspace
Resize btrfs filesystem to the minimum size in a single step
LUKS encryption with EFISTUB boot?

Leave a Reply

Only people in my network can comment.