summaryrefslogtreecommitdiffstats
path: root/misc/dracut_90reencrypt
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--misc/dracut_90reencrypt/README40
-rwxr-xr-xmisc/dracut_90reencrypt/check.old5
-rwxr-xr-xmisc/dracut_90reencrypt/install.old6
-rwxr-xr-xmisc/dracut_90reencrypt/module-setup.sh32
-rwxr-xr-xmisc/dracut_90reencrypt/parse-reencrypt.sh38
-rwxr-xr-xmisc/dracut_90reencrypt/reencrypt-verbose.sh6
-rwxr-xr-xmisc/dracut_90reencrypt/reencrypt.sh84
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