· via dev.to (home feed)
Guide: systemd-cryptenroll for unattended LUKS2 unlocks with TPM2, FIDO2 and recovery keys
A dev.to guide shows how to enroll TPM2, FIDO2 and recovery keys into LUKS2 volumes so encrypted Linux servers unlock at boot without a typed passphrase.
A practical guide published on dev.to walks Linux operators through systemd-cryptenroll, the systemd utility that binds LUKS2 encrypted volumes to hardware unlock factors so machines can survive reboots and power failures without anyone typing a passphrase.
The author's premise is blunt: encryption that pauses at the console on every reboot leaves the job half finished. That trade is tolerable on a laptop, but on a homelab node, a fleet box, or anything expected to restart on its own after power loss, an unlock prompt waiting for a human turns into downtime. According to the guide, commands and semantics come from the systemd-cryptenroll(1), crypttab(5) and [email protected](8) manual pages, covering features through systemd 262.
What the tool does, and does not
systemd-cryptenroll enrolls five unlock factor types into a LUKS2 volume: TPM2 security devices, FIDO2 tokens using the hmac-secret extension, PKCS#11 smartcards (RSA or EC key pairs), ordinary passphrases, and machine-generated recovery keys. The metadata lands in the LUKS2 JSON token area and is consumed at boot by systemd-cryptsetup together with /etc/crypttab.
The guide is equally clear about what the tool is not. Clevis with Tang covers network-bound disk encryption, where volumes unlock when a Tang server is reachable. systemd-creds holds per-service secrets at activation, not disk unlock keys. sbctl and Secure Boot sign the boot chain and complement rather than replace LUKS unlocking. cryptsetup luksAddKey adds passphrase or keyfile slots only, with none of the TPM2 or FIDO2 token JSON. LUKS1 is unsupported outright — those volumes need cryptsetup convert --type luks2 first, after backups.
Notably, enrollment does not place the LUKS master key in the clear on the token. With TPM2, a random unlock key is sealed to the chip, and unsealing succeeds only when the TPM can reproduce its policy — PCRs, an optional PIN, signed policies and so on. With FIDO2, the token computes an HMAC over a random salt using a secret that stays inside the authenticator, with presence, client PIN and user verification configurable.
Recovery key first
The first lab is deliberately unglamorous: before any TPM2 or FIDO2 experiment, enroll a recovery key with systemd-cryptenroll --recovery-key, then store it offline — a password manager, a printed QR code, a sealed envelope — never next to the machine. The command prompts for an existing passphrase to authorize the new slot, and the printed key is worth guarding as closely as a root password, with more entropy behind it. The guide also insists on a second session or a live USB before wiping passphrase slots, because wiping a slot without a recovery route destroys access to the volume key.
Wiring TPM2 unlock into boot
For a host you physically trust, the simplest route seals a key to the TPM with no PCR policy, so the volume unlocks whenever that TPM is present. The accepted threat model: a stolen disk alone will not unlock, but a stolen disk together with the machine's TPM might. Enrollment is one command — systemd-cryptenroll --tpm2-device=auto — followed by a crypttab entry such as rootfs UUID=YOUR-LUKS-UUID none tpm2-device=auto,x-initrd.attach and an initramfs rebuild (update-initramfs -u, dracut -f or mkinitcpio -P depending on distribution).
The crypttab options carry weight. tpm2-device=auto discovers the chip; x-initrd.attach is recommended for root so that devices detach in the right order at shutdown; headless=true blocks any fallback to an interactive password and belongs only in play once the TPM path is proven; token-timeout=, 30 seconds by default, waits for hardware tokens before falling back. Non-root volumes can be tested live via systemctl start [email protected], while root should get a controlled reboot with the recovery key and passphrase slots intact until one clean boot.
PCR binding and update-friendly policies
The second half binds the sealed key to measured boot state so unsealing fails if that state drifts. The man-page guidance quoted in the guide: bind volumes to a combination of PCR 7 (Secure Boot policy), PCR 11 (kernel-boot and UKI measurements) and PCR 14 (shim/MOK) when shim is in the path, for instance --tpm2-pcrs=7+11. The guide prefers certificate-backed measurements to raw firmware-code PCRs like 0 and 2, since those shift with each firmware update. The operational cost is explicit — kernel, UKI or Secure Boot changes that alter the bound PCRs break unlocking until re-enrollment or a recovery fallback, which the author frames as the purpose of the feature and the reason a recovery key is mandatory.
To soften that cost, signed PCR policies bind to a public key that signs allowed PCR states (--tpm2-public-key=, --tpm2-public-key-pcrs=, optionally --tpm2-signature=), so vendors or an in-house UKI pipeline can ship fresh signatures when kernels change.
Why it matters
An encrypted Linux server that stops for a passphrase cannot recover from power loss or a remote reboot without a human, which turns a security feature into a reliability liability for fleets. systemd-cryptenroll removes that person from the boot path while keeping protection against disk-only theft, and PCR binding extends the guarantee to boot-chain tamper detection. The guide's ordering — recovery key first, keep the passphrase until the hardware path is proven, then test with a controlled reboot — makes it a runbook rather than a command list, and its careful separation from Clevis/Tang, systemd-creds and Secure Boot tooling helps operators pick the right mechanism for each job.
- #linux
- #systemd
- #disk-encryption
- #luks2
- #tpm2