diff options
Diffstat (limited to '')
-rw-r--r-- | misc/dracut_90reencrypt/README | 40 | ||||
-rwxr-xr-x | misc/dracut_90reencrypt/check.old | 5 | ||||
-rwxr-xr-x | misc/dracut_90reencrypt/install.old | 6 | ||||
-rwxr-xr-x | misc/dracut_90reencrypt/module-setup.sh | 32 | ||||
-rwxr-xr-x | misc/dracut_90reencrypt/parse-reencrypt.sh | 38 | ||||
-rwxr-xr-x | misc/dracut_90reencrypt/reencrypt-verbose.sh | 6 | ||||
-rwxr-xr-x | misc/dracut_90reencrypt/reencrypt.sh | 84 |
7 files changed, 211 insertions, 0 deletions
diff --git a/misc/dracut_90reencrypt/README b/misc/dracut_90reencrypt/README new file mode 100644 index 0000000..0672949 --- /dev/null +++ b/misc/dracut_90reencrypt/README @@ -0,0 +1,40 @@ +Example of simple dracut module for reencryption of system +LUKS drive on-the-fly. + +Install in /usr/[share|lib]/dracut/modules.d/90reencrypt, then +build special initramfs "with dracut -a reencrypt -o crypt". +Reencrypt module doesn't work (has a conflict) with crypt module as +of now. After successful reencryption reboot using original initramfs. + +Dracut then recognize argument rd.luks.reencrypt=name:size, +e.g. rd.luks.reencrypt=sda2:52G means only 52G of device +will be reencrypted (default is whole device). +(Name is kernel name of device.) + +If there's more than single active keyslot in the target luks device +you're required to select one keyslot explicitly for reencryption via +rd.luks.reencrypt_keyslot=<keyslot_number> option. Bear in mind that +if you use this option, all other keyslots will get deactivated in the +process. + +Another argument, rd.luks.reencrypt_key=/dev/sda:/path/to/keyfile +can be used to read password for specific keyslot from device containing +filesystem with a keyfile (file with a password). If you omit reencrypt_key +argument, reencryption would work only in case a LUKS container has +exactly one keyslot activated. + +Arguments rd.luks.reencrypt_keyslot and rd.luks.reencrypt_key are not +mandatory. + +Note that reencryption context is stored in ramdisk, any +fail can mean complete lost of data! + +Copyright (C) 2012 Milan Broz <gmazyland@gmail.com> + +This copyrighted material is made available to anyone wishing to use, +modify, copy, or redistribute it subject to the terms and conditions +of the GNU General Public License v.2. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/misc/dracut_90reencrypt/check.old b/misc/dracut_90reencrypt/check.old new file mode 100755 index 0000000..53010b3 --- /dev/null +++ b/misc/dracut_90reencrypt/check.old @@ -0,0 +1,5 @@ +#!/bin/bash + +which cryptsetup-reencrypt >/dev/null 2>&1 || exit 1 + +exit 0 diff --git a/misc/dracut_90reencrypt/install.old b/misc/dracut_90reencrypt/install.old new file mode 100755 index 0000000..6e0523b --- /dev/null +++ b/misc/dracut_90reencrypt/install.old @@ -0,0 +1,6 @@ +#!/bin/bash + +inst cryptsetup-reencrypt + +inst_hook cmdline 30 "$moddir/parse-reencrypt.sh" +inst "$moddir"/reencrypt.sh /sbin/reencrypt diff --git a/misc/dracut_90reencrypt/module-setup.sh b/misc/dracut_90reencrypt/module-setup.sh new file mode 100755 index 0000000..fcd7c92 --- /dev/null +++ b/misc/dracut_90reencrypt/module-setup.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +check() { + [ -x /sbin/cryptsetup-reencrypt ] || return 1 + return 255 +} + +depends() { + echo dm rootfs-block +} + +installkernel() { + # requires hostonly='' override so that loop module is pulled in initramfs + # even if not loaded in actual kernel. dracut bug? + hostonly='' instmods dm_crypt =crypto loop +} + +install() { + if dracut_module_included crypt; then + derror "'reencrypt' can't be installed together with 'crypt'." + derror "Add '-o crypt' option to install reencrypt module." + return 1 + fi + + dracut_install cryptsetup-reencrypt + + # moddir variable is assigned in dracut general shell lib + # shellcheck disable=SC2154 + inst_hook cmdline 30 "$moddir/parse-reencrypt.sh" + inst_simple "$moddir"/reencrypt.sh /sbin/reencrypt + inst_simple "$moddir"/reencrypt-verbose.sh /sbin/cryptsetup-reencrypt-verbose +} diff --git a/misc/dracut_90reencrypt/parse-reencrypt.sh b/misc/dracut_90reencrypt/parse-reencrypt.sh new file mode 100755 index 0000000..5fec191 --- /dev/null +++ b/misc/dracut_90reencrypt/parse-reencrypt.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +REENC=$(getargs rd.luks.reencrypt=) +# shellcheck disable=SC2086 +REENC_DEV=$(echo $REENC | sed 's/:.*//') +# shellcheck disable=SC2086 +REENC_SIZE=$(echo $REENC | sed -n 's/.*://p') + +REENC_KEY=$(getargs rd.luks.reencrypt_key=) +if [ -z "$REENC_KEY" ] ; then + REENC_KEY=none +fi + +REENC_SLOT=$(getargs rd.luks.reencrypt_keyslot=) +if [ -z "$REENC_SLOT" ] ; then + REENC_SLOT=any +fi + +# shellcheck disable=SC2086 +# shellcheck disable=SC1004 +# shellcheck disable=SC2016 +if [ -n "$REENC_DEV" ] ; then +{ + printf 'SUBSYSTEM!="block", GOTO="reenc_end"\n' + printf 'ACTION!="add|change", GOTO="reenc_end"\n' + printf 'KERNEL=="%s", ' $REENC_DEV + printf 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue \ + --unique --onetime --settled --name crypt-reencrypt-%%k \ + /sbin/reencrypt $env{DEVNAME} %s"\n' "$REENC_KEY $REENC_SLOT $REENC_SIZE" + + printf 'ENV{ID_FS_UUID}=="*%s*", ' $REENC_DEV + printf 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="/sbin/initqueue \ + --unique --onetime --settled --name crypt-reencrypt-%%k \ + /sbin/reencrypt $env{DEVNAME} %s"\n' "$REENC_KEY $REENC_SLOT $REENC_SIZE" + printf 'LABEL="reenc_end"\n' +} > /etc/udev/rules.d/69-reencryption.rules + initqueue --unique --finished --name crypt-reencrypt-finished-${REENC_DEV} [ -e /tmp/reencrypted ] +fi diff --git a/misc/dracut_90reencrypt/reencrypt-verbose.sh b/misc/dracut_90reencrypt/reencrypt-verbose.sh new file mode 100755 index 0000000..109ce6e --- /dev/null +++ b/misc/dracut_90reencrypt/reencrypt-verbose.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +# Route stdout to stderr in initrd. Otherwise output is invisible +# unless we run in debug mode. +# shellcheck disable=SC2068 +/sbin/cryptsetup-reencrypt $@ 1>&2 diff --git a/misc/dracut_90reencrypt/reencrypt.sh b/misc/dracut_90reencrypt/reencrypt.sh new file mode 100755 index 0000000..db09e64 --- /dev/null +++ b/misc/dracut_90reencrypt/reencrypt.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# $1=$device [$2=keyfile|none [$3=keyslot|any [$4=size]]] +# + +[ -d /sys/module/dm_crypt ] || modprobe dm_crypt + +[ -d /sys/module/loop ] || modprobe loop + +[ -f /tmp/reencrypted ] && exit 0 + +. /lib/dracut-lib.sh + +# if device name is /dev/dm-X, convert to /dev/mapper/name +if [ "${1##/dev/dm-}" != "$1" ]; then + device="/dev/mapper/$(dmsetup info -c --noheadings -o name "$1")" +else + device="$1" +fi + +PARAMS="$device -T 1 --use-fsync --progress-frequency 5 -B 32" +if [ "$3" != "any" ]; then + PARAMS="$PARAMS -S $3" +fi + +if [ -n "$4" ]; then + PARAMS="$PARAMS --device-size $4" +fi + +reenc_readkey() { + keypath="${1#*:}" + keydev="${1%%:*}" + + mntp="/tmp/reencrypted-mount-tmp" + mkdir "$mntp" + mount -r "$keydev" "$mntp" && cat "$mntp/$keypath" + umount "$mntp" + rm -r "$mntp" +} + +# shellcheck disable=SC2086 +# shellcheck disable=SC2164 +reenc_run() { + cwd=$(pwd) + _prompt="LUKS password for REENCRYPTING $device" + cd /tmp + udevadm settle + if [ "$1" = "none" ] ; then + if [ "$2" != "any" ]; then + _prompt="$_prompt, using keyslot $2" + fi + /bin/plymouth ask-for-password \ + --prompt "$_prompt" \ + --command="/sbin/cryptsetup-reencrypt-verbose $PARAMS" + else + info "REENCRYPT using key $1" + reenc_readkey "$1" | /sbin/cryptsetup-reencrypt-verbose -d - $PARAMS + fi + _ret=$? + cd $cwd +} + +info "REENCRYPT $device requested" +# flock against other interactive activities +# shellcheck disable=SC2086 +{ flock -s 9; + reenc_run $2 $3 +} 9>/.console_lock + +if [ $_ret -eq 0 ]; then + # do not ask again + # shellcheck disable=SC2188 + >> /tmp/reencrypted + warn "Reencryption of device $device has finished successfully. Use previous" + warn "initramfs image (without reencrypt module) to boot the system. When" + warn "you leave the emergency shell, the system will reboot." + + emergency_shell -n "(reboot)" + [ -x /usr/bin/systemctl ] && /usr/bin/systemctl reboot + [ -x /sbin/shutdown ] && /sbin/shutdown -r now +fi + +# panic the kernel otherwise +exit 1 |