Skip to content

Authenticated_Boot

Robert T. edited this page Sep 4, 2025 · 6 revisions

Background

The Situation

When booting a debian system, the following components are executed:

  1. Boot loader = shim + systemd-boot
  2. Kernel
  3. 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:

  1. Shim is signed by a Microsoft key, trusted by the UEFI firmware
  2. Systemd-boot and the Kernel are signed by a Debian key, trusted by Shim
  3. 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.

The Problem

An attacked could modify the files in initrd and use it as an access point to your system.

The Solution

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:

  1. Shim is signed by a Microsoft key, trusted by the UEFI firmware
  2. Systemd-boot is signed by a Debian key, trusted by Shim
  3. 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.

Instructions

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:

sample screenshot

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.

Clone this wiki locally