-
Notifications
You must be signed in to change notification settings - Fork 11
Authenticated_Boot
When booting a debian system, the following components are executed:
- Boot loader = shim + systemd-boot
- Kernel
- Initrd
They are all stored unencrypted on the UEFI System Partition (ESP).
The Trusted Platform Module chip (TPM) can be used to unlock keys to decrypt the encrypted root partition.
The boot components can be validated by checking their signatures:
- Shim is signed by a Microsoft key, trusted by the UEFI firmware
- Systemd-boot and the Kernel are signed by a Debian key, trusted by Shim
- Initrd is generated locally on your PC and it is not signed
The above chain of trust is called Secure Boot and can be enabled in your PC firmware settings.
An attacked could modify the files in initrd and use it as an access point to your system.
Generate your own Machine Owner Key (MOK), enroll it with the UEFI firmware so that it is trusted. Combine the kernel and initrd to a single Unified Kernel Image (UKI) and sign the image by the MOK.
The chain of trust is now:
- Shim is signed by a Microsoft key, trusted by the UEFI firmware
- Systemd-boot is signed by a Debian key, trusted by Shim
- UKI = kernel + initrd is signed by MOK, trusted by the UEFI firmware
The above is chain of trust is called Fully Authenticated Boot and is available in Opinionated Debian Installer, an alternative Debian installer for laptops and workstation PCs.
We will enable the Fully Authenticated Boot on a debian system installed by the Opinionated Debian Installer before 2025-08-30, e.g. before SecureBoot was part of the installation.
All the commands below are executed as root: sudo su -
Some lines from the output are removed for readability.
Make sure all required packages are installed and grub removed:
apt install shim-signed systemd-boot-efi-amd64-signed systemd-ukify mokutil sbsigntool grub-efi-amd64-signed- grub-efi-amd64-unsigned- grub-efi-amd64-bin- grub-common- --allow-remove-essential
Verify exact path to the underlying partition for the root volume - in this text, we will assume /dev/vda2:
root@debian13-vm:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 20G 0 disk
├─vda1 253:1 0 1G 0 part /boot/efi
└─vda2 253:2 0 19G 0 part
└─root 254:0 0 19G 0 crypt /root/btrfs1
/home
/
Temporarily allow TPM unlock of the LUKS volume without checking any PCRs (we will switch back to a more secure setup later):
root@debian13-vm:~# systemd-cryptenroll --tpm2-pcrs= --tpm2-device=auto --tpm2-pcrlock= --wipe-slot=tpm2 /dev/vda2
🔐 Please enter current passphrase for disk /dev/vda2: •••••••••
New TPM2 token enrolled as key slot 3.
Wiped slot 2.
Set up the kernel installation tools to generate and sign UKIs:
root@debian13-vm:~# editor /etc/kernel/install.conf
layout=uki
uki_generator=ukify
initrd_generator=dracut
root@debian13-vm:~# editor /etc/kernel/uki.conf
[UKI]
Cmdline=@/etc/kernel/cmdline
SecureBootCertificate=/etc/kernel/mok.cert.pem
SecureBootPrivateKey=/etc/kernel/mok.priv.pem
Now, depending on whether you are using any DKMS (such as the proprietary NVIDIA driver) or not, we will generate the MOK or use the one generated by DKMS.
No DKMS:
root@debian13-vm:~# dkms
-bash: dkms: command not found
Generate the MOK and convert to DER form:
root@debian13-vm:~# ukify genkey --config /etc/kernel/uki.conf
Using config file: /etc/kernel/uki.conf
Writing SecureBoot private key to /etc/kernel/mok.priv.pem
Writing SecureBoot certificate to /etc/kernel/mok.cert.pem
root@debian13-vm:~# openssl x509 -in /etc/kernel/mok.cert.pem -out /etc/kernel/mok.cert.der -outform der
root@debian13-vm:~# openssl rsa -in /etc/kernel/mok.priv.pem -out /etc/kernel/mok.priv.der -outform der
writing RSA key
Symlink to where DKMS expects it:
root@debian13-vm:~# mkdir -p /var/lib/dkms
root@debian13-vm:~# ln -s /etc/kernel/mok.priv.pem /var/lib/dkms/mok.key
root@debian13-vm:~# ln -s /etc/kernel/mok.cert.der /var/lib/dkms/mok.pub
DKMS is installed
root@hp-laptop:~# dkms
Error! Unknown action specified: ""
Usage: /usr/sbin/dkms [action] [options]
[...]
Convert the keys generated by dkms to PEM form and symlink to the other directory:
root@hp-laptop:~# ln -s /var/lib/dkms/mok.key /etc/kernel/mok.priv.pem
root@hp-laptop:~# ln -s /var/lib/dkms/mok.pub /etc/kernel/mok.cert.der
root@hp-laptop:~# openssl x509 -in /etc/kernel/mok.cert.der -out /etc/kernel/mok.cert.pem -outform pem
root@hp-laptop:~# openssl rsa -in /etc/kernel/mok.priv.pem -out /etc/kernel/mok.priv.der -outform der
writing RSA key
Continue
Symlink to the "de-facto standard ubuntu" directory:
root@debian13-vm:~# mkdir -p /var/lib/shim-signed/mok
root@debian13-vm:~# ln -s /etc/kernel/mok.cert.der /var/lib/shim-signed/mok/MOK-Kernel.der
root@debian13-vm:~# ln -s /etc/kernel/mok.cert.pem /var/lib/shim-signed/mok/MOK-Kernel.pem
root@debian13-vm:~# ln -s /etc/kernel/mok.priv.der /var/lib/shim-signed/mok/MOK-Kernel.priv
Import the MOK:
root@debian13-vm:~# mokutil --import /etc/kernel/mok.cert.der
Failed to get Subject Key ID
input password:
input password again:
Set a short password that you will use in MokManager later.
Back up the contents of the ESP:
root@debian13-vm:~# mkdir efibackup
root@debian13-vm:~# cd efibackup/
root@debian13-vm:~/efibackup# mv /boot/efi/* .
Check old entries in EFI boot variables:
root@debian13-vm:~# efibootmgr
BootCurrent: 0002
BootOrder: 0002,0003,0001,0000
Boot0000* UiApp FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
Boot0001* UEFI Misc Device PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x0){auto_created_boot_option}
Boot0002* Linux Boot Manager HD(1,GPT,a40cc0d8-61a4-411a-8d4f-dd0da6107e9b,0x800,0x200000)/File(\EFI\systemd\systemd-bootx64.efi)
Boot0003* Debian HD(1,GPT,a40cc0d8-61a4-411a-8d4f-dd0da6107e9b,0x800,0x200000)/File(EFI\debian\shimx64.efi)5c004500460049005c00730079007300740065006d0064005c00730079007300740065006d0064002d0062006f006f0074007800360034002e0065006600690020005c003000
Now delete old entries - unsigned systemd-boot, old shim - in the example above, these are entries 0002 and 0003:
root@debian13-vm:~# efibootmgr -B -b 0002
[...]
root@debian13-vm:~# efibootmgr -B -b 0003
BootCurrent: 0002
Timeout: 0 seconds
BootOrder: 0001,0000
Boot0000* UiApp FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
Boot0001* UEFI Misc Device PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x0){auto_created_boot_option}
We will add the new boot entry by reconfiguring the systemd-boot package:
root@debian13-vm:~# dpkg-reconfigure systemd-boot
Created "/boot/efi/EFI".
Created "/boot/efi/EFI/systemd".
Created "/boot/efi/EFI/BOOT".
Created "/boot/efi/loader".
Created "/boot/efi/loader/keys".
Created "/boot/efi/loader/entries".
Created "/boot/efi/EFI/Linux".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed" to "/boot/efi/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed" to "/boot/efi/EFI/BOOT/BOOTX64.EFI".
Random seed file /boot/efi/loader/random-seed successfully written (32 bytes).
Created EFI boot entry "Linux Boot Manager".
Check that shim (under the name "Debian") is now the first entry in Boot Order:
root@debian13-vm:~# efibootmgr
[...]
BootOrder: 0003,0002,0001,0000
[...]
Boot0003* Debian HD(1,GPT,a40cc0d8-61a4-411a-8d4f-dd0da6107e9b,0x800,0x200000)/File(EFI\debian\shimx64.efi)5c004500460049005c00730079007300740065006d0064005c00730079007300740065006d0064002d0062006f006f0074007800360034002e0065006600690020005c003000
Optional: Workaround for bug #1095646 so that dracut doesn't run 2x every time:
ln -s /dev/null /etc/kernel/install.d/50-dracut.install
Now generate the UKI and install it to the ESP by reconfiguring the linux-image-VERSION package:
root@debian13-vm:~# dpkg-reconfigure linux-image-$(uname -r)
/etc/kernel/postinst.d/dracut:
dracut: Generating /boot/initrd.img-6.12.38+deb13-amd64
[...]
Updating kernel version 6.12.38+deb13-amd64 in systemd-boot...
Using config file: /etc/kernel/uki.conf
+ sbverify --list /boot/vmlinuz-6.12.38+deb13-amd64
+ sbsign --key /etc/kernel/mok.priv.pem --cert /etc/kernel/mok.cert.pem /tmp/ukiqrfipifn --output /tmp/kernel-install.staging.NPa1dM/uki.efi
Signing Unsigned original image
Wrote signed /tmp/kernel-install.staging.NPa1dM/uki.efi
Verify that all files are present in the ESP: shim64.efi, systemd-bootx64.efi, debian-VERSION.efi:
root@debian13-vm:~# find /boot/efi/
/boot/efi/
/boot/efi/EFI
/boot/efi/EFI/systemd
/boot/efi/EFI/systemd/systemd-bootx64.efi
/boot/efi/EFI/BOOT
/boot/efi/EFI/BOOT/BOOTX64.efi
/boot/efi/EFI/BOOT/fbx64.efi
/boot/efi/EFI/Linux
/boot/efi/EFI/Linux/debian-6.12.38+deb13-amd64.efi
/boot/efi/EFI/debian
/boot/efi/EFI/debian/shimx64.efi
/boot/efi/EFI/debian/fbx64.efi
/boot/efi/EFI/debian/mmx64.efi
/boot/efi/EFI/debian/BOOTX64.CSV
/boot/efi/loader
/boot/efi/loader/keys
/boot/efi/loader/entries
/boot/efi/loader/loader.conf
/boot/efi/loader/random-seed
/boot/efi/loader/entries.srel
We can reboot the PC now.
root@debian13-vm:~# reboot
It should boot to the MokManager and ask to enroll the MOK. Please see screenshots at the readme file SecureBoot section and don't be surprised:

After the MOK is enrolled and the OS boots fine with SecureBoot disabled, we can reboot to the EFI firmware and enable it. While you are at it, you can also enable Administrator password in the firmware setup.
root@debian13-vm:~# systemctl reboot --firmware-setup
The PC should now boot with SecureBoot enabled:
root@debian13-vm:~# bootctl
System:
Firmware: UEFI 2.70 (Debian distribution of EDK II 1.00)
Firmware Arch: x64
Secure Boot: enabled (user)
TPM2 Support: yes
Measured UKI: yes
Boot into FW: supported
[...]
Default Boot Loader Entry:
type: Boot Loader Specification Type #2 (.efi)
title: Debian GNU/Linux 13 (trixie)
id: debian-6.12.38+deb13-amd64.efi
source: /boot/efi//EFI/Linux/debian-6.12.38+deb13-amd64.efi (on the EFI System Partition)
sort-key: debian
version: 13 (trixie)
linux: /boot/efi//EFI/Linux/debian-6.12.38+deb13-amd64.efi
[...]
As the last step, we can now set a more restrictive PCR settings for TPM:
root@debian13-vm:~# systemd-cryptenroll --tpm2-pcrs=secure-boot-policy+shim-policy --tpm2-device=auto --tpm2-pcrlock= --wipe-slot=tpm2 /dev/vda2
🔐 Please enter current passphrase for disk /dev/vda2: •••••••••
New TPM2 token enrolled as key slot 2.
Wiped slot 3.