Secure Boot & MOK
TL;DR. Secure Boot on kldload is opt-in and easy to enable. The recommended path is Bring Your Own Key — supply your existing MOK so the boot chain's trust anchor is part of your PKI, not one the installer generated. Auto-generated keys are supported for quick starts. Enable at install time by setting KLDLOAD_ENABLE_SECURE_BOOT=1 plus the BYOK paths below.
Design principle. kldload's job is to lay down the OS with ZFS on root and the value-added kernel modules (ZFS, WireGuard, NVIDIA), then hand the box over to you. It stays out of your security policy deliberately — boot-chain trust is your call, on your PKI, on your timeline. Shipping a self-generated MOK that users had to trust by default would force kldload's keys into your trust chain whether you wanted them or not.
Opting in: auto-generated MOK
Set the environment variable before kicking off the installer. The installer reads it and lays down the full shim → distro-grub → kernel chain plus MOK-signed DKMS modules with MokManager enrollment queued.
# From the web UI: tick the 🔒 Secure Boot checkbox in Platform Options
# From CLI: set before invoking kldload-install-target
export KLDLOAD_ENABLE_SECURE_BOOT=1
sudo kldload-install-target
What this triggers during install:
kldload-ca initgenerates an RSA-4096 root at/etc/kldload/ca/root/ca.{crt,key,der}— the unified TLS + MOK trust root (one cert covers browser TLS for webui/grafana/k9s AND kernel module signing)- The same key is copied to
/var/lib/dkms/mok.{key,pub,der}for DKMS to use as the sign_helper —zfs.ko(and any other DKMS modules: WireGuard, NVIDIA) gets MOK-signed at build time - Shim (the Microsoft-signed binary from the distro's
shim-x64package) installed at\EFI\BOOT\BOOTX64.EFIas the first-stage UEFI loader - Distro-signed
grubx64.efi(from/boot/efi/EFI/centos|rocky|fedora|redhat/grubx64.efi) copied to\EFI\BOOT\grubx64.efias shim's second stage — trusted by shim's embedded vendor cert, no MOK enrollment needed for boot - ZFSBootMenu installed at
\EFI\zbm\BOOTX64.EFI, MOK-signed when sbsign is available, as an optional boot-environment-selection alternative path mokutil --importof the kldload MOK DER queued for first boot
On first reboot MokManager's blue screen appears; approve enrollment of the kldload MOK. After enrollment, reboot with Secure Boot enabled in BIOS — shim → distro grub → vendor-signed kernel all chain via the firmware vendor-cert path; zfs.ko loads via the enrolled MOK; rpool imports; system boots clean.
Opting in: bring your own key (BYOK)
Most users who actually want Secure Boot already have their own PKI — an org-issued cert, an existing machine-owner key you've enrolled on a fleet, an HSM-backed signing key, whatever. kldload can use that instead of generating a per-install throwaway.
Set both of these paths (PEM format) before running the installer. Both files must be readable in the live environment, and both are required:
export KLDLOAD_ENABLE_SECURE_BOOT=1
export KLDLOAD_MOK_KEY_FILE=/path/to/your-mok.key # PEM private key
export KLDLOAD_MOK_CERT_FILE=/path/to/your-mok.pub # PEM X.509 cert
sudo kldload-install-target
BYOK takes precedence over CA-init: the installer copies both files to /var/lib/dkms/mok.{key,pub} on the target, regenerates the DER form for mokutil --import, and uses your key as the DKMS sign_helper for zfs.ko (and as the optional sbsign key for the alt-path ZBM at \EFI\zbm\BOOTX64.EFI). A fresh kldload-ca root is still issued for TLS leaf certs (browsers don't want an HSM-backed code-signing key terminating HTTPS), but DKMS signs with your key. The boot binaries themselves — shim and distro grub — are not re-signed by anyone; they ride the firmware's pre-installed vendor cert trust. If you've already enrolled the matching cert on the target firmware, no MokManager enrollment is needed — boot Just Works.
Production PKI pattern: generate one RSA-2048 or RSA-4096 keypair per fleet, store the private key on a restricted host (or HSM), enroll the cert on every box once, then point every kldload install at the same key files. You get a uniform signing authority across the fleet with zero per-install enrollment dances.
Opting in: pre-staged key
A third path, useful for automation hooks that want to write the key directly to the target before the installer runs its build phase: put the files at /var/lib/dkms/mok.{key,pub} inside the target mount (usually /target) before k_generate_mok_keys runs. kldload detects the pre-staged pair and skips generation.
mkdir -p /target/var/lib/dkms
cp my-fleet-mok.key /target/var/lib/dkms/mok.key
cp my-fleet-mok.pub /target/var/lib/dkms/mok.pub
chmod 0600 /target/var/lib/dkms/mok.key
chmod 0644 /target/var/lib/dkms/mok.pub
export KLDLOAD_ENABLE_SECURE_BOOT=1
# … proceed with the install …
Generating a BYOK key from scratch
If you don't already have a MOK and want to create a fleet-wide one, a single openssl invocation does it:
# 10-year self-signed RSA-2048 key usable by DKMS + sbsign + mokutil
openssl req -new -x509 -newkey rsa:2048 \
-keyout fleet-mok.key \
-out fleet-mok.pub \
-days 3650 -nodes \
-subj "/CN=acme-corp fleet MOK 2026/"
# DER form for one-time manual enrollment via mokutil
openssl x509 -in fleet-mok.pub -out fleet-mok.der -outform DER
# Enroll once per box (requires reboot into MokManager)
sudo mokutil --import fleet-mok.der
Store fleet-mok.key somewhere that only your CI / deployment system can reach — it's the long-lived secret. The .pub and .der are public and fine to ship with automation.
Post-install: turning SB on later
If you installed without SB and later decide you want it, you have two options:
- Reinstall with
KLDLOAD_ENABLE_SECURE_BOOT=1(or BYOK vars). Cleanest. Takes 10–15 minutes. - Use
kldload-secure-boot enableon the running install. Generates (or accepts BYOK), MOK-signszfs.ko, installs distroshim-x64to\EFI\BOOT\BOOTX64.EFI, copies distro-signedgrubx64.efinext to it, optionally MOK-signs ZBM at\EFI\zbm\BOOTX64.EFI, and queuesmokutil --import. Reboot, enroll via MokManager, reboot with SB enabled in BIOS.
Don't just flip Secure Boot on in BIOS without first enrolling your MOK. The boot chain itself (shim → distro grub → vendor-signed kernel) verifies fine via the firmware's vendor cert without any MOK enrollment — but the kernel will refuse to load zfs.ko under SB lockdown without the MOK that signed it enrolled, and on a ZFS-on-root system that means no rpool import and a drop into emergency shell. Either enroll first via MokManager, or leave SB off.
Verifying SB status on an installed system
# What does firmware think?
sudo mokutil --sb-state
# Is our MOK enrolled?
sudo mokutil --test-key /etc/kldload/ca/root/ca.der
# What's at the boot path? (shim + distro-signed grub)
sudo sbverify --list /boot/efi/EFI/BOOT/BOOTX64.EFI # shim, MS-signed
sudo sbverify --list /boot/efi/EFI/BOOT/grubx64.efi # distro vendor-signed
# Is the ZFS kernel module signed with our MOK?
sudo modinfo zfs | grep -E '^sig_|^signer|signature'
# Is the optional alt-path ZBM signed? (only matters if you boot via /EFI/zbm/)
sudo sbverify --cert /etc/kldload/ca/root/ca.crt \
/boot/efi/EFI/zbm/BOOTX64.EFI
# What SBAT level is shim enforcing?
sudo mokutil --list-sbat-revocations
Disabling SB cleanly after an SB install
Just turn Secure Boot off in BIOS. The kldload boot chain — shim → distro-signed grub → vendor-signed kernel → MOK-signed ZFS module — works transparently without SB enabled; nothing in kldload relies on SB being on. If you want to remove the MOK artifacts entirely, run kldload-secure-boot disable (clears the MOK from the kldload CA store and rebuilds initramfs without signed-module requirements).
Related reading
- Secure Boot & the Boot Chain — how UEFI → shim → distro-grub → kernel → MOK-signed modules actually works
- Upstream SBAT specification
- ZFSBootMenu docs
- Linux kernel module signing