diff --git a/dracut-kexec-crypt-setup.sh b/dracut-kexec-crypt-setup.sh new file mode 100644 index 0000000..7d79ed5 --- /dev/null +++ b/dracut-kexec-crypt-setup.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# +echo true > /sys/kernel/config/crash_dm_crypt_keys/restore diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index c32b381..2673a87 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -1145,6 +1145,50 @@ remove_cpu_online_rule() { sed -i '/SUBSYSTEM=="cpu"/d' "$file" } +kdump_check_crypt_targets() { + local _luks_dev _devuuid _key_desc + declare -a _luks_devs + + mapfile -t _luks_devs < <(get_all_kdump_crypt_dev) + + if [[ ${#_luks_devs[@]} -lt 1 ]]; then + return + fi + + if [[ ! -d $LUKS_CONFIGFS ]]; then + dwarn "$LUKS_CONFIGFS not available" + return 1 + fi + + # This overrides behaviour of 90crypt + inst cryptsetup + instmods dm_crypt + + echo > "$initdir/etc/cmdline.d/90crypt.conf" + echo > "$initdir/etc/crypttab" + echo > "${initdir}/sbin/crypt-run-generator" + + # configfs is mounted after dracut pre-udev hook + # shellcheck disable=SC2154 + inst_hook initqueue 20 "$moddir/kexec-crypt-setup.sh" + + # shellcheck disable=SC2154 + mkdir -p "$hookdir/initqueue/finished" + CRYPTSETUP_PATH=$(command -v cryptsetup) + for _luks_dev in "${_luks_devs[@]}"; do + _devuuid=$(maj_min_to_uuid "$_luks_dev") + _key_desc=$LUKS_KEY_PRFIX$_devuuid + cat << EOF >> "${initdir}/etc/udev/rules.d/70-luks-kdump.rules" +ENV{ID_FS_UUID}=="$_devuuid", \ +RUN+="/sbin/initqueue --settled --unique --onetime --name kdump-crypt-target-%k \ +$CRYPTSETUP_PATH luksOpen --volume-key-keyring \ +%%user:$_key_desc \$env{DEVNAME} luks-$_devuuid" +EOF + done + + dracut_need_initqueue +} + install() { declare -A unique_netifs ipv4_usage ipv6_usage local arch has_ovs_bridge is_nvmf @@ -1204,6 +1248,8 @@ install() { kdump_check_nvmf_target + kdump_check_crypt_targets + kdump_install_systemd_conf # nfs/ssh dump will need to get host ip in second kernel and need to call 'ip' tool, see get_host_ip for more detail diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh index e1b5d53..7b0fa49 100755 --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -8,6 +8,10 @@ KDUMP_CONFIG_FILE="/etc/kdump.conf" FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump" FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send" LVM_CONF="/etc/lvm/lvm.conf" +# shellcheck disable=SC2034 +LUKS_CONFIGFS=/sys/kernel/config/crash_dm_crypt_keys +# shellcheck disable=SC2034 +LUKS_KEY_PRFIX="systemd-cryptsetup:vk-" # Read kdump config in well formated style kdump_read_conf() diff --git a/kdumpctl b/kdumpctl index 107137d..c572954 100755 --- a/kdumpctl +++ b/kdumpctl @@ -47,6 +47,7 @@ trap ' ret=$?; is_mounted $TMPMNT && umount -f $TMPMNT; rm -rf "$KDUMP_TMPDIR" + [[ -d $LUKS_CONFIGFS ]] && find $LUKS_CONFIGFS/ -mindepth 1 -type d -delete exit $ret; ' EXIT @@ -677,6 +678,11 @@ load_kdump() chcon -t boot_t "$KDUMP_KERNEL" fi + if ! prepare_luks; then + derror "kexec: failed to prepare for a LUKS target" + return 1 + fi + ddebug "$KEXEC $KEXEC_ARGS $standard_kexec_args --command-line=$KDUMP_COMMANDLINE --initrd=$TARGET_INITRD $KDUMP_KERNEL" # shellcheck disable=SC2086 @@ -1051,6 +1057,36 @@ check_final_action_config() fi } +prepare_luks() +{ + local _luks_dev _key_id _key_des + declare -a _luks_devs + + mapfile -t _luks_devs < <(get_all_kdump_crypt_dev) + + if [[ ${#_luks_devs[@]} -lt 1 ]]; then + return + fi + + if [[ ! -d $LUKS_CONFIGFS ]]; then + dwarn "$LUKS_CONFIGFS not available, please use a newer kernel." + return 1 + fi + + for _luks_dev in "${_luks_devs[@]}"; do + _devuuid=$(maj_min_to_uuid "$_luks_dev") + _key_dir=$LUKS_CONFIGFS/$_devuuid + _key_des=$LUKS_KEY_PRFIX$_devuuid + if _key_id=$(keyctl request logon "$_key_des" 2> /dev/null); then + mkdir "$_key_dir" + printf "%s" "$_key_des" > "$_key_dir"/description + else + derror "Failed to get logon key $_key_des. Ensure the link-volume-key option is correctly set up in /etc/crypttab (see man crypttab) and that the key is available." + return 1 + fi + done +} + start() { if ! check_dump_feasibility; then diff --git a/kexec-tools.spec b/kexec-tools.spec index 061981f..6c9a1c3 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -60,6 +60,7 @@ Source106: dracut-kdump-capture.service Source107: dracut-kdump-emergency.target Source108: dracut-early-kdump.sh Source109: dracut-early-kdump-module-setup.sh +Source110: dracut-kexec-crypt-setup.sh Source200: dracut-fadump-init-fadump.sh Source201: dracut-fadump-module-setup.sh @@ -250,6 +251,7 @@ cp %{SOURCE102} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpb cp %{SOURCE104} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE104}} cp %{SOURCE106} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE106}} cp %{SOURCE107} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE107}} +cp %{SOURCE110} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE110}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}} mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump diff --git a/mkdumprd b/mkdumprd index 77c3538..d4a7de4 100644 --- a/mkdumprd +++ b/mkdumprd @@ -359,24 +359,10 @@ check_resettable() return 1 } -check_crypt() -{ - local _dev - - for _dev in $(get_kdump_targets); do - if [[ -n $(get_luks_crypt_dev "$(get_maj_min "$_dev")") ]]; then - derror "Device $_dev is encrypted." && return 1 - fi - done -} - if ! check_resettable; then exit 1 fi -if ! check_crypt; then - dwarn "Warning: Encrypted device is in dump path, which is not recommended, see kexec-kdump-howto.txt for more details." -fi # firstly get right SSH_KEY_LOCATION keyfile=$(kdump_get_conf_val sshkey) diff --git a/supported-kdump-targets.txt b/supported-kdump-targets.txt index 4ae0d59..71e7ecc 100644 --- a/supported-kdump-targets.txt +++ b/supported-kdump-targets.txt @@ -49,6 +49,7 @@ storage: NVMe-FC (qla2xxx, lpfc) NVMe/TCP configured by NVMe Boot Firmware Table (users may need to increase the crashkernel value) + LUKS-encrypted volume network: Hardware using kernel modules: (igb, ixgbe, ice, i40e, e1000e, igc,