#!/bin/bash # Save these options to be the persistent default set -e -o pipefail . /tmp/config . /etc/functions TRACE "Under /bin/kexec-save-default" while getopts "b:d:p:i:" arg; do case $arg in b) bootdir="$OPTARG" ;; d) paramsdev="$OPTARG" ;; p) paramsdir="$OPTARG" ;; i) index="$OPTARG" ;; esac done if [ -z "$bootdir" -o -z "$index" ]; then die "Usage: $0 -b /boot -i menu_option " fi if [ -z "$paramsdev" ]; then paramsdev="$bootdir" fi if [ -z "$paramsdir" ]; then paramsdir="$bootdir" fi bootdir="${bootdir%%/}" paramsdev="${paramsdev%%/}" paramsdir="${paramsdir%%/}" TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt" ENTRY_FILE="$paramsdir/kexec_default.$index.txt" HASH_FILE="$paramsdir/kexec_default_hashes.txt" PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt" if [ ! -r "$TMP_MENU_FILE" ]; then die "No menu options available, please run kexec-select-boot" fi entry=`head -n $index $TMP_MENU_FILE | tail -1` if [ -z "$entry" ]; then die "Invalid menu index $index" fi KEY_DEVICES="$paramsdir/kexec_key_devices.txt" KEY_LVM="$paramsdir/kexec_key_lvm.txt" save_key="n" if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ]; then if [ ! -r "$KEY_DEVICES" ]; then read \ -n 1 \ -p "Do you wish to add a disk encryption to the TPM [y/N]: " \ add_key_confirm echo if [ "$add_key_confirm" = "y" \ -o "$add_key_confirm" = "Y" ]; then lvm_suggest="e.g. qubes_dom0 or blank" devices_suggest="e.g. /dev/sda2 or blank" save_key="y" fi else read \ -n 1 \ -p "Do you want to reseal a disk key to the TPM [y/N]: " \ change_key_confirm echo if [ "$change_key_confirm" = "y" \ -o "$change_key_confirm" = "Y" ]; then old_lvm_volume_group="" if [ -r "$KEY_LVM" ]; then old_lvm_volume_group=`cat $KEY_LVM` || true old_key_devices=`cat $KEY_DEVICES \ | cut -d\ -f1 \ | grep -v "$old_lvm_volume_group" \ | xargs` || true else old_key_devices=`cat $KEY_DEVICES \ | cut -d\ -f1 | xargs` || true fi lvm_suggest="was '$old_lvm_volume_group'" devices_suggest="was '$old_key_devices'" save_key="y" fi fi if [ "$save_key" = "y" ]; then echo "+++ LVM volume groups (lvm vgscan): " lvm vgscan || true read \ -p "LVM group containing Encrypted LVs (retype to keep)? ($lvm_suggest): " \ lvm_volume_group echo "+++ Block devices (blkid): " blkid || true read \ -p "Encrypted devices (retype to keep)? ($devices_suggest): " \ key_devices save_key_params="-s -p $paramsdev" if [ -n "$lvm_volume_group" ]; then save_key_params="$save_key_params -l $lvm_volume_group $key_devices" else save_key_params="$save_key_params $key_devices" fi echo "Running kexec-save-key with params: $save_key_params" kexec-save-key $save_key_params \ || die "Failed to save the disk key" fi fi # try to switch to rw mode mount -o rw,remount $paramsdev if [ ! -d $paramsdir ]; then mkdir -p $paramsdir \ || die "Failed to create params directory" fi if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then sha256sum /tmp/primary.handle > "$PRIMHASH_FILE" \ || die "ERROR: Failed to Hash TPM2 primary key handle!" fi rm $paramsdir/kexec_default.*.txt 2>/dev/null || true echo "$entry" > $ENTRY_FILE ( cd $bootdir && kexec-boot -b "$bootdir" -e "$entry" -f| \ xargs sha256sum > $HASH_FILE \ ) || die "Failed to create hashes of boot files" if [ ! -r $ENTRY_FILE -o ! -r $HASH_FILE ]; then die "Failed to write default config" fi if [ "$save_key" = "y" ]; then # logic to parse OS initrd to extract crypttab, its filepaths and its OS defined options mkdir -p /tmp/initrd_extract cd /tmp/initrd_extract # Get initrd filename selected to be default initrd that OS could be using to configure LUKS on boot by deploying crypttab files current_default_initrd=$(cat /boot/kexec_default_hashes.txt | grep initr | awk -F " " {'print $NF'} | sed 's/\.\//\/boot\//g') # Get crypttab files paths from initrd echo "Checking current selected default boot's $current_default_initrd for existing crypttab files..." # First either decompress or use the original if it's not compressed initrd_decompressed="/tmp/initrd_extract/initrd_decompressed.cpio" zcat < "$current_default_initrd" > "$initrd_decompressed" 2> /dev/null || initrd_decompressed="$current_default_initrd" crypttab_files=$(cpio --list --quiet < "$initrd_decompressed" | grep crypttab 2> /dev/null) || true if [ ! -z "$crypttab_files" ]; then echo "Extracting current selected default boot's $current_default_initrd for found crypttab files analysis..." cpio -id --quiet < $initrd_decompressed $crypttab_files 2> /dev/null rm -f $bootdir/kexec_initrd_crypttab_overrides.txt || true #Parsing each crypttab file found echo "$crypttab_files" | while read filepath; do # Keep only non-commented lines current_filepath_entries=$(cat "$filepath" | grep -v "^#") # Modify each retained crypttab line to contain to be injected /secret.key at next default boots modified_filepath_entries=$(echo "$current_filepath_entries" | sed 's/none/\/secret.key/g') echo "$modified_filepath_entries" | while read single_modified_filepath_entry; do # Append each found filepath:entry into additional kexec_ file that will be part of detached signed digest echo "$filepath:$single_modified_filepath_entry" >> $bootdir/kexec_initrd_crypttab_overrides.txt done done cd - > /dev/null #insert current default boot's initrd crypttab locations into tracking file to be overwritten into initramfs at kexec-inject-key echo "The following OS crypttab file:entry were modified from default boot's initrd:" cat $bootdir/kexec_initrd_crypttab_overrides.txt echo "Heads added /secret.key in those entries and saved them under $bootdir/kexec_initrd_crypttab_overrides.txt" echo "Those overrides will be part of detached signed digests and used to prepare cpio injected at kexec of selected default boot entry." else echo "No crypttab file found in extracted initrd. Removing $bootdir/kexec_initrd_crypttab_overrides.txt" rm -f "$bootdir/kexec_initrd_crypttab_overrides.txt" || true fi # Cleanup rm -rf /tmp/initrd_extract || true fi # sign and auto-roll config counter extparam= if [ "$CONFIG_TPM" = "y" ];then if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then extparam=-r fi fi kexec-sign-config -p $paramsdir $extparam \ || die "Failed to sign default config" # switch back to ro mode mount -o ro,remount $paramsdev