One of the few things I have been excited about the past year is usable
cryptography. We have a lot of neat things these days with hardware tokens, the
Trusted Platform Module (TPM) and Secure Boot. But the tooling around these
things are bad and hard to use for a while now which is why I got super excited
when I saw Lennart Poettering wrote about the upcoming systemd-cryptenroll. It
allows one to easily utilize the TPM or FIDO key for unlocking your encrypted
partition.
At this point I realized I’m still using a busybox initramfs. mkinitcpio is
what Arch Linux uses to create initramfs and it supports two sets of hooks
currently which is the “busybox” hooks and the “systemd” hooks. By default the
busybox hooks are used and users needs to be over to the systemd ones if they
want to.
At this point I also learned that GPT UUIDs, which denotes the partition type, is not only for show. systemd is capable of mounting several partitions solely based on the UUID using the “Discoverable Partitions” specification. Which is pretty neat!
Thus we have the list of goals to modernize my boot process:
- Use systemd initramfs
- EFI System Partition with only UEFI stubs (I’ll explain this!)
- Remove all UUIDs from fstab and kernel parameters
- Optional:
- Secure the boot with secure boot
- Unlock partition hardware key
Current Setup
My current setup is fairly basic I believe. It’s a laptop with two partitions.
One is the EFI system partition (ESP), mounted to /boot, and the other is an
LUKS encrypted partition formatted with btrfs for /. A few subvolumes for
snapper snapshots and the swapfile, but nothing else really.
λ ~ » tree -L 1 /var/btrfs
/var/btrfs
├── @home
├── @home-snapshots
├── @root
├── @root-snapshots
└── @swapfileλ ~ » tree /boot
/boot
├── EFI
│ ├── arch
│ │ └── fwupdx64.efi
│ ├── BOOT
│ │ └── BOOTX64.EFI
│ └── systemd
│ └── systemd-bootx64.efi
├── loader
│ ├── entries
│ │ └── arch.conf
│ ├── loader.conf
│ └── random-seed
├── intel-ucode.img
├── initramfs-linux.img
├── initramfs-linux-lts.img
├── vmlinuz-linux
└── vmlinuz-linux-lts
λ ~ » cat /boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=UUID=67c1a020-ed36-49d5-9e53-f239ee452120 \
cryptdevice=UUID=a356ac71-8f26-452c-a100-588d4e59bd19:root \
rootflags=subvol=@root rw quietThe systemd-boot entry is also fairly basic. Point at cryptdevice UUID for unlocking the root partition. The rootflags point at the root subvolme in btrfs. There is not a lot to this setup which is special.
mkinicpio and systemd
First on our agenda is to move from the busybox initramfs to the systemd one. This is the main
Old hooks
HOOKS=(base udev autodetect modconf block keymap encrypt filesystems keyboard btrfs)
New hooks
HOOKS=(systemd autodetect modconf block keyboard sd-encrypt filesystems)
Todo list
- Use systemd initrd
- Remove UUIDs from any boot stuff
- UEFI Executable with sd-boot stub
- (Optional)
- Use fido tokens
- Secure Boot
Change the GPT UUID
$ gdisk /dev/nvme0n1
GPT fdisk (gdisk) version 1.0.7
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): t
Partition number (1-2): 2
Current type is 8304 (Linux x86-64 root (/))
Hex code or GUID (L to show codes, Enter = 8304): 8304 // <- note the number
Changed type of partition to 'Linux x86-64 root (/)'
Command (? for help): w // write the table
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Command (? for help): i
Partition number (1-2): 2
Partition GUID code: 4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709 (Linux x86-64 root (/))
Partition unique GUID: 44C302FB-1AE1-49B5-9C78-484B7BAFDE6C
First sector: 1050624 (at 513.0 MiB)
Last sector: 1000215182 (at 476.9 GiB)
Partition size: 999164559 sectors (476.4 GiB)
Attribute flags: 0000000000000000
Partition name: 'Linux x86-64 root (/)'$ cat /etc/fstab
/dev/mapper/root / btrfs rw,noatime,compress=lzo,subvol=@root 0 0
# /dev/mapper/lvm
/dev/mapper/root /.snapshots btrfs rw,noatime,compress=lzo,subvol=@root-snapshots 0 0
# /dev/mapper/lvm
/dev/mapper/root /home btrfs rw,noatime,compress=lzo,subvol=/@home,subvol=@home 0 0
# /dev/mapper/lvm
/dev/mapper/root /home/.snapshots btrfs rw,noatime,compress=lzo,subvol=@home-snapshots 0 0
# /dev/mapper/lvm
/dev/mapper/root /var/swap btrfs rw,noatime,compress=lzo,subvol=@swapfile 0 0$ cat /etc/kernel/cmdline.systemd
rw quiet acpi_osi= acpi_backlight=thinkpad_screen nowatchdog bgrt_disable$ systemd-cryptenroll --fido2-device=auto /dev/nvme0n1p2
🔐 Please enter current passphrase for disk /dev/nvme0n1p2: *****************
Initializing FIDO2 credential on security token.
👆 (Hint: This might require verification of user presence on security token.)
Generating secret key on FIDO2 security token.
👆 In order to allow secret key generation, please verify presence on security token.
New FIDO2 token enrolled as key slot 1.- Usecase
- systemd-crypsetup
- fido tokens
- Optional: TPM2
- UEFI Executables
- Simplifying boot
- GPT UUIDs
The bad :c
No 2FA. Only TPM2 and/or FIDO2. Mention PIN