#!/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 #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. A generic crypttab will be generated" if [ -e "$bootdir/kexec_initrd_crypttab_overrides.txt" ]; then echo "+++ Removing $bootdir/kexec_initrd_crypttab_overrides.txt" rm -f "$bootdir/kexec_initrd_crypttab_overrides.txt" fi fi # Cleanup cd / 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 if [ "$CONFIG_BASIC" != "y" ]; then kexec-sign-config -p $paramsdir $extparam \ || die "Failed to sign default config" fi # switch back to ro mode mount -o ro,remount $paramsdev