From 6ff6bef619178edb9bc0cc82f436bfc4e0371494 Mon Sep 17 00:00:00 2001 From: m2 <69128853+m2Giles@users.noreply.github.com> Date: Sun, 7 Jul 2024 16:00:22 -0400 Subject: [PATCH] refactor: Rewrite luks tpm2 script. (#302) * refactor: Rewrite luks tpm2 script. The previous version of the tpm2 script did not fail out when encountering unsupported configurations. This script is narrowly focused at enabling tpm2 decryption for root devices. By default we expect this to be configured via the installer. This script will now fail out if it cannot find the disk. The disk is determined via the kernel commandline instead of /etc/crypttab. It still only supports a single disk. It now also provides hints on why the script has failed and the commands to run to disable and/or enable. * refactor: Provide more information with script * refactor: Include more safety checks * fix: remove unnecessary luks check --------- Co-authored-by: Benjamin Sherman --- .../luks-disable-tpm2-autounlock | 60 +++++++++++--- .../ublue-os-luks/luks-enable-tpm2-autounlock | 81 ++++++++++++------- build/ublue-os-luks/ublue-os-luks.spec | 6 +- 3 files changed, 103 insertions(+), 44 deletions(-) diff --git a/build/ublue-os-luks/luks-disable-tpm2-autounlock b/build/ublue-os-luks/luks-disable-tpm2-autounlock index 7e9a603d..e8eadacc 100755 --- a/build/ublue-os-luks/luks-disable-tpm2-autounlock +++ b/build/ublue-os-luks/luks-disable-tpm2-autounlock @@ -1,39 +1,72 @@ #!/bin/bash ## disable auto-unlock LUKS2 encrypted root on Fedora/Silverblue/maybe others -set -u +set -euo pipefail [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;} -read -p "This will modify your system and disable TPM2 auto-unlock of your LUKS partition! Are you sure you've read the script and are good with this? " -n 1 -r +echo "This script utilizes systemd-cryptenroll for removing tpm2 auto-unlock." +echo "You can review systemd-cryptenroll's manpage for more information." +read -p "This will modify your system and disable TPM2 auto-unlock of your LUKS partition! Are you sure you are good with this? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then - [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell + [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell fi -DISK_UUID=$(sudo awk '{ print $2 }' /etc/crypttab | cut -d= -f2) +## Inspect Kernel Cmdline for rd.luks.uuid +RD_LUKS_UUID="$(xargs -n1 -a /proc/cmdline | grep rd.luks.uuid | cut -d = -f 2)" + +# Check to make sure cmdline rd.luks.uuid exists +if [[ -z ${RD_LUKS_UUID:-} ]]; then + printf "LUKS device not defined on Kernel Commandline.\n" + printf "This is not supported by this script.\n" + printf "Exiting...\n" + exit 1 +fi + +# Check to make sure that the specified cmdline uuid exists. +if ! grep -q "${RD_LUKS_UUID}" <<< "$(lsblk)" ; then + printf "LUKS device not listed in block devices.\n" + printf "Exiting...\n" + exit 1 +fi + +# Cut off the luks- +LUKS_PREFIX="luks-" +if grep -q ^${LUKS_PREFIX} <<< "${RD_LUKS_UUID}"; then + DISK_UUID=${RD_LUKS_UUID#"$LUKS_PREFIX"} +else + echo "LUKS UUID format mismatch." + echo "Exiting..." + exit 1 +fi + +# Specify Crypt Disk by-uuid CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" +# Check to make sure crypt disk exists +if [[ ! -L "$CRYPT_DISK" ]]; then + printf "LUKS device not listed in block devices.\n" + printf "Exiting...\n" + exit 1 +fi + ## Restore the crypttab cp -a /etc/crypttab /etc/crypttab.working-before-disable-tpm2 if [ -f /etc/crypttab.known-good ]; then echo "Restoring /etc/crypttab.known-good to original /etc/crypttab" mv /etc/crypttab.known-good /etc/crypttab -else - echo "No /etc/crypttab.known-good found to restore" fi ## Wipe luks slot -cryptsetup luksDump $CRYPT_DISK | grep systemd-tpm2 > /dev/null -if [ 0 -eq $? ]; then +if cryptsetup luksDump "$CRYPT_DISK" | grep systemd-tpm2 > /dev/null; then echo "Wiping systemd-tpm2 from LUKS on $CRYPT_DISK" - systemd-cryptenroll --wipe-slot=tpm2 $CRYPT_DISK + systemd-cryptenroll --wipe-slot=tpm2 "$CRYPT_DISK" else echo "No systemd-tpm2 found in LUKS to wipe" fi ## Disable initramfs -rpm-ostree initramfs | grep tpm2 > /dev/null -if [ 0 -eq $? ]; then +if rpm-ostree initramfs | grep tpm2 > /dev/null; then echo "WARNING: if you configured initramfs for anything other than TPM2, this wipes that too..." echo "here's a printout:" rpm-ostree initramfs @@ -41,5 +74,8 @@ if [ 0 -eq $? ]; then echo "Disabling rpm-ostree initramfs..." rpm-ostree initramfs --disable else - echo "TPM2 was not found in 'rpm-ostree initramfs'..." + echo "TPM2 is not configured in 'rpm-ostree initramfs'..." fi + +echo "TPM2 auto-unlock disabled..." +echo "To reenroll TPM2 auto unlock please run ujust setup-luks-tpm-unlock..." diff --git a/build/ublue-os-luks/luks-enable-tpm2-autounlock b/build/ublue-os-luks/luks-enable-tpm2-autounlock index f8baf092..0e232c96 100755 --- a/build/ublue-os-luks/luks-enable-tpm2-autounlock +++ b/build/ublue-os-luks/luks-enable-tpm2-autounlock @@ -1,57 +1,76 @@ #!/bin/bash ## setup auto-unlock LUKS2 encrypted root on Fedora/Silverblue/maybe others -set -u +set -eou pipefail [ "$UID" -eq 0 ] || { echo "This script must be run as root."; exit 1;} -read -p "This will modify your system and enable TPM2 auto-unlock of your LUKS partition! Are you sure you've read the script and are good with this? " -n 1 -r +echo "This script uses systemd-cryptenroll to enable TPM2 auto-unlock." +echo "You can review systemd-cryptenroll's manpage for more information." +echo "This script will modify your system." +echo "It will enable TPM2 auto-unlock of your LUKS partition for your root device!" +echo "It will bind to PCR 7 only which is tied to your secureboot state." +read -p "Are you sure are good with this and want to enable TPM2 auto-unlock? " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then - [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell + [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell fi -## Inspect crypttab to find disk info, should look like this -#sudo cat /etc/crypttab -#luks-912462a2-39ce-abcd-1234-89c6c0304cb4 UUID=912462a2-39ce-abcd-1234-89c6c0304cb4 none discard -DISK_UUID=$(sudo awk '{ print $2 }' /etc/crypttab | cut -d= -f2) -CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" +## Inspect Kernel Cmdline for rd.luks.uuid +RD_LUKS_UUID="$(xargs -n1 -a /proc/cmdline | grep rd.luks.uuid | cut -d = -f 2)" -## Backup the crypttab -if [ -f /etc/crypttab.known-good ]; then - echo "Our backup already exists at /etc/crypttab.known-good\nExiting..." - [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 +# Check to make sure cmdline rd.luks.uuid exists +if [[ -z ${RD_LUKS_UUID:-} ]]; then + printf "LUKS device not defined on Kernel Commandline.\n" + printf "This is not supported by this script.\n" + printf "Exiting...\n" + exit 1 fi -cp -a /etc/crypttab /etc/crypttab.known-good -## modify the crypttab -grep tpm2-device /etc/crypttab > /dev/null -if [ 0 -eq $? ]; then - echo "TPM2 already present in /etc/crypttab. Exiting..." - [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 +# Check to make sure that the specified cmdline uuid exists. +if ! grep -q "${RD_LUKS_UUID}" <<< "$(lsblk)" ; then + printf "LUKS device not listed in block devices.\n" + printf "Exiting...\n" + exit 1 fi -sed -i "s/discard/discard,tpm2-device=auto/" /etc/crypttab -cryptsetup luksDump $CRYPT_DISK | grep systemd-tpm2 > /dev/null -if [ 0 -eq $? ]; then - KEYSLOT=$(cryptsetup luksDump $CRYPT_DISK|grep -A23 systemd-tpm2|grep Keyslot|awk '{print $2}') - echo "TPM2 already present in LUKS Keyslot $KEYSLOT of $CRYPT_DISK. Exiting..." - [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 +# Cut off the luks- +LUKS_PREFIX="luks-" +if grep -q ^${LUKS_PREFIX} <<< "${RD_LUKS_UUID}"; then + DISK_UUID=${RD_LUKS_UUID#"$LUKS_PREFIX"} +else + echo "LUKS UUID format mismatch." + echo "Exiting..." + exit 1 +fi + +# Specify Crypt Disk by-uuid +CRYPT_DISK="/dev/disk/by-uuid/$DISK_UUID" + +# Check to make sure crypt disk exists +if [[ ! -L "$CRYPT_DISK" ]]; then + printf "LUKS device not listed in block devices.\n" + printf "Exiting...\n" + exit 1 +fi + +if cryptsetup luksDump "$CRYPT_DISK" | grep systemd-tpm2 > /dev/null; then + KEYSLOT=$(cryptsetup luksDump "$CRYPT_DISK"|grep -A29 systemd-tpm2|grep Keyslot|awk '{print $2}') + echo "TPM2 already present in LUKS Keyslot $KEYSLOT of $CRYPT_DISK." + echo "Remove the existing TPM2 enrollment with ujust remove-luks-tpm2-autounlock" + echo "Exiting..." + [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 fi ## Run crypt enroll echo "Enrolling TPM2 unlock requires your existing LUKS2 unlock password" -echo -systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 $CRYPT_DISK +systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 "$CRYPT_DISK" -lsinitrd 2>&1 | grep -q tpm2-tss > /dev/null -if [ 1 -eq $? ]; then +if lsinitrd 2>&1 | grep -q tpm2-tss > /dev/null; then ## add tpm2-tss to initramfs - rpm-ostree initramfs | grep tpm2 > /dev/null - if [ 0 -eq $? ]; then + if rpm-ostree initramfs | grep tpm2 > /dev/null; then echo "TPM2 already present in rpm-ostree initramfs config." rpm-ostree initramfs - echo echo "Re-running initramfs to pickup changes above." fi rpm-ostree initramfs --enable --arg=--force-add --arg=tpm2-tss diff --git a/build/ublue-os-luks/ublue-os-luks.spec b/build/ublue-os-luks/ublue-os-luks.spec index f5cb27ed..63520f68 100644 --- a/build/ublue-os-luks/ublue-os-luks.spec +++ b/build/ublue-os-luks/ublue-os-luks.spec @@ -1,7 +1,7 @@ Name: ublue-os-luks Packager: ublue-os Vendor: ublue-os -Version: 0.2 +Version: 0.3 Release: 1%{?dist} Summary: ublue-os scripts for simplified LUKS usage License: MIT @@ -31,6 +31,10 @@ install -Dm644 %{SOURCE2} %{buildroot}/%{_exec_prefix}/lib/dracut/dracut.conf.d %attr(0644,root,root) %{_exec_prefix}/lib/dracut/dracut.conf.d/90-ublue-luks.conf %changelog +* Thu Jul 04 2024 m2Giles <69128853+m2Giles@users.noreply.github.com> - 0.3 +- Rewrite enable script to fail out if disk is not found +- LUKs disk is determined from kernel commandline instead of /etc/crypttab + * Sat Jun 29 2024 Benjamin Sherman - 0.2 - Add tpm, fido2, pkcs11 to dracut config enabling initramfs LUKS unlock options