Secure Boot
Secure Boot
Secure Boot is a UEFI security feature designed to protect the pre-boot environment from malware like bootkits and rootkits, or to strictly enforce which operating systems are permitted to load. By validating bootloaders, kernels, and drivers against a user-controlled database of authorized cryptographic signatures, it blocks both unauthorized code and unapproved operating systems from executing.
ATTENTION: When using Secure Boot it's imperative to use it with disk encryption. If the storage device that stores the keys is not encrypted, anybody can read the keys and use them to sign bootable images, thereby defeating the purpose of using Secure Boot at all. Therefore, this guide will assume disk encryption is being used.
Preparations
Firmware
To determine the current state of Secure BootBoot, execute:
bootctl status
This prints information about the current boot environment:
System:
Firmware: UEFI 2.70 (EDK II 1.00)
Firmware Arch: x64
Secure Boot: disabled (user) <-- SEE THIS LINE
TPM2 Support: yes
Measured UKI: no
Measured OS: no
Boot into FW: supported
Platform Lang: n/a
...
InTo order to proceedproceed, you need tomust set your firmware's Secure Boot mode intoto "setup"Setup mode.Mode This(this canis usually be achieveddone by clearing/wiping the keydefault storefactory ofkeys theinside firmware.your UEFI settings). Refer to your mainboard'motherboard's user manual onfor howspecific to do this.instructions.
WARNING: Purging default Secure Boot keys to enroll custom ones can soft-brick your machine! Hardware Option ROMs (OpROMs)—such as your GPU's VBIOS—are typically signed using the Microsoft 3rd Party UEFI CA certificate. If this specific certificate is missing from the signature database (db) when Secure Boot is active, the firmware will block the GPU's OpROM from executing. This results in a black screen during POST, completely disabling display output and locking you out of the UEFI settings needed to revert the change!
Unified Kernel Image
The most practical way to sign images is a Unified Kernel Image, which combines everything the systemkernel, needsinitramfs, and kernel command line into a single file.EFI executable.
mkinitcpio recommends using ukify for UKI generationgeneration. butInstall it'sit as an optional dependency that needs to be installed:dependency:
pacman -S --asdeps systemd-ukify
If mkinitcpio detects ukify on the systemsystem, it useswill use it automatically. Refer to your local UKI configuration on how to set up UKIs with mkinitcpio.
Refer to the Unified Kernel Image section of initramfs on how to set up UKIs with mkinitcpio.
Generating keys
SEE ALSO: The Meaning of all the UEFI Keys
Secure Boot implementations use these keys:
| Key Type | Description |
|---|---|
| Platform Key (PK) | Establishes platform ownership and toggles Setup Mode. The private key signs updates to the KEK database. |
| Key Exchange Key (KEK) | Database of certificates authorized to sign updates to db and dbx. |
| Signature Database (db) | Database containing certificates or SHA-256 hashes of allowed EFI binaries, kernels, and Option ROMs. |
| Forbidden Signatures Database (dbx) | Database containing revoked certificates or hashes of banned binaries. Checked first; overrides matches in db. |
systemd-ukify has built-in support for generating Secure Boot keys.keys Itand can thenwill use systemd-sbsign to sign the UKIsgenerated it generates.UKIs.
TheTo simplestgenerate waythe ofkeys, generating keys is supplyingsupply ukify with a configconfiguration file that lists all the keys intended for signing.file. Create /etc/kernel/uki.conf with the following contents:
NOTE: The [PCRSignature] sections are optional. They allow a TPM to unlock a LUKS volume with signed PCR Policies during boot. If you don't intend to use TPM unlocking, you can leave them out.
[UKI]
SecureBootSigningTool=systemd-sbsign
SignKernel=true
SecureBootPrivateKey=/etc/kernel/secure-boot-private-key.pem
SecureBootCertificate=/etc/kernel/secure-boot-certificate.pem
[PCRSignature:all]
PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key.pem
PCRPublicKey=/etc/systemd/tpm2-pcr-public-key.pem
[PCRSignature:initrd]
Phases=enter-initrd
PCRPrivateKey=/etc/systemd/tpm2-pcr-private-key-initrd.pem
PCRPublicKey=/etc/systemd/tpm2-pcr-public-key-initrd.pem
Instruct ukify to generate the keys listed in the config file:
ukify genkey --config=/etc/kernel/uki.conf
IfWhen mkinitcpio isrebuilds setthe upinitramfs toduring generatesystem UKIsupgrades withit calls ukify itwith /etc/kernel/uki.conf and will automatically sign the resulting UKIs itwith buildsthe duringkeys systemlisted upgradesin from thisthat config.
Signing systemd-boot
The bootloader ofitself a Secure Boot system needs tomust be signed as well,signed, or the firmware will notrefuse authorizeto itsexecute execution when the system boots.it.
ACreate simplea pacman hook takes care of signing the bootloader during installation and upgrades, e.g.at /etc/pacman.d/hooks/90-systemd-boot-sign.hook: to automatically sign systemd-boot during installation and upgrades:
[Trigger]
Operation = Install
Operation = Upgrade
Type = Path
Target = usr/lib/systemd/boot/efi/systemd-boot*.efi
[Action]
Description = Signing systemd-boot EFI binary for Secure Boot
When = PostTransaction
Exec = /bin/sh -c 'while read -r f; do /usr/lib/systemd/systemd-sbsign sign --private-key /etc/kernel/secure-boot-private-key.pem --certificate /etc/kernel/secure-boot-certificate.pem --output "${f}.signed" "$f"; done;'
Depends = sh
NeedsTargets
This takes all .efi binaries in the target path and creates signed .efi.signed copies of them.
Reinstall systemd to invoke the hook:bootloader signing hook and build a signed UKI:
pacman -S --asdeps systemd
To keep the bootloader up-to-date, enable systemd-boot-update.service:
systemctl enable systemd-boot-update
It invokes bootctl update on every boot, checking if a newer version is available for installation, and copies the updated, signed version of the bootloader to the ESP.
Kernel Lockdown Mode
To further strengthen security you might want to consider using the kernel's built-in Lockdown Mode. When engaging lockdown, access to certain features and facilities is blocked, even for the root user. This helps prevent Secure Boot from being bypassed through a compromised system, for example by editing EFI variables or replacing the kernel at runtime.
Lockdown Mode knowssupports two modes of operation:levels:
integrity: Disables kernel features that allow userland to modify the running kernelare(e.g.,disabled (kexec,bpf)certain eBPF modifications, and raw port access).confidentiality:kernelAdditionallyfeatures that allowblocks userlandtofromextractextracting confidential information from the kernelare also disabledspace.
The recommended mode is integrity, as confidentiality can break certain applications (e.g. Docker).
To enable Lockdown Mode, set the lockdown= kernel command line parameter with your preferred mode.MODE
Enrolling keys in firmware
WARNING: If your system loads OpROMs (e.g. GPU firmware) you need to make sure to either include Microsoft's keys or the OpROM's digest value from the TPM Event Log into your firmware signature database. Check for OpROMs with find /sys/devices/ -name rom. If there is output, your system has OpROMs and you need to take extra steps to not soft-brick your machine!
ATTENTION: Make sure your firmware's Secure Boot mode is set to setup mode! You can do this by going into your firmware settings and wiping the factory default keys. Additionally, keep an eye out for any setting that auto-restores the default keys on system start.
Enrollingsystemd-boot is capable of enrolling Secure Boot keyskeys. canTo beinstruct accomplishedit byto do systemd-bootwithso theautomatically followingon parameters:next boot:
bootctl install \
--secure-boot-auto-enroll yes \
--certificate /etc/kernel/secure-boot-certificate.pem \
--private-key /etc/kernel/secure-boot-private-key.pem
This creates the necessary signature lists inside $ESP/loader/keys/auto/{db,KEK,PK}.auth files and instructstriggers systemd-boot to attemptnative auto-enrollment on next boot.reboot.