How to enable Secure Boot using systemd-boot, sdbootutil and sbctl?

I am doing a command line installation of openSUSE Tumbleweed.

I am trying to enable Secure Boot using systemd-boot, sdbootutil and sbctl.
Unfortunately I cannot find or lack some information and I need some help please.

Currently, after preparing the disks and installing everything I need, I proceed with:

# Installing bootloader
zypper in -y systemd-boot
bootctl install

# Installing boot helpers
zypper in -y sdbootutil fde-tools tpm2-0-tss

# Deleting all .efi entries from NVRAM
efibootmgr --delete-bootnum --bootnum "<num here>"

# UEFI Secure Boot is in "Setup Mode" (and keys have been deleted)

# TPM auto-unlock for LUKS devices
sdbootutil enroll --method=tpm2

# Generating and enrolling keys for Secure Boot
zypper in -y sbctl
sbctl create-keys
sbctl enroll-keys -m

# Updating bootloader & boot entries (I am also using the Snapper integration)
sdbootutil install
sdbootutil set-timeout -- 8
sdbootutil add-all-kernels

At this point I was hoping for things (bootloader, initrd, kernel) to be signed but that is not the case.
… and running “sbctl verify” confirms this.

I see that sbctl comes with “/usr/lib/kernel/install.d/91-sbctl.install” which should automatically sign the kernel when there’s an update. So my guess is I just need to force the update of the kernel.

What hooks do I need to install/configure such that the bootloader and initrd are signed automatically on updates?

I’ve also looked into UKI but I am confused on the state.
I understand there’s uki-tool but it’s still experimental so maybe I could use systemd-ukify?

I am not sure on how to integrate the UKI in the entire pipeline such that it’s not broken on system updates.

What is the recommended path?

@dan2704 Hi, I just selected systemd-boot at install? If you run fwupdmgr security is “UEFI secure boot: Enabled”

Edit: I preconfigured the disk and allowed 4GB for /boot/efi (Just like Aeon).

@malcolmlewis I am not using the UI installer, I am doing a command line install using chroot.

Ok, if you use sdbootutil -v add-all-kernels to give verbose output, do you see the entries created etc;

ll /boot/efi/
total 12
drwxr-xr-x.  4 root root 4096 Jul  8 06:43 EFI
drwxr-xr-x.  3 root root 4096 Oct  5 11:31 loader
drwxr-xr-x. 11 root root 4096 Oct  2 22:21 opensuse-tumbleweed

sdbootutil does not use kernel-install.

1 Like

bootctl install
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" to "/boot/efi/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" 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".
sdbootutil enroll --method=tpm2
Recovery PIN: hbfercub-rdgrrghc-fdlluirv-ibftkgei-ktjdktjn-ldjghbct-ekdgbuhn-vijktlnt
You can also scan it with your mobile phone:
*{some QR code}*                                                                                
NVIndex policy created

🔐 Please enter current passphrase for disk /dev/nvme0n1p2: ••••                    
New TPM2 token enrolled as key slot 1.
sbctl create-keys
Created Owner UUID ea302f7e-0b1c-47e4-b0e0-b17398616825
Creating secure boot keys...✓ 
Secure boot keys created!

sbctl enroll-keys -m
Enrolling keys to EFI variables...
With vendor keys from microsoft...✓ 
Enrolled keys to the EFI variables!
sdbootutil install
NVIndex policy created

sdbootutil set-timeout -- 8
NVIndex policy created
sdbootutil -v add-all-kernels
Installing all kernels
Found kernel 6.17.0-1-default = 35ef7aeaef5806afdbf9174915fb9a039bfc2828
Installing kernel 6.17.0-1-default
Found existing initrd /opensuse-tumbleweed/6.17.0-1-default/initrd-7e824ec74e0f9da29b62fb37c681d54352291fe6
Required free space in ESP: 15836 KB
Reusing /boot/efi/opensuse-tumbleweed/6.17.0-1-default/linux-35ef7aeaef5806afdbf9174915fb9a039bfc2828
 /boot/efi/loader/entries/opensuse-tumbleweed-6.17.0-1-default-1.conf unchanged
Loading config file /etc/sysconfig/fde-tools
Generating TPM2 predictions with systemd-pcrlock
Generating TPM2 predictions with systemd-pcrlock (systemd-boot)
NVIndex policy created
sbctl status
|Installed:|✓ sbctl is installed|
|---|---|
|Owner GUID:|ea302f7e-0b1c-47e4-b0e0-b17398616825|
|Setup Mode:|✓ Disabled|
|Secure Boot:|✗ Disabled|
|Vendor Keys:|microsoft|
sbctl verify
Verifying file database and EFI images in /boot/efi...
✗ /boot/efi/EFI/BOOT/BOOTX64.EFI is not signed
failed to verify file /boot/efi/EFI/systemd/boot.csv: /boot/efi/EFI/systemd/boot.csv: invalid pe header
failed to verify file /boot/efi/EFI/systemd/installed_by_sdbootutil: /boot/efi/EFI/systemd/installed_by_sdbootutil: invalid pe header
failed to verify file /boot/efi/EFI/systemd/measure-pcr-prediction: /boot/efi/EFI/systemd/measure-pcr-prediction: invalid pe header
failed to verify file /boot/efi/EFI/systemd/measure-pcr-prediction.sha256: /boot/efi/EFI/systemd/measure-pcr-prediction.sha256: invalid pe header
failed to verify file /boot/efi/EFI/systemd/pcrlock.json: /boot/efi/EFI/systemd/pcrlock.json: invalid pe header
✗ /boot/efi/EFI/systemd/systemd-bootx64.efi is not signed
failed to verify file /boot/efi/loader/entries/opensuse-tumbleweed-6.17.0-1-default-1.conf: /boot/efi/loader/entries/opensuse-tumbleweed-6.17.0-1-default-1.conf: invalid pe header
failed to verify file /boot/efi/loader/entries.srel: /boot/efi/loader/entries.srel: invalid pe header
failed to verify file /boot/efi/loader/loader.conf: /boot/efi/loader/loader.conf: invalid pe header
failed to verify file /boot/efi/loader/random-seed: /boot/efi/loader/random-seed: invalid pe header
failed to verify file /boot/efi/opensuse-tumbleweed/6.17.0-1-default/initrd-7e824ec74e0f9da29b62fb37c681d54352291fe6: /boot/efi/opensuse-tumbleweed/6.17.0-1-default/initrd-7e824ec74e0f9da29b62fb37c681d54352291fe6: invalid pe header
✗ /boot/efi/opensuse-tumbleweed/6.17.0-1-default/linux-35ef7aeaef5806afdbf9174915fb9a039bfc2828 is not signed
bootctl status
System:
      Firmware: n/a (n/a)
 Firmware Arch: x64
   Secure Boot: disabled (unknown)
  TPM2 Support: yes
  Measured UKI: no
  Boot into FW: supported

Random Seed:
 System Token: set
       Exists: yes

Available Boot Loaders on ESP:
          ESP: /boot/efi (/dev/disk/by-partuuid/6926d525-d2c6-4f4a-80fe-14433e698cab)
         File: ├─/EFI/systemd/systemd-bootx64.efi (systemd-boot 257.9+suse.23.gc139debf2c)
               └─/EFI/BOOT/BOOTX64.EFI (systemd-boot 257.9+suse.23.gc139debf2c)

Boot Loaders Listed in EFI Variables:
        Title: openSUSE Boot Manager (systemd-boot)
           ID: 0x0001
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/ba2c8303-b48b-4877-ad19-450382689682
         File: └─/EFI/systemd/systemd-bootx64.efi

        Title: Linux Boot Manager
           ID: 0x0004
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/6926d525-d2c6-4f4a-80fe-14433e698cab
         File: └─/EFI/systemd/systemd-bootx64.efi

        Title: UEFI Samsung Flash Drive FIT 0375022010004300
           ID: 0x0003
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/27b06976-221c-4bf5-96a0-57e188823e80
         File: └─/EFI/Boot/BootX64.efi

        Title: Linux Boot Manager
           ID: 0x0000
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/ba2c8303-b48b-4877-ad19-450382689682
         File: └─/EFI/systemd/systemd-bootx64.efi

        Title: UEFI KXG70ZNV512G NVMe KIOXIA 512GB 922A10A3KTF5 1
           ID: 0x0002
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/ba2c8303-b48b-4877-ad19-450382689682
         File: └─/EFI/Boot/BootX64.efi

Boot Loader Entries:
        $BOOT: /boot/efi (/dev/disk/by-partuuid/6926d525-d2c6-4f4a-80fe-14433e698cab)
        token: opensuse-tumbleweed

Default Boot Loader Entry:
         type: Boot Loader Specification Type #1 (.conf)
        title: openSUSE Tumbleweed 20251003
           id: opensuse-tumbleweed-6.17.0-1-default-1.conf
       source: /boot/efi//loader/entries/opensuse-tumbleweed-6.17.0-1-default-1.conf (on the EFI System Partition)
     sort-key: opensuse-tumbleweed
      version: 1@6.17.0-1-default
        linux: /boot/efi//opensuse-tumbleweed/6.17.0-1-default/linux-35ef7aeaef5806afdbf9174915fb9a039bfc2828
       initrd: /boot/efi//opensuse-tumbleweed/6.17.0-1-default/initrd-7e824ec74e0f9da29b62fb37c681d54352291fe6
      options: cryptdevice=UUID=7b886caa-3c48-412f-be01-bb8d85f1388e:root root=/dev/mapper/root quiet systemd.show_status=yes  rootflags=subvol=@/.snapshots/1/snapshot

Right, I was talking about sbctl:

rpm -ql sbctl

/usr/lib/kernel
/usr/lib/kernel/install.d
/usr/lib/kernel/install.d/91-sbctl.install
/usr/sbin/sbctl
/usr/share/bash-completion/completions/sbctl
/usr/share/doc/packages/sbctl
/usr/share/doc/packages/sbctl/README.md
/usr/share/fish
/usr/share/fish/vendor_completions.d
/usr/share/fish/vendor_completions.d/sbctl.fish
/usr/share/licenses/sbctl
/usr/share/licenses/sbctl/LICENSE
/usr/share/man/man5/sbctl.conf.5.gz
/usr/share/man/man8/sbctl.8.gz
/usr/share/zsh
/usr/share/zsh/site-functions
/usr/share/zsh/site-functions/_sbctl

That’s why I was saying maybe I should force the kernel update to trigger that kernel sign. I was mentioning this in the context of seamless sign on system updates.

And I tell you what program makes use of /usr/lib/kernel/install.d.

You may try removing sdbootutil in which case update-bootloader should fall back to kernel-install. But then you will lose snapshot support.

Yes, that’s the thing, I don’t want to lose snapshot support (with all the bells and whistles).

I configured dracut to build a UKI (that part works). I assumed (very badly I guess) that would go through kernel-install so the sbctl hook (91-sbctl.install) would auto-sign it.

Regardless, I found out that the UKI is not discovered by sdbootutil, it still generates entries for separate kernel+initrd files.

I am a bit confused on how to achieve my goal and not sure if it’s supported without some custom hooks.

No

There was some attempt to add support for snapshots to the kernel-install, but it went nowhere.

kernel-install: snapshot support by lnussel · Pull Request #25801 · systemd/systemd · GitHub