This bypass decrypt LUKS target in second kernel, so memory usage is
reduced by a lot, and no longer need to input password in second kernel.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
dracut-module-setup.sh | 16 +++++++++++
kdumpctl | 60 ++++++++++++++++++++++++++++++++++++++++++
kexec-crypt-init.sh | 18 +++++++++++++
kexec-crypt-setup.sh | 18 +++++++++++++
kexec-tools.spec | 4 +++
5 files changed, 116 insertions(+)
create mode 100644 kexec-crypt-init.sh
create mode 100644 kexec-crypt-setup.sh
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index b4efc46..88764e0 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -826,6 +826,20 @@ kdump_install_systemd_conf() {
echo "ForwardToConsole=yes" >>
${initdir}/etc/systemd/journald.conf.d/kdump.conf
}
+kdump_check_crypt_targets()
+{
+ # This overrides behaviour of 90crypt
+ inst_hook cmdline 20 "/usr/lib/kdump/kexec-crypt-setup.sh"
+
+ inst cryptsetup
+ instmods dm_crypt
+
+ echo > "$initdir/etc/cmdline.d/90crypt.conf"
+ echo > "$initdir/etc/crypttab"
+
+ dracut_need_initqueue
+}
+
install() {
kdump_module_init
kdump_install_conf
@@ -868,6 +882,8 @@ install() {
# at some point of time.
kdump_check_iscsi_targets
+ 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/kdumpctl b/kdumpctl
index 009d259..c6acfdb 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -4,6 +4,7 @@ KEXEC=/sbin/kexec
KDUMP_KERNELVER=""
KDUMP_KERNEL=""
KDUMP_COMMANDLINE=""
+KEXEC_CRYPTO_TMPDIR=""
KEXEC_ARGS=""
KDUMP_CONFIG_FILE="/etc/kdump.conf"
KDUMP_LOG_PATH="/var/log"
@@ -670,6 +671,60 @@ function remove_kdump_kernel_key()
keyctl unlink $KDUMP_KEY_ID %:.ima
}
+# Load the kdump kernel specified in /etc/sysconfig/kdump
+# If none is specified, try to load a kdump kernel with the same version
+prepare_luks_initramfs()
+{
+ local _crypt_devices
+
+ _crypt_devices="$(get_all_kdump_crypt_dev)"
+ [[ -z "$_crypt_devices" ]] && return
+
+ trap '
+ ret=$?;
+ if [[ -d "$KEXEC_CRYPTO_TMPDIR" ]]; then
+ clean_luks_initramfs
+ fi
+ exit $ret;
+ ' EXIT
+
+ KEXEC_CRYPTO_TMPDIR="$(mktemp -d -t kexec-crypt.XXXXXX)"
+ [ -d "$KEXEC_CRYPTO_TMPDIR" ] || perror_exit "kdumpctl: mktemp -p -d -t
kexec-crypt.XXXXXX failed."
+ mkdir -p "$KEXEC_CRYPTO_TMPDIR/rootfs"
+ chmod -R 0600 "$KEXEC_CRYPTO_TMPDIR/rootfs"
+
+ # clean up after ourselves no matter how we die.
+ trap 'exit 1;' SIGINT
+
+ local _dev _uuid
+ for _dev in $_crypt_devices; do
+ _uuid=$(get_block_uuid "$_dev")
+ if ! get_luks_dev_master_key "$_dev"
"$KEXEC_CRYPTO_TMPDIR/rootfs/.kexec-luks-key.$_uuid";
+ then
+ dwarn "Can't retrive LUKS key, crashkernel value should be large enough for
LUKS key decryption, and kdump kernel will prompt for password."
+ clean_luks_initramfs
+ return 1
+ fi
+ done
+
+ lsinitrd "$TARGET_INITRD" -f /init >
"$KEXEC_CRYPTO_TMPDIR/rootfs/init.kexec.orig"
+ cp /usr/lib/kdump/kexec-crypt-init.sh "$KEXEC_CRYPTO_TMPDIR/rootfs/init"
+ chmod -R 0700 "$KEXEC_CRYPTO_TMPDIR/rootfs/init"
+ chmod -R 0700 "$KEXEC_CRYPTO_TMPDIR/rootfs/init.kexec.orig"
+
+ cp "$TARGET_INITRD" "$KEXEC_CRYPTO_TMPDIR/crypt-initramfs"
+ append_initramfs "$KEXEC_CRYPTO_TMPDIR/crypt-initramfs"
"$KEXEC_CRYPTO_TMPDIR/rootfs"
+
+ TARGET_INITRD=$KEXEC_CRYPTO_TMPDIR/crypt-initramfs
+}
+
+clean_luks_initramfs()
+{
+ [[ -d "$KEXEC_CRYPTO_TMPDIR" ]] || return 0
+ find "$KEXEC_CRYPTO_TMPDIR" -type f -exec shred {} \;
+ rm --one-file-system -rf -- "$KEXEC_CRYPTO_TMPDIR";
+}
+
# Load the kdump kernel specified in /etc/sysconfig/kdump
# If none is specified, try to load a kdump kernel with the same version
# as the currently running kernel.
@@ -690,6 +745,7 @@ load_kdump()
fi
ddebug "$KEXEC $KEXEC_ARGS $standard_kexec_args --command-line=$KDUMP_COMMANDLINE
--initrd=$TARGET_INITRD $KDUMP_KERNEL"
+ [[ $(get_all_kdump_crypt_dev) ]] && prepare_luks_initramfs
# The '12' represents an intermediate temporary file descriptor
# to store the standard error file descriptor '2', and later
@@ -708,6 +764,10 @@ load_kdump()
set +x
exec 2>&12 12>&-
+ # unset here to avoid any misuse
+ unset TARGET_INITRD
+
+ clean_luks_initramfs
remove_kdump_kernel_key
if [ $ret == 0 ]; then
diff --git a/kexec-crypt-init.sh b/kexec-crypt-init.sh
new file mode 100644
index 0000000..cec1977
--- /dev/null
+++ b/kexec-crypt-init.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/sh
+PATH=/bin:/sbin:/usr/bin:/usr/sbin
+
+for _bin in grep mkdir mount mv; do
+ [ -n "$(command -v $_bin)" ] && continue
+ [ -n "$(command -v busybox)" ] && eval 'alias $_bin="busybox
$_bin"' && continue
+
+ echo "$_bin is missing!"
+done
+
+[ -e /proc/self/mounts ] || \
+ ( mkdir -p /proc && mount -t proc -o nosuid,noexec,nodev proc /proc )
+
+grep -q '^devtmpfs /dev devtmpfs' < /proc/self/mounts || \
+ ( mkdir -p /dev && mount -t devtmpfs -o mode=755,noexec,nosuid,strictatime
devtmpfs /dev )
+
+mv /.kexec-luks-key.* /dev/
+exec /init.kexec.orig
diff --git a/kexec-crypt-setup.sh b/kexec-crypt-setup.sh
new file mode 100644
index 0000000..021bedc
--- /dev/null
+++ b/kexec-crypt-setup.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+_kexec_crypt_setup() {
+ for _mk in /dev/.kexec-luks-key.*; do
+ _devuuid=${_mk#/dev/.kexec-luks-key.}
+
+ printf -- '[ -e /dev/disk/by-id/dm-uuid-CRYPT-LUKS?-*-luks-%s ] || exit 1\n'
"$_devuuid" >>
"$hookdir/initqueue/finished/99-kdumpbase-crypt.sh"
+
+ {
+ printf -- 'ENV{ID_FS_UUID}=="%s", ' "$_devuuid"
+ printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v
initqueue)"
+ printf -- '--name kdump-crypt-target-%%k %s ' "$(command -v
cryptsetup)"
+ printf -- 'luksOpen --master-key-file %s $env{DEVNAME} %s"\n'
"$_mk" "luks-$_devuuid"
+ } >> /etc/udev/rules.d/70-luks-kdump.rules
+ done
+}
+
+_kexec_crypt_setup
diff --git a/kexec-tools.spec b/kexec-tools.spec
index 598f238..43e19c5 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -39,6 +39,8 @@ Source28: kdump-udev-throttler
Source29: kdump.sysconfig.aarch64
Source30: 60-kdump.install
Source31: kdump-logger.sh
+Source32: kexec-crypt-init.sh
+Source33: kexec-crypt-setup.sh
#######################################
# These are sources for mkdumpramfs
@@ -191,6 +193,8 @@ install -m 644 %{SOURCE25} $RPM_BUILD_ROOT%{_mandir}/man8/kdumpctl.8
install -m 755 %{SOURCE20} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-lib.sh
install -m 755 %{SOURCE23} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-lib-initramfs.sh
install -m 755 %{SOURCE31} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kdump-logger.sh
+install -m 755 %{SOURCE32} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kexec-crypt-init.sh
+install -m 755 %{SOURCE33} $RPM_BUILD_ROOT%{_prefix}/lib/kdump/kexec-crypt-setup.sh
%ifnarch s390x
install -m 755 %{SOURCE28} $RPM_BUILD_ROOT%{_udevrulesdir}/../kdump-udev-throttler
%endif
--
2.30.2