booster

repository·master·Indexed 20 days ago

https://github.com/anatol/booster

A fast, secure, and modern initramfs generator for Linux designed for compact, host-specific boot images. It features advanced support for encrypted-boot workflows, including TPM2, FIDO2, and remote SSH unlocking, as well as support for LVM, mdraid, and ZFS.

Tokens
13K
Snippets
34
Records
51
Agent score
71%

What's inside booster

  1. What is Booster?

    master
    Booster is a tool designed to generate initramfs images for the early stages of the Linux boot process. It is optimized for speed and full disk encryption use cases, offering features like fast build/boot times, out-of-the-box LUKS support, and automatic host configuration discovery to create minimalistic, host-specific images.
  2. Configure LUKS unlocking via kernel parameters

    master

    When booting an encrypted system, you can pass specific parameters to the kernel to instruct Booster how to unlock LUKS devices.

    Key LUKS Parameters:

    • rd.luks.uuid=$UUID: The UUID of the LUKS partition. Booster will attempt to unlock this.
    • rd.luks.name=$UUID=$NAME: Specifies both the UUID and the name used for the resulting mapper device (e.g., rd.luks.name=1234-abcd=cryptroot).
    • rd.luks.key=$UUID=$PATH: Absolute path to a keyfile inside the initramfs used for unlocking. If missing or failing, it falls back to a password prompt.
    • rd.luks.header=$UUID=$PATH: Used for detached LUKS headers. $PATH can be:
      • An absolute path to a file bundled in the initramfs via extra_files.
      • A raw block device (e.g., /dev/sdb).
      • A file on a separate device using the format $path:$deviceref (e.g., /etc/luks/hdr.bin:UUID=...).
    • rd.luks.data=$UUID=$deviceref: Pins the data device for a LUKS volume with a detached header. Required if using detached headers to identify the underlying partition.
    • rd.luks.options=opt1,opt2: Comma-separated LUKS flags. Supported: discard, same-cpu-crypt, submit-from-crypt-cpus, no-read-workqueue, no-write-workqueue. Also supports token-timeout=<duration> (e.g., 30s) and tpm2-measure-pcr=yes|no.
    # Example kernel command line for LUKS with a named mapper
    root=/dev/mapper/cryptroot rd.luks.name=550e8400-e29b-41d4-a716-446655440000=cryptroot
  3. Use Device References in Kernel Parameters

    master

    When specifying devices or partitions in kernel parameters (e.g., for root= or rd.luks.uuid=), you can use several reference formats to ensure reliable identification:

    • Path: /dev/XXX (e.g., /dev/sda1, /dev/nvme0n1, or /dev/mapper/root).
    • UUID: UUID=$UUID or /dev/disk/by-uuid/$UUID.
    • Label: LABEL=$LABEL or /dev/disk/by-label/$LABEL.
    • GPT Partition UUID: PARTUUID=$UUID or /dev/disk/by-partuuid/$UUID.
    • GPT Offset: PARTUUID=$UUID/PARTNROFF=$OFFSET (references an offset from a GPT partition).
    • GPT Partition Label: PARTLABEL=$LABEL or /dev/disk/by-partlabel/$LABEL.
    • Hardware Path: HWPATH=$PATH or /dev/disk/by-path/$PATH (e.g., pci-0000:02:00.0-nvme-1-part2).
    • WWID: WWID=$ID (e.g., nvme-KXG6AZNV256G_TOSHIBA_40SA13GZF6B1-part3).
  4. Manage LUKS token unlocking behavior

    master

    Booster provides advanced controls for how hardware tokens (TPM2, FIDO2, Clevis) and PINs are handled during the LUKS unlock process.

    Token Serialization

    By default, tokens race concurrently. To prevent a non-interactive token (like TPM2) from being preempted by a PIN prompt, use serialize_tokens.

    • serialize_tokens.enabled: Set to true to try tokens one at a time in ascending ID order.
    • serialize_tokens.clevis_timeout, serialize_tokens.tpm2_timeout, serialize_tokens.fido2_timeout: Set per-token bounds (Go duration) to prevent a stuck token from hanging the boot.

    Prompt Timing and Feedback

    • token_timeout: The maximum time booster waits for tokens before showing the keyboard passphrase prompt.
    • pin_delay: Used in concurrent mode. It holds the first interactive PIN prompt (TPM2-PIN, FIDO2-PIN) for the specified duration to allow parallel non-interactive tokens to finish unlocking first. This prevents the prompt from being drawn if a token wins during the delay.
    • password_echo: Controls how characters appear during prompts. Supported modes: asterisks, silent, plaintext. The first entry is the starting mode; users can cycle through them with Tab.
  5. Understand LUKS Unlock Concurrency and Behavior

    master

    Booster executes LUKS unlock paths concurrently to speed up boot.

    Key Behaviors:

    • PIN-token serialization: Tokens requiring a PIN (e.g., TPM2-PIN, FIDO2-PIN) are prompted serially in ascending LUKS2 token-ID order to avoid racing multiple PIN prompts. To check order, use cryptsetup luksDump <device>.
    • FIDO2 Pre-flight: For multiple FIDO2 tokens, Booster performs a CTAP2 assertion (up=false) to identify the correct device before prompting for a PIN, skipping non-matching devices silently.
    • Cancel-on-win: If any parallel unlock path succeeds (e.g., a touchless token or a successful keyfile read), all active prompts (keyboard, FIDO2-PIN, TPM2-PIN) are automatically dismissed on both the kernel console and Plymouth.
    • PIN attempt caps: Each PIN-bearing token allows up to 3 attempts. Pressing Enter with an empty input skips the current token to try the next one.
  6. How TPM2 auto-unlock and supplantation defense works

    master

    Booster can unseal a LUKS volume key from a systemd-tpm2 token to enable pinless auto-unlock. To prevent filesystem supplantation (where an attacker uses a substituted kernel or initrd to trick the TPM), Booster binds the key to a specific chain of TPM PCRs:

    1. PCR 7 (Secure Boot): Anchors the boot to the firmware's Secure Boot policy. The key is withheld if Secure Boot is disabled or keys change.
    2. PCR 11 (UKI Measurement): Acts as the primary barrier against substituted kernels/initrds. Under a Unified Kernel Image (UKI), systemd-stub measures the kernel, initrd, and command line into PCR 11. Booster uses a signed (authorized) policy (--tpm2-public-key=) rather than a literal PCR value. This allows the key to remain valid across kernel/initrd updates because ukify/systemd-measure re-signs the new PCR 11 value.
      • Note: In a non-UKI boot, you must supply the signature via the kernel parameter tpm2-signature=<path>. Booster reads the signature from /.extra/tpm2-pcr-signature.json (unpacked by systemd-stub).
    3. PCR 15 (Single-use Latch): Ensures the unseal is single-use per boot. The key is sealed to the virgin all-zero value of PCR 15. Immediately after unsealing, Booster extends PCR 15 with an HMAC of the volume key. This "latches" the PCR, making it non-zero and preventing a second unseal in the same boot session.

    Multi-device root (e.g., Btrfs RAID): If multiple root members must unlock in the initramfs, bind them to signed PCR 11 + PCR 7 without the PCR 15 latch. Because the latch is single-volume, the first member to unseal will dirty PCR 15, causing subsequent members to fail if they are also bound to zero.

    Recovery: If PCRs mismatch (due to hardware changes or tampering), the system falls back to a passphrase keyslot. For headless systems, use Booster's Remote Unlock (SSH) to submit the passphrase.

  7. Set up Remote SSH unlocking for LUKS

    master

    Booster can unlock LUKS volumes via SSH during early boot once networking is active. This replaces the need for dropbear-initramfs by using native Go SSH implementation.

    Setup Steps

    1. Generate a host key (to be embedded in the image):

      ssh-keygen -t ed25519 -f /etc/booster/ssh_host_ed25519_key -N ''
    2. Create an authorized_keys file containing your public keys:

      ssh-ed25519 AAAAC3Nz...user1@laptop
      ssh-ed25519 AAAAC3Nz...user2@phone
    3. Configure /etc/booster.yaml to wire these files and enable networking:

      network:
        dhcp: on
        ssh_host_key: /etc/booster/ssh_host_ed25519_key
        ssh_authorized_keys: /etc/booster/authorized_keys
        ssh_listen: :22

    Usage

    Connect from a client as root to provide the passphrase:

    $ ssh -p 22 root@<host>

    Security Considerations

    • Exposure: The host private key and authorized_keys are embedded in the initramfs. If /boot is accessible, these are considered compromised.
    • Brute Force: Sessions are disconnected after 10 failed attempts. However, attackers can reconnect to try again.
    • Network Binding: ssh_listen: :22 listens on all interfaces. For better security, pin it to a specific address (e.g., 10.0.0.5:22).
    • Restrictions: The SSH session is a restricted passphrase prompt only; no shell, command execution, or port forwarding is allowed.
    network:
      dhcp: on
      ssh_host_key: /etc/booster/ssh_host_ed25519_key
      ssh_authorized_keys: /etc/booster/authorized_keys
      ssh_listen: :22
  8. Regenerate booster images after configuration changes

    master

    After modifying /etc/booster.yaml or other configuration files, you must regenerate the initramfs images located in /boot. Use the provided convenience script to perform this task as if it were done by your package manager:

    /usr/lib/booster/regenerate_images
  9. Configure Headless TPM2 auto-unlock with SSH recovery

    master

    This setup allows a headless machine to unlock via TPM2 automatically, with a fallback to SSH-based passphrase entry if the TPM unseals fail (e.g., due to hardware/firmware changes).

    1. Prepare RSA Keys

    Generate an RSA key pair to sign the PCR policy. Booster and ukify require RSA.

    openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -out /etc/kernel/pcr-private.pem
    openssl rsa -pubout -in /etc/kernel/pcr-private.pem -out /etc/kernel/pcr-public.pem

    2. Configure UKI and PCR Signing

    Extend /etc/kernel/uki.conf to include Secure Boot keys and a [PCRSignature:initrd] section to sign PCR 11.

    [UKI]
    Microcode=/boot/amd-ucode.img
    SecureBootPrivateKey=/etc/kernel/secureboot/db.key
    SecureBootCertificate=/etc/kernel/secureboot/db.crt
    PCRBanks=sha256
    
    [PCRSignature:initrd]
    PCRPrivateKey=/etc/kernel/pcr-private.pem
    PCRPublicKey=/etc/kernel/pcr-public.pem

    3. Enroll TPM Pinless

    Use systemd-cryptenroll to bind the LUKS slot to PCR 7 (Secure Boot state), signed PCR 11, and a zeroed PCR 15 latch.

    systemd-cryptenroll --tpm2-device=auto \
          --tpm2-pcrs=7+15:sha256=0000000000000000000000000000000000000000000000000000000000000000 \
          --tpm2-public-key=/etc/kernel/pcr-public.pem --tpm2-public-key-pcrs=11 /dev/sda2

    4. Enable SSH Recovery

    To allow remote passphrase entry if the TPM fails, configure the network and SSH keys in /etc/booster.yaml.

    network:
      dhcp: on
      ssh_host_key: /etc/booster/ssh_host_ed25519_key
      ssh_authorized_keys: /etc/booster/authorized_keys
  10. Enable GPT root autodiscovery

    master

    You can boot without a root= parameter on the kernel command line by using GPT autodiscovery.

    1. Tag the partition: Use sgdisk to set the specific per-architecture GUID on your root partition (e.g., 4f68bce3-e8cd-4db1-96e7-fbcaf984b709 for x86-64).
    2. Configure /etc/crypttab: If using LUKS, name the mapper in /etc/crypttab and include the x-initrd.attach option. If no mapper name is provided, Booster synthesizes /dev/mapper/root.
    3. Bootloader: The bootloader entry only needs mount-style flags (e.g., rw).
    # Tag the root partition (x86-64 example)
    sgdisk --typecode=2:4f68bce3-e8cd-4db1-96e7-fbcaf984b709 /dev/sda
    # /etc/crypttab for LUKS
    cryptroot  UUID=e122d09e-87a9-4b35-83f7-2592ef40cefa  none  x-initrd.attach
  11. Regenerate images after configuration changes

    master

    If you modify /etc/booster.yaml or update your kernel, you must regenerate the images. On many distributions, a helper script is provided:

    /usr/lib/booster/regenerate_images

    If your distribution provides systemd-ukify, you can also generate a Unified Kernel Image (UKI):

    /usr/lib/booster/regenerate_uki build /boot/EFI/Linux
    # Regenerate packaged images
    /usr/lib/booster/regenerate_images
    
    # Generate a Unified Kernel Image (UKI)
    /usr/lib/booster/regenerate_uki build /boot/EFI/Linux
  12. Unlock LUKS with FIDO2 hardware tokens

    master

    Booster supports hardware-token unlocking via FIDO2.

    1. Enroll the device: Use systemd-cryptenroll to enroll a FIDO2 device into a LUKS slot.
    2. Configure /etc/crypttab: Add an entry for your root partition. Booster automatically bundles fido2plugin.so when it detects the fido2-device= option.
      • token-timeout=: Sets the wait time for a FIDO2 touch before falling back to a passphrase prompt (e.g., 60s). Use 0 to wait indefinitely.
      • x-initrd.attach: Required to ensure the mapper is available in the initramfs.
    3. Update Bootloader: Point the root= parameter to the mapper name defined in the first column of /etc/crypttab (e.g., /dev/mapper/cryptroot).
    # 1. Enroll FIDO2 device
    systemd-cryptenroll --fido2-device=auto /dev/sda2
    # 2. /etc/crypttab entry
    cryptroot  UUID=e122d09e-87a9-4b35-83f7-2592ef40cefa  none  fido2-device=auto,token-timeout=60s,x-initrd.attach
    # 3. Bootloader options
    options root=/dev/mapper/cryptroot rw