Contents

Secure Boot on Linux Without Losing Your Mind

Your own keys, a signed kernel, and a firmware menu that fights back

Contents

Secure Boot arrived in 2012 attached to a genuine fear that Microsoft was locking Linux out of PC hardware. That fear turned out to be misplaced, the community built shim to work around it, and the result was thirteen years of Linux users treating Secure Boot as an obstacle to disable in the firmware menu on the way to installing anything.

That reflex has outlived its usefulness. Secure Boot on Linux works fine now, and on a machine using TPM-based disk unlock it stops being decorative and becomes load-bearing. It is still fiddly, the failure modes are alarming, and the documentation assumes you already understand a key hierarchy that nobody has explained to you.

So: what it actually does, how to set it up in a way you can undo, and — the part usually skipped — whether it is worth your evening.

What it defends against, precisely

Advertisement

Secure Boot verifies that each stage of boot is signed by a key the firmware trusts. Firmware checks the bootloader, the bootloader checks the kernel, and an unsigned or modified binary refuses to load.

The attack it stops is the evil maid: someone with brief physical access replaces your bootloader with one that looks identical, logs your disk passphrase, and passes it along. Your machine boots normally and you never notice. Disk encryption offers no defence — the tampering happens in the unencrypted boot partition, which has to be readable for the machine to start at all.

The attacks it does not stop are most of them. It does nothing about remote compromise, nothing about a malicious package, nothing about a weak SSH configuration, and nothing about someone with root on the running system. It is one specific control against one specific physical attack.

Which makes the homelab question sharp: does anybody sneak into your house to modify your server’s bootloader, then leave, then come back for the harvested passphrase? Almost certainly not.

The real reason to care is second-order. Secure Boot is what makes TPM-based measurements meaningful. PCR 7 records the Secure Boot policy state, and if Secure Boot is off, PCR 7 records “the policy permits anything”, which is a measurement of nothing. A TPM-sealed LUKS key without Secure Boot is a lock that opens for any kernel you care to boot, so the property you thought you bought — that the disk unlocks only for software you approved — is absent. If you are doing anything with LUKS and automated unlocking, Secure Boot is the foundation that argument stands on. On its own, it is a nice-to-have.

The four key databases, explained once

Every guide throws PK, KEK, db and dbx at you in the first paragraph and moves on. They are four lists in your firmware’s NVRAM, arranged in a hierarchy, and ten minutes understanding them saves an evening of confusion.

PK — the Platform Key. Exactly one, and it is the root. Whoever holds the PK’s private half controls the whole hierarchy, because the PK is what authorises changes to the next level down. It ships from the factory as your motherboard vendor’s key. “Setup Mode” simply means the PK slot is empty, and while it is empty the firmware accepts new keys from anyone — which is why clearing the PK is the first step of taking ownership, and why a machine left in setup mode has no security at all.

KEK — Key Exchange Keys. A list. Holding a KEK lets you modify db and dbx. Your board ships with Microsoft’s KEK in here, which is how Microsoft can push revocations to your machine through a Windows update without touching the PK.

db — the allowed list. The one that does the day-to-day work. Every binary the firmware loads must be signed by something in db, or match a hash listed in it directly. When sbctl enroll-keys -m adds Microsoft’s certificates, this is where they land, next to yours.

dbx — the forbidden list. Signatures and hashes that are refused even when db would otherwise allow them. This exists because Microsoft signed a number of bootloaders that turned out to be exploitable, and revoking a signature is impossible without a blocklist. dbx grows over time and is pushed out via fwupd on Linux or Windows Update, and it is why “signed by Microsoft” and “trusted” have drifted apart.

The practical consequence: taking ownership means clearing the PK to enter setup mode, then enrolling your PK, KEK and db in one operation — which is precisely what sbctl enroll-keys does. Nothing exotic is happening. It is writing four EFI variables, and the reason the process feels arcane is that vendors give the operation a different name in every firmware menu they ship.

One warning that follows directly from the hierarchy: a firmware update can reset all four lists to factory defaults. Your keys go, your signatures no longer match anything in db, and a machine that booted fine yesterday now does not. Nothing is broken and nothing is lost — sbctl enroll-keys again puts it back, since your private keys still live in /usr/share/secureboot on the disk. Back that directory up somewhere off the machine, though. Losing it means regenerating everything and re-signing from a live USB.

Shim, or your own keys

Advertisement

Two routes, and picking wrong is how people end up in a firmware menu at midnight.

Shim and MOK is what Ubuntu, Fedora and Debian ship. A small bootloader signed by Microsoft’s key — which every consumer firmware trusts — loads, then verifies GRUB and the kernel against its own Machine Owner Key database. Secure Boot works out of the box. When you build a DKMS module, mokutil prompts you to enrol a key through a blue screen at the next boot.

This works, requires nothing, and has a philosophical wart: your machine’s chain of trust is rooted in Microsoft’s signature. Your firmware trusts Linux because Microsoft vouched for it. That is a fact about the world rather than a practical problem, and if it bothers you, that is a legitimate reason to do the other thing.

Your own keys means clearing the factory Platform Key, enrolling your own, and signing everything yourself. The firmware then trusts your key and nothing else — including, if you choose, not Microsoft’s. This is more work, more control, and considerably more ways to end up with a laptop that will not boot.

sbctl has made the second route roughly ten times less painful than it was, and it is what I use.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Firmware must be in Setup Mode first — clear the platform key in the BIOS
$ sbctl status
Installed:       sbctl is not installed
Setup Mode:      Enabled
Secure Boot:     Disabled

$ sbctl create-keys
Created Owner UUID 8f2c...
Creating secure boot keys...

# The -m flag ALSO enrols Microsoft's keys. Read the next section before omitting it.
$ sbctl enroll-keys -m
Enrolling keys to EFI variables...

$ sbctl verify
Verifying file database and EFI images in /boot...
 /boot/EFI/systemd/systemd-bootx64.efi is not signed
 /boot/vmlinuz-linux is not signed

$ sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efi
$ sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI
$ sbctl sign -s /boot/vmlinuz-linux

The -s flag adds each file to sbctl’s database, so sbctl sign-all re-signs everything after a kernel update, and the pacman/apt hooks call it automatically. Forget -s and your next kernel update produces an unbootable machine, which is a lesson best learnt with a live USB in the drawer.

The -m flag, and the option to brick your board

enroll-keys -m includes Microsoft’s certificates in your db alongside your own. Purists object, since the entire point was to remove Microsoft from your trust chain, and it does mean the firmware will still load anything Microsoft signed — including, notoriously, old vulnerable bootloaders that have been used as Secure Boot bypasses.

Include them anyway, on any machine you value, for one boring reason: many vendors sign their UEFI option ROMs with Microsoft’s third-party key. Your GPU’s video BIOS, your NIC’s PXE stack, your RAID controller’s firmware. Remove Microsoft’s key on some boards and they refuse to POST, because the firmware cannot verify its own option ROM and gives up before anything else happens. There is no menu at that point. There is a machine that does not turn on.

Some boards handle it fine. Some brick. Which category yours falls into is discoverable only by trying, and the recovery is a hardware programmer and a SOIC clip. On a desktop with a socketed BIOS chip and a spare afternoon, experiment. On a laptop, use -m.

Unified kernel images, which fix the annoying part

The classic setup signs the bootloader and the kernel and leaves the initramfs unsigned, because nothing verifies it. That is a hole roughly the size of the one you were trying to close — the initramfs is what asks for your passphrase, and an attacker who can modify it is exactly the evil maid.

A unified kernel image bundles the kernel, initramfs, kernel command line and a stub into one signed PE binary. One file, one signature, everything covered. It also makes TPM measurement coherent, since PCR 11 now measures one blob rather than a set of pieces measured separately.

1
2
3
4
5
# /etc/mkinitcpio.d/linux.preset (Arch)
ALL_kver="/boot/vmlinuz-linux"
PRESETS=('default')
default_uki="/boot/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

kernel-install on Fedora and dracut --uefi do the equivalent. systemd-boot finds anything in /boot/EFI/Linux/ automatically and builds a menu, so you can drop GRUB entirely — a real simplification, since GRUB’s Secure Boot story involves a module-loading design that has produced a steady stream of CVEs.

The cost is that the kernel command line is baked in and signed, so changing a boot parameter means regenerating the image. That is a feature. An attacker appending init=/bin/bash to your command line was the other obvious bypass.

Troubleshooting

Advertisement

sbctl enroll-keys fails with “not in setup mode”. The firmware still holds the factory Platform Key. Find the Secure Boot section of your BIOS and choose “Clear keys”, “Erase all secure boot settings” or “Delete PK”, depending on which vendor’s UI you are enduring. Vendors hide this under Advanced, Security, or occasionally Boot.

The machine boots straight to firmware after enabling Secure Boot. Something in the chain is unsigned. sbctl verify from a live USB with the ESP mounted lists exactly what. Usually it is BOOTX64.EFI, the fallback path, which people forget because it is a copy of the bootloader under a different name.

Everything worked, then a kernel update broke it. The hook did not fire, or you signed without -s so the file is not in the database. sbctl list-files shows what it knows about. Add the pacman hook or the dracut/kernel-install integration, then test a reboot while you are sitting in front of the machine.

The NVIDIA module refuses to load: “Key was rejected by service”. Kernel lockdown is on because Secure Boot is on, and unsigned modules cannot load. Either sign the DKMS output with your key (/etc/dkms/framework.conf has mok_signing_key and mok_certificate for this), or use the distribution’s signed build. Sign automatically or you will do it manually every kernel update for a month, then give up.

Windows dual-boot demands the BitLocker recovery key. Predictable and your own fault. Changing the Secure Boot state changes PCR 7, and BitLocker sealed against it. Suspend BitLocker in Windows before touching Secure Boot, then resume it afterwards. Have the recovery key to hand either way.

“Verification failed: (0x1A) Security Violation” from shim. You are mixing routes: shim is loading, but the thing after it is signed with a key shim does not know. Pick one design and stick to it — shim with MOK, or your own keys with sbctl.

What it costs, honestly

Setup on a machine you can see is about an hour, most of it in the firmware menu learning where your vendor put things.

The ongoing cost is a small tax on every kernel update. With the hooks wired correctly it is zero, right up to the day something changes — a new bootloader version at a new path, a DKMS module that skips the signing step, a firmware update that clears your keys and drops you back to setup mode with a machine that no longer boots. That last one has happened to me once, and it is exactly as fun as it sounds.

Keep a live USB with sbctl on it. Not “consider keeping”. Keep one, in the drawer, before you start.

The pairing that makes this worthwhile is Secure Boot plus a UKI plus TPM-sealed LUKS. Together they give you a machine that unlocks itself automatically, only when running the exact software you signed, with no passphrase to type and no key on the disk. Any one of the three alone is a partial answer; the set is a coherent one, and it is the setup I would build for a machine that has to come up alone after a power cut.

The verdict

For most homelabs, this is optional and you should feel no guilt. If you can name the last person other than you who touched your server physically, and the answer is nobody, Secure Boot is defending a door that faces a wall. Your time buys more security in SSH hardening, in kernel sysctl settings, or in running Lynis and fixing what it finds — all of which address attacks that actually reach you across the internet, daily.

Do it on a laptop. Laptops get left in hotel rooms and offices and taxis, the evil maid is a real threat model rather than a thought experiment, and combined with TPM unlock you get a machine that is genuinely difficult to tamper with.

Do it on any machine using TPM-sealed disk keys, because without it the sealing is theatre.

Skip it on a server in your house that nobody visits, unless you want to understand it — which is a perfectly good reason, and the one that got me here. Just do it on a Saturday morning with a live USB nearby, rather than at 23:00 on a Sunday because you read an article and got enthusiastic.

Advertisement
Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.