2023-02-08 21:01:48 +00:00
|
|
|
#!/bin/bash
|
2017-07-04 23:49:14 +00:00
|
|
|
# Save these options to be the persistent default
|
2017-07-12 04:17:45 +00:00
|
|
|
set -e -o pipefail
|
2018-12-06 23:24:28 +00:00
|
|
|
. /tmp/config
|
2017-07-04 23:49:14 +00:00
|
|
|
. /etc/functions
|
|
|
|
|
2023-02-20 16:01:17 +00:00
|
|
|
TRACE "Under /bin/kexec-save-default"
|
2023-02-18 17:58:43 +00:00
|
|
|
|
2017-07-22 20:32:10 +00:00
|
|
|
while getopts "b:d:p:i:" arg; do
|
2017-07-04 23:49:14 +00:00
|
|
|
case $arg in
|
2023-08-22 18:34:29 +00:00
|
|
|
b) bootdir="$OPTARG" ;;
|
|
|
|
d) paramsdev="$OPTARG" ;;
|
|
|
|
p) paramsdir="$OPTARG" ;;
|
|
|
|
i) index="$OPTARG" ;;
|
2017-07-04 23:49:14 +00:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2017-07-08 20:59:37 +00:00
|
|
|
if [ -z "$bootdir" -o -z "$index" ]; then
|
2017-07-17 16:43:14 +00:00
|
|
|
die "Usage: $0 -b /boot -i menu_option "
|
2017-07-04 23:49:14 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$paramsdev" ]; then
|
|
|
|
paramsdev="$bootdir"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$paramsdir" ]; then
|
|
|
|
paramsdir="$bootdir"
|
|
|
|
fi
|
|
|
|
|
2017-07-22 18:25:39 +00:00
|
|
|
bootdir="${bootdir%%/}"
|
|
|
|
paramsdev="${paramsdev%%/}"
|
|
|
|
paramsdir="${paramsdir%%/}"
|
|
|
|
|
2017-07-08 20:59:37 +00:00
|
|
|
TMP_MENU_FILE="/tmp/kexec/kexec_menu.txt"
|
2017-07-04 23:49:14 +00:00
|
|
|
ENTRY_FILE="$paramsdir/kexec_default.$index.txt"
|
|
|
|
HASH_FILE="$paramsdir/kexec_default_hashes.txt"
|
2022-08-25 18:43:31 +00:00
|
|
|
PRIMHASH_FILE="$paramsdir/kexec_primhdl_hash.txt"
|
2023-08-22 18:34:29 +00:00
|
|
|
KEY_DEVICES="$paramsdir/kexec_key_devices.txt"
|
|
|
|
KEY_LVM="$paramsdir/kexec_key_lvm.txt"
|
|
|
|
|
|
|
|
lvm_suggest=$(lvm vgscan | awk -F '"' {'print $1'} | tail -n +2)
|
|
|
|
num_lvm=$(echo "$lvm_suggest" | wc -l)
|
|
|
|
if [ "$num_lvm" -eq 1 ] && [ -n "$lvm_suggest" ]; then
|
|
|
|
lvm_volume_group="$lvm_suggest"
|
|
|
|
elif [ -z "$lvm_suggest" ]; then
|
|
|
|
num_lvm=0
|
|
|
|
fi
|
|
|
|
DEBUG "LVM num_lvm: $num_lvm, lvm_suggest: $lvm_suggest"
|
|
|
|
|
|
|
|
# get all LUKS container devices
|
|
|
|
devices_suggest=$(blkid | cut -d ':' -f 1 | while read device; do
|
2023-08-31 16:07:39 +00:00
|
|
|
if cryptsetup isLuks "$device"; then echo "$device"; fi
|
2023-08-22 18:34:29 +00:00
|
|
|
done | sort)
|
|
|
|
num_devices=$(echo "$devices_suggest" | wc -l)
|
|
|
|
|
|
|
|
if [ "$num_devices" -eq 1 ] && [ -s "$devices_suggest" ]; then
|
|
|
|
key_devices=$devices_suggest
|
|
|
|
else
|
|
|
|
devices_suggest=$(echo $devices_suggest)
|
|
|
|
fi
|
|
|
|
DEBUG "LUKS num_devices: $num_devices, devices_suggest: $devices_suggest"
|
|
|
|
|
|
|
|
if [ "$num_lvm" -eq 0 ] && [ "$num_devices" -eq 0 ]; then
|
|
|
|
#No encrypted partition found.
|
|
|
|
no_encrypted_partition=1
|
|
|
|
fi
|
2017-07-04 23:49:14 +00:00
|
|
|
|
2017-07-08 20:59:37 +00:00
|
|
|
if [ ! -r "$TMP_MENU_FILE" ]; then
|
|
|
|
die "No menu options available, please run kexec-select-boot"
|
|
|
|
fi
|
|
|
|
|
2023-08-22 18:34:29 +00:00
|
|
|
entry=$(head -n $index $TMP_MENU_FILE | tail -1)
|
2017-07-08 20:59:37 +00:00
|
|
|
if [ -z "$entry" ]; then
|
|
|
|
die "Invalid menu index $index"
|
|
|
|
fi
|
|
|
|
|
2017-07-29 17:24:34 +00:00
|
|
|
save_key="n"
|
2023-06-30 18:37:38 +00:00
|
|
|
if [ "$CONFIG_TPM" = "y" ] && [ "$CONFIG_TPM_NO_LUKS_DISK_UNLOCK" != "y" ] && [ "$CONFIG_BASIC" != y ]; then
|
2023-08-22 18:34:29 +00:00
|
|
|
DEBUG "TPM is enabled and TPM_NO_LUKS_DISK_UNLOCK is not set"
|
2023-08-31 16:07:39 +00:00
|
|
|
DEBUG "Checking if a a TPM Disk Unlock Key was previously set up from $KEY_DEVICES"
|
2017-12-05 08:29:07 +00:00
|
|
|
if [ ! -r "$KEY_DEVICES" ]; then
|
2023-08-31 16:07:39 +00:00
|
|
|
DEBUG "No previous TPM Disk Unlock Key was set up for LUKS devices, confirming to add a disk encryption to the TPM"
|
2017-12-05 08:29:07 +00:00
|
|
|
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
|
2023-08-22 18:34:29 +00:00
|
|
|
DEBUG "User confirmed to add a disk encryption to the TPM"
|
2017-12-05 08:29:07 +00:00
|
|
|
save_key="y"
|
|
|
|
fi
|
|
|
|
else
|
2023-08-31 16:07:39 +00:00
|
|
|
DEBUG "Previous TPM Disk Unlock Key was set up for LUKS devices"
|
2017-12-05 08:29:07 +00:00
|
|
|
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
|
2023-08-22 18:34:29 +00:00
|
|
|
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
|
2017-12-05 08:29:07 +00:00
|
|
|
else
|
2023-08-22 18:34:29 +00:00
|
|
|
old_key_devices=$(cat $KEY_DEVICES |
|
|
|
|
cut -d\ -f1 | xargs) || true
|
2017-12-05 08:29:07 +00:00
|
|
|
fi
|
|
|
|
|
2023-08-22 18:34:29 +00:00
|
|
|
lvm_suggest="$old_lvm_volume_group"
|
|
|
|
devices_suggest="$old_key_devices"
|
2017-12-05 08:29:07 +00:00
|
|
|
save_key="y"
|
2017-07-22 20:32:10 +00:00
|
|
|
fi
|
2017-07-29 17:24:34 +00:00
|
|
|
fi
|
|
|
|
|
2017-12-05 08:29:07 +00:00
|
|
|
if [ "$save_key" = "y" ]; then
|
2023-08-22 18:34:29 +00:00
|
|
|
if [ -n "$old_key_devices" ] || [ -n "$old_lvm_volume_group" ]; then
|
2023-08-31 16:07:39 +00:00
|
|
|
DEBUG "Previous TPM Disk Unlock Key was set up for LUKS devices $old_key_devices $old_lvm_volume_group"
|
2023-08-22 18:34:29 +00:00
|
|
|
read \
|
|
|
|
-n 1 \
|
|
|
|
-p "Do you want to reuse configured Encrypted LVM groups/Block devices? (Y/n):" \
|
|
|
|
reuse_past_devices
|
|
|
|
echo
|
|
|
|
if [ "$reuse_past_devices" = "y" ] || [ "$reuse_past_devices" = "Y" ] || [ -z "$reuse_past_devices" ]; then
|
|
|
|
if [ -z "$key_devices" ] && [ -n "$old_key_devices" ]; then
|
|
|
|
key_devices="$old_key_devices"
|
|
|
|
fi
|
|
|
|
if [ -z "$lvm_volume_group" ] && [ -n "$old_lvm_volume_group" ]; then
|
|
|
|
lvm_volume_group="$old_lvm_volume_group"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
else
|
2023-08-31 16:07:39 +00:00
|
|
|
DEBUG "No previous TPM Disk Unlock Key was set up for LUKS devices, setting up new ones"
|
2023-08-22 18:34:29 +00:00
|
|
|
if [ "$num_lvm" -gt 1 ]; then
|
|
|
|
DEBUG "Multiple LVM groups found"
|
2023-08-31 16:07:39 +00:00
|
|
|
# TODO: untested codepath. What uses lvm+LUKS on top nowadays?!?
|
2023-08-22 18:34:29 +00:00
|
|
|
selected_lvmdev_not_existing=1
|
|
|
|
while [ $selected_lvmdev_not_existing -ne 0 ]; do
|
|
|
|
{
|
|
|
|
read \
|
|
|
|
-p "Encrypted LVM group? choose between: '$lvm_suggest': " \
|
|
|
|
lvm_volume_group
|
2017-07-29 17:24:34 +00:00
|
|
|
|
2023-08-22 18:34:29 +00:00
|
|
|
result=$(echo "$lvm_suggest" | grep -q "$lvm_volume_group") || selected_lvmdev_not_existing=1
|
|
|
|
if [ $? == 0 ]; then
|
|
|
|
selected_lvmdev_not_existing=0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
done
|
|
|
|
elif [ "$num_lvm" -eq 1 ] && [ -s $lvm_suggest ]; then
|
|
|
|
echo "Single Encrypted LVM group found at $lvm_suggest."
|
|
|
|
lvm_volume_group=$lvm_suggest
|
|
|
|
else
|
|
|
|
echo "No encrypted LVM Group found."
|
|
|
|
fi
|
2017-07-29 17:24:34 +00:00
|
|
|
|
2023-08-22 18:34:29 +00:00
|
|
|
if [ "$num_devices" -gt 1 ]; then
|
|
|
|
DEBUG "Multiple LUKS devices found"
|
|
|
|
selected_luksdev_not_existing=1
|
|
|
|
while [ $selected_luksdev_not_existing -ne 0 ]; do
|
|
|
|
{
|
|
|
|
read \
|
|
|
|
-p "Encrypted devices? (choose between: '$devices_suggest'): " \
|
|
|
|
key_devices
|
2017-07-29 17:24:34 +00:00
|
|
|
|
2023-08-22 18:34:29 +00:00
|
|
|
result=$(echo "$devices_suggest" | grep -q "$key_devices") || selected_luksdev_not_existing=1
|
2023-08-31 16:07:39 +00:00
|
|
|
#if result is not empty, then the device exists
|
|
|
|
if [ -n "$result" ]; then
|
2023-08-22 18:34:29 +00:00
|
|
|
selected_luksdev_not_existing=0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
done
|
|
|
|
elif [ "$num_devices" -eq 1 ]; then
|
|
|
|
echo "Single Encrypted Disk found at $devices_suggest."
|
|
|
|
key_devices=$devices_suggest
|
|
|
|
else
|
|
|
|
echo "No encrypted devices found."
|
|
|
|
fi
|
|
|
|
fi
|
2017-07-29 17:24:34 +00:00
|
|
|
|
2017-12-05 08:29:07 +00:00
|
|
|
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
|
2023-08-22 18:34:29 +00:00
|
|
|
kexec-save-key $save_key_params ||
|
|
|
|
die "Failed to save the disk key"
|
2017-07-22 20:32:10 +00:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2017-07-04 23:49:14 +00:00
|
|
|
# try to switch to rw mode
|
|
|
|
mount -o rw,remount $paramsdev
|
|
|
|
|
|
|
|
if [ ! -d $paramsdir ]; then
|
2023-08-22 18:34:29 +00:00
|
|
|
mkdir -p $paramsdir ||
|
|
|
|
die "Failed to create params directory"
|
2017-07-04 23:49:14 +00:00
|
|
|
fi
|
2022-08-25 18:43:31 +00:00
|
|
|
|
|
|
|
if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then
|
2023-08-22 18:34:29 +00:00
|
|
|
sha256sum /tmp/primary.handle >"$PRIMHASH_FILE" ||
|
|
|
|
die "ERROR: Failed to Hash TPM2 primary key handle!"
|
2022-08-25 18:43:31 +00:00
|
|
|
fi
|
|
|
|
|
2020-08-26 11:21:57 +00:00
|
|
|
rm $paramsdir/kexec_default.*.txt 2>/dev/null || true
|
2023-08-22 18:34:29 +00:00
|
|
|
echo "$entry" >$ENTRY_FILE
|
|
|
|
(
|
|
|
|
cd $bootdir && kexec-boot -b "$bootdir" -e "$entry" -f |
|
|
|
|
xargs sha256sum >$HASH_FILE
|
2023-01-13 19:53:11 +00:00
|
|
|
) || die "Failed to create hashes of boot files"
|
2017-07-04 23:49:14 +00:00
|
|
|
if [ ! -r $ENTRY_FILE -o ! -r $HASH_FILE ]; then
|
|
|
|
die "Failed to write default config"
|
|
|
|
fi
|
|
|
|
|
2023-01-16 20:15:21 +00:00
|
|
|
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')
|
2023-08-22 18:34:29 +00:00
|
|
|
|
2023-01-16 20:15:21 +00:00
|
|
|
# Get crypttab files paths from initrd
|
2023-03-09 18:28:04 +00:00
|
|
|
echo "+++ Checking current selected default boot's $current_default_initrd for existing crypttab files..."
|
2023-01-16 20:15:21 +00:00
|
|
|
# First either decompress or use the original if it's not compressed
|
|
|
|
initrd_decompressed="/tmp/initrd_extract/initrd_decompressed.cpio"
|
2023-08-22 18:34:29 +00:00
|
|
|
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
|
|
|
|
|
2023-01-16 20:15:21 +00:00
|
|
|
if [ ! -z "$crypttab_files" ]; then
|
2023-03-09 18:28:04 +00:00
|
|
|
echo "+++ Extracting current selected default boot's $current_default_initrd for found crypttab files analysis..."
|
2023-08-22 18:34:29 +00:00
|
|
|
cpio -id --quiet $crypttab_files <$initrd_decompressed 2>/dev/null
|
2023-01-16 20:15:21 +00:00
|
|
|
rm -f $bootdir/kexec_initrd_crypttab_overrides.txt || true
|
2023-08-22 18:34:29 +00:00
|
|
|
|
2023-01-16 20:15:21 +00:00
|
|
|
#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
|
2023-08-22 18:34:29 +00:00
|
|
|
echo "$filepath:$single_modified_filepath_entry" >>$bootdir/kexec_initrd_crypttab_overrides.txt
|
2023-01-16 20:15:21 +00:00
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
|
|
#insert current default boot's initrd crypttab locations into tracking file to be overwritten into initramfs at kexec-inject-key
|
2023-03-09 18:28:04 +00:00
|
|
|
echo "+++ The following OS crypttab file:entry were modified from default boot's initrd:"
|
2023-01-16 20:15:21 +00:00
|
|
|
cat $bootdir/kexec_initrd_crypttab_overrides.txt
|
2023-03-09 18:28:04 +00:00
|
|
|
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."
|
2023-01-16 20:15:21 +00:00
|
|
|
else
|
2023-03-14 14:42:21 +00:00
|
|
|
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
|
2023-01-16 20:15:21 +00:00
|
|
|
fi
|
2023-03-14 14:42:21 +00:00
|
|
|
|
2023-01-16 20:15:21 +00:00
|
|
|
# Cleanup
|
2023-03-14 14:42:21 +00:00
|
|
|
cd /
|
2023-01-16 20:15:21 +00:00
|
|
|
rm -rf /tmp/initrd_extract || true
|
|
|
|
fi
|
|
|
|
|
2017-07-08 20:59:37 +00:00
|
|
|
# sign and auto-roll config counter
|
2017-12-05 08:29:07 +00:00
|
|
|
extparam=
|
2023-08-22 18:34:29 +00:00
|
|
|
if [ "$CONFIG_TPM" = "y" ]; then
|
2022-08-25 18:43:31 +00:00
|
|
|
if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then
|
|
|
|
extparam=-r
|
|
|
|
fi
|
2017-12-05 08:29:07 +00:00
|
|
|
fi
|
2023-06-21 18:36:28 +00:00
|
|
|
if [ "$CONFIG_BASIC" != "y" ]; then
|
2023-08-22 18:34:29 +00:00
|
|
|
kexec-sign-config -p $paramsdir $extparam ||
|
|
|
|
die "Failed to sign default config"
|
2022-03-15 17:05:04 +00:00
|
|
|
fi
|
2017-07-04 23:49:14 +00:00
|
|
|
# switch back to ro mode
|
|
|
|
mount -o ro,remount $paramsdev
|