The best option seems to be dracut with a little configuration. While clevis works, it is not as clean or easy to use as systemd-cryptenroll. Apart from adding tpm2-device=auto to /etc/crypttab, also add the following to dracut configuration (e.g. create /etc/dracut.conf.d/tpm2.conf):
hostonly="yes"
add_dracutmodules+=" tpm2-tss "
As others have noted tpm2-device=auto does not work with initramfs-tools that is used by default in Ubuntu, and dracut will likely replace initramfs-tools by Ubuntu 25.10 release in any case.
The full set of steps are below which have been tested on a fresh install of Ubuntu 24.04 where LVM+encryption was chosen during install.
- First install
dracut and tpm2-tools
sudo apt install dracut tpm2-tools --autoremove --purge
This will also remove initramfs-tools and some dependent packages (including brltty that depends on initramfs-tools for some reason).
- Enroll TPM2 with the LUKS partition
Create a script tpm2-luks-enroll.sh with the contents below and make it executable (chmod +x tpm2-luks-enroll.sh). This will be used for first enroll as well as for re-enrolling after any change in system configuration that causes TPM2 to reject the key fetch.
#!/bin/sh -e
LUKS_DEV=/dev/disk/by-uuid/506d04fe-ef0b-4554-8797-57f10dc9d0d8
sudo systemd-cryptenroll --wipe-slot=tpm2 $LUKS_DEV
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1+7+8+11+14:sha256" --tpm2-with-pin=true "$@" $LUKS_DEV
Use the required LUKS partition for LUKS_DEV above, or just change the UUID above to the one in your /etc/crypttab.
Here I am using some additional PCRs. The systemd-cryptenroll man page recommends 7, 11, 14 which cover most cases. Check their meaning and adjust accordingly but don't add too many which can be counter productive where TPM2 has to be re-enrolled after every little system change. For example, one can add 9 above to detect an evil maid attack tampering with initrd but that will mean re-enrolling in the next boot after every dracut run. On the other hand, remove 8 if someone running grub with changed kernel command-line is not a concern for you.
TPM2 pin is also enabled so that it is better protected in case of theft etc, but it (--tpm2-with-pin=true) can be removed to enable full auto unlock if such cases are not a concern. This pin can be shorter than what a LUKS password should be, since TPM2 will lock up pretty quick in case of repeated failures.
Run this script and it will enroll TPM2 with the LUKS partition asking for existing password and then the desired PIN (if enabled).
- Lastly update crypttab and add dracut configuration as noted at the start
The /etc/crypttab for above example after the change can look like this:
dm_crypt-0 UUID=506d04fe-ef0b-4554-8797-57f10dc9d0d8 none luks,tpm2-device=auto,discard,no-read-workqueue,no-write-workqueue
The last three options give better performance for SSDs -- check the security implication of discard before adding it, but other two should always be better for SSDs with no down sides.
Add /etc/dracut.conf.d/tpm2.conf as noted at the start, then run dracut -f which should generate the initrd that should include output about LUKS additions towards the end.
On reboot, it will ask for the PIN (if enabled) but will fail the first time due to the first dracut run, so you will need to enter password the first time. Removing 8 from PCRs should avoid it, so check if you need it. Run tpm2-luks-enroll.sh again and TPM2 should work next time onwards in either case.