format_list_bulleted

Self-Signed Secure Boot for Full-Encrypted Fedora

dark_mode
Self-Signed Secure Boot for Full-Encrypted Fedora
Protect the kernel and initrd by packing and signing unified kernel image.
fedora
secure-boot
unified-kernel-image
visibility -- public -- group --

The script is originally completed on May 8, 2024.

This tutorial mainly shown how to protect your boot chain which aims to prevent the Evil Maid Attack.

Why cannot we fully trust GRUB?

The /boot is usually not protected. Anyone who can physically access the device can tamper the kernel and initramfs.

The GRUB can validate the kernel and initrd, but does not validate its configuration itself. And signing files under /boot is complicated.

Alternative to Secure Boot

Some NVMe devices support TCG security functions such as Pyrite (controller password) and Opal (on-disk encryption). Attacker cannot tamper the disk without correct password.

But it requires to be attended boot.

Unattended boot with Clevis LUKS

Clevis will unlock LUKS volumes by passphrase stored in TPM on boot. Refer to ArchLinux Wiki and Red Hat.

clevis luks bind -d /dev/sdX tpm2 '{}'

Set up

Install dependencies

  • dracut
  • efitools
  • openssl
  • sbsigntools
  • systemd-boot: EFI stub file is required by dracut
dnf install dracut efitools openssl sbsigntools systemd-boot

[!CAUTION]

Backup your UEFI configuration, ESP and bootloader, have a backup in case the unexpected happens.

Configure Secure Boot to Custom Mode

[!NOTE]

It depends on your UEFI firmware.

Setup under Custom Mode: PK, KEK and DB keys

[!IMPORTANT]

Make sure your COMPLETELY understand how the commands operate before acting.

Refer to Simon Ruderich’s article.

Generate keypairs

openssl req -new -x509 -newkey rsa:2048 -subj "/CN=PK/"  -keyout PK.key  -out PK.crt  -days 7300 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=KEK/" -keyout KEK.key -out KEK.crt -days 7300 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=db/"  -keyout db.key  -out db.crt  -days 7300 -nodes -sha256

Translate public keys (certificate) to EFI signature lists

cert-to-efi-sig-list PK.crt PK.esl
sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth

cert-to-efi-sig-list KEK.crt KEK.esl
sign-efi-sig-list -k PK.key -c PK.crt KEK KEK.esl KEK.auth

cert-to-efi-sig-list db.crt db.esl
sign-efi-sig-list -k KEK.key -c KEK.crt db db.esl db.auth

Write PK, KEK, DB public keys into EFI Var

efi-updatevar -f db.auth db
efi-updatevar -f KEK.auth KEK
efi-updatevar -f PK.auth PK

[!TIP]

Some UEFI firmwares support enrolling PK, KEK, DB public keys in the Setup interface. It’s recommended if your firmware supports.

[!IMPORTANT]

Protect your UEFI Setup by admin password to keep SecureBoot truly effective.

[!WARNING]

The keys can be reset in UEFI Setup. You may not have to back them up. But make sure you kept the UEFI Setup password well!

Packing unified kernel image with dracut

dracut is a shell script for generating initramfs/initrd image. The .conf files are shell scripts with environment variable definitions inside.

Write the kernel cmdline to /etc/dracut.conf.d/cmdline.conf:

kernel_cmdline=$(cat /proc/cmdline)

Alternatively, you can also add the kernel cmdline as an option to dracut.

dracut --kernel-cmdline $(cat /proc/cmdline)

For x86_64 machines:

dracut \
    --kernel-cmdline $(cat /proc/cmdline) \
    --uefi-stub /lib/systemd/boot/efi/linuxx64.efi.stub \
    --uefi /boot/efi/EFI/$(uname -r).efi

Sign the UKI

sbsign --key db.key --cert db.crt --output /boot/efi/EFI/$(uname -r).efi /boot/efi/EFI/$(uname -r).efi

Add boot entry to UEFI for the UKI

efibootmgr \
    -L "Fedora - $(uname -r)" \
    --loader /boot/efi/EFI/$(uname -r).efi \
    --create

Activate Secure Boot: Standard Mode

Make sure everything is ready.

Reboot and enter UEFI Setup. Set Secure Boot to Standard Mode.

Check that your Secure Boot settings truly affect

You can validate the self-signed Secure Boot by adding another EFI executable without valid signature to UEFI. If it rejects booting EFI executables without valid signature, the Secure Boot does work.

[!WARNING]

For this step, you have to check manually. It is IMPORTANT!

[!TIP]

Copy /boot to the encrypted partition. Copy them back before update. So that you don’t need to protect /boot anymore.