Filesystems, Kernel & Boot
This page explains how an installed InterGenOS system boots: the signed boot chain, the per-machine signing key, optional full-disk encryption, and how the kernel is rebuilt and signed on every install or upgrade. It is written for users and contributors who want to understand the model well enough to operate and recover it.
The boot path is the most privileged code on the machine, so InterGenOS verifies every executable that runs before userspace and gives you a machine you understand, can modify, and can trust.
For the installer that sets all of this up, see Forge, the installer. Related deep dives ship as Verified boot and Disk encryption.
The boot chain at a glance
InterGenOS builds a fully signed boot chain, though it does not require UEFI Secure Boot — the default fleet install runs with it off, so the signatures are present and verifiable but not firmware-enforced unless you enable Secure Boot. The chain of trust runs:
Firmware (UEFI)
│ trusts the Microsoft 3rd-party CA
▼
Microsoft-signed shim (v1.0 piggybacks Fedora's pre-signed shim)
│ trusts your machine's MOK
▼
InterGenOS GRUB (release-signed on the ISO/install media;
│ enforces signature MOK-signed for the GRUB written to disk)
│ verification on UKIs
▼
InterGenOS UKI (kernel + initramfs + cmdline, bundled and
│ kernel handoff signed as one Authenticode binary)
▼
InterGenOS userspace
A Unified Kernel Image (UKI) is a single signed file that bundles the kernel, the initramfs, and the kernel command-line. One signature covers all three; nothing inside can be swapped without breaking it.
The live ISO and install media ship UKIs signed by the InterGenOS release key, which lives only on an offline signing workstation and never touches your machine. Once you install to disk, every kernel you install or upgrade is rebuilt into a UKI on your machine and signed with your own key.
The Machine Owner Key (MOK)
A Machine Owner Key is a per-machine signing key generated on your own machine during install. The firmware trusts it because you enroll it once, via MokManager, at first boot. It exists so that:
- Your machine signs the kernels you install. When you install a kernel, InterGenOS rebuilds the UKI and signs it with your MOK. The release key never sees a kernel you build or install locally.
- You can trust your own out-of-tree drivers. Modules you build (for example, proprietary GPU drivers via DKMS) can be signed by your MOK and load on a Secure Boot system without disabling enforcement.
The MOK is yours and lives only on the installed system, under /var/lib/intergen/mok/. Reinstalling generates a fresh MOK; migrating to a new machine means generating a new one there.
During the bootloader stage, the Forge installer generates an RSA-2048 MOK keypair as mok.key (private), mok.crt (PEM X.509, used by sbsign for UKI signing), and mok.der (DER X.509, the form MokManager wants for enrollment). It also generates a random 12-character enrollment password, stages the MOK for enrollment, installs ukify and sbsigntool so the kernel package can build and sign UKIs later, installs an initial MOK-signed UKI, and configures a recovery boot entry that loads the bare vmlinuz.
Forge shows the enrollment password on the install-complete screen and writes it to /var/log/intergen-install.log. Write it down before you reboot. You need it once.
First-boot MOK enrollment
On the first boot, the firmware sees the pending enrollment request and runs MokManager (blue text on black) through three screens:
- Perform MOK management — press any key to start.
- Enroll MOK — review the certificate. Its subject reads
CN=InterGenOS Machine Owner Key. Confirm. - Enter password — type the enrollment password. It is single-use.
After enrollment, the system boots normally and the firmware trusts your MOK from then on. If you skip enrollment, the system still boots the release-signed UKI that shipped on the installer image, but the next kernel upgrade (which produces a MOK-signed UKI) will not be trusted, and you fall through to the recovery entry until you enroll.
Kernel install and upgrade
When you install or upgrade a kernel with pkm install linux-kernel-X.Y.Z, the kernel package’s post_install hook runs entirely on your machine, with no release-infrastructure key material:
- Reads the kernel, the standard initramfs (plus the FDE initramfs if the system is LUKS-encrypted), and the canonical command-line.
- Runs
ukify buildto bundle them into a single UKI. - Runs
sbsign --key /var/lib/intergen/mok/mok.key --cert /var/lib/intergen/mok/mok.crtto sign the UKI. (sbsignreads the PEM cert; the.derform is for MokManager enrollment only.) - Writes the signed UKI to
/boot/efi/EFI/Linux/intergenos-<kernel-version>.efi. - Updates the GRUB menu so the new kernel is the default entry.
- Retains a configurable number of old kernels and their UKIs as fallback entries (default: 2).
If signing fails (corrupt key file, full ESP), the hook falls back to writing the kernel and initramfs separately and having GRUB load them directly. GRUB is itself signed and enforces check_signatures=enforce, so the same verification semantics apply. You never end up with a half-installed kernel.
ESP sizing
Because every installed kernel becomes a UKI in /boot/efi, the ESP needs headroom for several kernel generations. A typical UKI is 80–150 MB depending on the initramfs payload. Forge creates a fixed 1 GiB ESP, leaving room for several kernel generations. If the ESP fills up, kernel install fails with a clear message; free space with pkm remove linux-kernel-<old-version>.
Full-disk encryption (LUKS2)
Full-disk encryption is opt-in, not default. Forge asks; you choose. We recommend it for any portable device.
- The format is LUKS2 with a passphrase, via
cryptsetup: AES-256 in XTS mode, withargon2id(memory-hard) key derivation. Forge forces argon2id parameters (1 GB memory cost, 4 iterations, 4 threads) calibrated to defeat GPU-accelerated brute force without risking out-of-memory on 4 GB systems. - The encrypted volume holds the entire root filesystem —
/home,/var,/etc,/root, and swap if placed inside the container. - Your passphrase is never written to disk outside the LUKS header slot, never logged, and never sent anywhere. There is no recovery key escrow and no master key. If you forget your passphrase, the data is gone by design.
- The ESP is not encrypted — the firmware must read it before any OS runs. Its integrity is protected by Secure Boot verification on the UKI, not by encryption.
A LUKS2 volume has a header (cipher metadata plus up to eight key slots), independent key slots (each wrapping the master key with one unlock method), and the encrypted payload. The master key never leaves the header; your passphrase unwraps a slot to yield it, and the passphrase lives only in volatile memory during unlock.
What Forge does for an encrypted install
When you tick Encrypt the root filesystem with LUKS2, Forge prompts for a passphrase with a confirmation field. Both frontends enforce a non-empty, matching value and surface a soft strength warning (8 characters is the floor; 12 with at least two character classes is the recommended baseline). The warning does not block — you confirm and continue. Forge then formats the partition with cryptsetup luksFormat, writes /etc/crypttab (mapper name cryptroot, referenced by UUID=), writes /etc/fstab with /dev/mapper/cryptroot as the root source, and the kernel hook bundles the FDE initramfs into the signed UKI. The passphrase is piped to cryptsetup via stdin (never on the command line), zeroized after use, and never written to disk outside the LUKS header.
Experimental unlock methods
Two unlock methods are wired as EXPERIMENTAL v1.0 sub-options. Both compose with the passphrase by adding an extra LUKS key slot; the passphrase slot is always retained as the unconditional fallback.
- TPM2-sealed unlock seals a fresh 32-byte key against the current measured-boot state, bound to a PCR0 + PCR7 policy (PCR0 tracks firmware code; PCR7 tracks Secure Boot policy/MOK state). The sealed blob triplet is written to the ESP under
/intergen/tpm2/. Normal boots then unlock automatically. It is EXPERIMENTAL because a firmware update (PCR0) or a Secure Boot/shim/MOK change (PCR7) invalidates the seal and falls through to the passphrase. The sub-checkbox is greyed out if no TPM is exposed (/dev/tpmrm0absent) or the TPM2 tools are missing from the ISO. - FIDO2-token unlock enrolls a credential on a FIDO2 token (YubiKey, Solo, Nitrokey, and similar). Enrollment runs
fido2-cred -Mthen afido2-assert -G --hmac-secretagainst a random nonce; the HMAC output becomes a LUKS slot. The relying-party ID isintergenos. Forge writes{cred_id, stored_nonce}to the ESP under/intergen/fido2/. A lost or swapped token invalidates the slot, so the passphrase stays in the header for fallback.
Neither the TPM2 sealed blob nor the FIDO2 metadata is secret on its own: without the specific TPM (and matching PCR state) or the physical token, those files are useless.
The boot-time unlock flow
After Secure Boot verifies the UKI and the kernel hands off to the FDE init, the unlock chain runs in order:
- TPM2 (if enrolled and
/dev/tpmrm0present):tpm2_load+tpm2_unsealagainst the PCR0+PCR7 policy, piped tocryptsetup. On any failure, fall through. - FIDO2 (if enrolled and tools available): wait up to 30 s for the token, run
fido2-assertagainst the stored nonce, pipe the HMAC tocryptsetup. On any failure, fall through. - Passphrase prompt (always the final fallback): an InterGenOS-branded prompt with three attempts, then a recovery shell.
If neither experimental method is enrolled, the chain skips straight to the passphrase prompt and the path is identical to a passphrase-only install. The FDE initramfs is tiny — a static cryptsetup, a static busybox, the dm_crypt/ext4 modules, and the storage drivers needed to see the disk (plus the static TPM2/FIDO2 tools and their modules when those methods are enrolled). It does no logging, no telemetry, and no network.
The FDE init emits journal-friendly prefixes you can correlate after boot:
| Prefix | Meaning |
|---|---|
[fde-init][EXPERIMENTAL TPM2] | TPM2 unlock attempt and outcome (skipping, attempting via sealed key, tpm2_load failed, unseal/cryptsetup failed, or success). |
[fde-init][EXPERIMENTAL FIDO2] | FIDO2 unlock attempt and outcome (skipping, attempting, no token within 30s, a pipeline diagnostic, or success). |
[fde-init] (no suffix) | Passphrase prompt path, recovery-shell drop, and root-mount errors. |
Search them with journalctl -b | grep fde-init.
How encryption and signed boot compose
The encrypted-root and signed-boot models are designed to compose. On a non-encrypted install the UKI’s bundled initramfs is minimal (typically only CPU microcode), because storage and filesystem drivers are built into the kernel. On an encrypted install, the UKI’s bundled initramfs is the FDE initramfs: the same code that prompts for your passphrase is inside the same signed envelope as the kernel.
The practical consequences:
- An attacker cannot substitute a fake unlock prompt to capture your passphrase, because the prompt code is inside the signed UKI. Tamper with it and Secure Boot refuses to load it.
- A kernel upgrade rebuilds the UKI with the new kernel and the same FDE initramfs, signed with your MOK. The unlock experience is identical across upgrades.
- A TPM2-sealed unlock does not skip Secure Boot verification; the TPM bits live inside the signed envelope too.
What encryption does and does not protect
Protected at rest: the entire root filesystem and anything written to disk while the system is running and unlocked.
Not protected: the ESP (read by firmware before any OS; integrity comes from Secure Boot, not encryption); the LUKS header itself (visible on disk — it reveals that the partition is LUKS and which cipher is used, but nothing about the payload); and a running, unlocked system (the master key is in kernel memory and the filesystem is readable to permitted processes). Encryption-at-rest does not replace process isolation, user permissions, or AppArmor confinement. If your threat model includes someone with physical access while the machine is running and unlocked, you want a screen lock or a powered-off machine, not just FDE.
Recovery
Most of the time none of this needs attention. When something goes wrong:
Add or remove a LUKS passphrase
LUKS2 supports up to eight key slots. From a running system, as root:
cryptsetup luksAddKey /dev/disk/by-uuid/<uuid>
cryptsetup luksRemoveKey /dev/disk/by-uuid/<uuid>
luksAddKey prompts for an existing passphrase, then the new one. luksRemoveKey prompts for the passphrase of the slot to remove; other slots are untouched.
Back up the LUKS header
If the header is corrupted (disk damage at the wrong offset, or an accidental dd), the payload is unrecoverable even with the correct passphrase. Back it up to offline media:
cryptsetup luksHeaderBackup /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
cryptsetup luksHeaderRestore /dev/disk/by-uuid/<uuid> \
--header-backup-file /path/to/external/header.bin
Anyone with the backup and your passphrase can decrypt the disk; store it accordingly.
I forgot my LUKS passphrase
The data is gone. There is no master key, no escrow, and no back door, because a recovery channel we could use is a channel an attacker could use. Boot a live ISO and reinstall. Back up early and often.
I need to regenerate the MOK
The MOK lives under /var/lib/intergen/mok/. On a default install Secure Boot is off and there is no enrollment password to lose. If you run with Secure Boot enabled and need a fresh MOK, reinstalling with Forge regenerates one; the next kernel install or upgrade rebuilds the UKIs with it, and the bare-vmlinuz fallback in GRUB keeps the system booting in the meantime. (There is no separate recovery wrapper command — UKI signing is handled by the kernel package’s post-install hook.)
Boot dropped me to the FDE recovery shell
Three failed passphrase attempts (or a missing /etc/crypttab or LUKS volume) drop you to a minimal busybox shell with cryptsetup. From there:
cryptsetup open /dev/disk/by-uuid/<uuid> cryptroot
mount /dev/mapper/cryptroot /newroot
exec switch_root /newroot /sbin/init
Use ls /dev/disk/by-uuid/ to inspect what enumerated, and reboot -f to reboot (the standard reboot is not available pre-systemd). The recovery shell has no network and no logs by design.
Secure Boot is refusing my new kernel
Usually the MOK was not enrolled (or was un-enrolled) but the post-install hook signed a UKI with it. Boot the recovery entry (bare vmlinuz via GRUB), then re-enroll or regenerate the MOK.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Boot prompt asks for the passphrase but every attempt fails | Wrong passphrase, or boot keyboard layout differs from inside the OS | The FDE initramfs uses US-QWERTY by default; type the QWERTY equivalents for layout-sensitive characters. |
| Boot drops to the FDE recovery shell: “no LUKS volume specified” | /etc/crypttab was not written, or encryption did not complete | cat /etc/crypttab; if empty, reinstall from a live ISO with encryption enabled. |
| Boot drops to the FDE recovery shell: “LUKS volume not found after 30s wait” | Disk did not enumerate in time (failing/USB/RAID-slow) | ls /dev/disk/by-uuid/; if the volume appears, retry cryptsetup open manually. |
| TPM2-sealed unlock falls through to passphrase | PCR0 or PCR7 changed (firmware update, Secure Boot reconfig, shim/MOK update) | Enter the passphrase; re-enroll TPM2 against the new PCR state. Check `journalctl -b |
| FIDO2 unlock does not detect the token | Token plugged in too late, or dead battery | Plug in before boot (30 s window); fall back to passphrase. Check `journalctl -b |
| New kernel installs but won’t boot, falls through to recovery | UKI signed with a MOK the firmware doesn’t trust | Re-enroll the MOK, then re-run the kernel post-install hook. |
| GRUB menu shows only the recovery entry | UKI signing has been failing silently | Inspect /var/log/intergen-kernel-postinstall.log; ESP-full and a missing MOK key file are the common causes. |
| The ESP filled on a kernel upgrade and the new UKI was skipped | UKI generation logged ESP-full and kept the previous default | pkm remove linux-kernel-<old-version> to free space, then re-run the post-install hook. |
ukify is missing on the installed system | Forge skipped the UKI tooling on an older or different-boot-path install | pkm install ukify sbsigntool and re-run the post-install hook for the current kernel. |
Running unsigned kernels
Don’t, on a real install. Every kernel that boots is signed. Build your kernel, sign it with your MOK using sbsign, and install it through the same pkm flow as everything else. To test bare unsigned kernels, use a VM with Secure Boot off.
Further reading
- Forge, the installer — the install flow that sets up the MOK, the boot chain, and optional encryption.
- Verified boot and Disk encryption — the install-side companions to this page.
- FAQ — quick answers to common boot and encryption questions.