feat: add TPM2 auto-unlock support to encrypted storage ingredient
Add cryptsetup, tpm2-tools and tpm2-tss to every encrypted dish so the initrd can be rebuilt with TPM2 support. A guarded %pre stashes a preseeded LUKS passphrase from the kickstart, and a guarded %post enrolls PCR 7-bound auto-unlock via systemd-cryptenroll, switches crypttab to tpm2-device=auto and regenerates the initrd. Without a preseeded passphrase or a TPM device the enrollment is skipped and the system keeps the regular passphrase prompt.
This commit is contained in:
@@ -6,3 +6,70 @@ clearpart --all --initlabel # Erase all partitions and Initializes the disk labe
|
||||
part /boot/efi --fstype="efi" --size=512 --fsoptions="umask=0077,shortname=winnt" --label=efi # Creates a 512 MiB EFI system partition
|
||||
part /boot --fstype="ext4" --size=2048 --label=boot # Creates a 2048 MiB ext4 boot partition
|
||||
part / --fstype="ext4" --grow --label=root --mkfsoptions="-O encrypt,fast_commit" --encrypted --passphrase= # Create a single encrypted root partition with the remaining space.
|
||||
|
||||
# Tools for LUKS management and TPM2-based auto-unlock
|
||||
%packages --exclude-weakdeps
|
||||
|
||||
cryptsetup # Userspace tool for dm-crypt, required to open and manage the LUKS root device
|
||||
tpm2-tools # TPM2 tools, provides the dracut tpm2-tss module needed to rebuild the initrd for TPM2 auto-unlock
|
||||
tpm2-tss # TPM2 TSS libraries, runtime dependency of tpm2-tools and systemd-cryptenroll
|
||||
|
||||
%end # End of the packages section
|
||||
|
||||
# Stash a preseeded LUKS passphrase so the %post below can enroll TPM2-based
|
||||
# auto-unlock. Only acts when `--passphrase=` was preseeded on the encrypted
|
||||
# `part /` line; with the interactive default (empty passphrase) nothing is
|
||||
# stashed and the %post enrollment is skipped cleanly.
|
||||
%pre --logfile=/tmp/luks-tpm-pre.log
|
||||
|
||||
KS_FILE=""
|
||||
for candidate in /run/install/ks.cfg /tmp/ks.cfg; do
|
||||
if [ -f "$candidate" ]; then
|
||||
KS_FILE="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$KS_FILE" ]; then
|
||||
LINE=$(grep -E '^[[:space:]]*part[[:space:]]+/[[:space:]].*--encrypted' "$KS_FILE" | grep -- '--passphrase=' | head -n 1)
|
||||
if [ -n "$LINE" ]; then
|
||||
PW=${LINE#*--passphrase=}
|
||||
case "$PW" in
|
||||
\"*) PW=${PW#\"}; PW=${PW%%\"*} ;;
|
||||
*) PW=${PW%%[[:space:]]*} ;;
|
||||
esac
|
||||
if [ -n "$PW" ]; then
|
||||
printf '%s' "$PW" > /tmp/.luks-passphrase
|
||||
chmod 600 /tmp/.luks-passphrase
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
%end
|
||||
|
||||
# Enroll TPM2-based LUKS auto-unlock (PCR 7-bound) when both guards hold: a
|
||||
# TPM2 device is available at install time and a passphrase was preseeded in
|
||||
# the kickstart (stashed by the %pre above). Otherwise the system keeps the
|
||||
# regular passphrase prompt at boot. On any failure the LUKS configuration is
|
||||
# left untouched, so the worst case is a passphrase prompt on every boot.
|
||||
%post --logfile=/root/luks-tpm-post.log
|
||||
|
||||
if [ -e /dev/tpmrm0 ] && [ -s /tmp/.luks-passphrase ]; then
|
||||
set -x
|
||||
LUKSUUID=$(awk '$2 ~ /^UUID=/ {sub(/^UUID=/, "", $2); print $2}' /etc/crypttab)
|
||||
LUKSDEV="/dev/disk/by-uuid/$LUKSUUID"
|
||||
if systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 --unlock-key-file=/tmp/.luks-passphrase "$LUKSDEV"; then
|
||||
sed -i 's| none discard,x-initrd.attach| tpm2-device=auto,discard,x-initrd.attach|' /etc/crypttab
|
||||
if ! grep -q 'tpm2-device=auto' /etc/crypttab; then
|
||||
sed -i -E 's|[[:space:]]none([[:space:]]|$)| tpm2-device=auto,discard\1|' /etc/crypttab
|
||||
fi
|
||||
if grep -q 'tpm2-device=auto' /etc/crypttab; then
|
||||
MID=$(cat /etc/machine-id)
|
||||
KVER=$(ls /usr/lib/modules | head -n 1)
|
||||
dracut -f --kver "$KVER" "/boot/efi/$MID/$KVER/initrd"
|
||||
fi
|
||||
fi
|
||||
shred -u /tmp/.luks-passphrase 2>/dev/null || true
|
||||
fi
|
||||
|
||||
%end
|
||||
|
||||
Reference in New Issue
Block a user