From 0d55d48f0fb4ca47bce2a45fdd9102174d832b18 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 23 Jun 2020 06:08:40 -0400 Subject: [PATCH 1/4] ZFS: Ask for stage 2 encryption passwords using systemd-ask-password --- nixos/modules/tasks/filesystems/zfs.nix | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 71eed4d6f1a..3cdfcebe1b0 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -490,7 +490,11 @@ in description = "Import ZFS pool \"${pool}\""; # we need systemd-udev-settle until https://github.com/zfsonlinux/zfs/pull/4943 is merged requires = [ "systemd-udev-settle.service" ]; - after = [ "systemd-udev-settle.service" "systemd-modules-load.service" ]; + after = [ + "systemd-udev-settle.service" + "systemd-modules-load.service" + "systemd-ask-password-console.service" + ]; wantedBy = (getPoolMounts pool) ++ [ "local-fs.target" ]; before = (getPoolMounts pool) ++ [ "local-fs.target" ]; unitConfig = { @@ -515,7 +519,20 @@ in done poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. if poolImported "${pool}"; then - ${optionalString cfgZfs.requestEncryptionCredentials "\"${packages.zfsUser}/sbin/zfs\" load-key -r \"${pool}\""} + ${optionalString cfgZfs.requestEncryptionCredentials '' + ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while read ds kl; do + case "$kl" in + none ) + ;; + prompt ) + ${config.systemd.package}/bin/systemd-ask-password "Enter key for $ds:" | ${packages.zfsUser}/sbin/zfs load-key "$ds" + ;; + * ) + ${packages.zfsUser}/sbin/zfs load-key "$ds" + ;; + esac + done + ''} echo "Successfully imported ${pool}" else exit 1 From c128229dcea2936080974f5d00341c59deab69fa Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 23 Jun 2020 06:09:29 -0400 Subject: [PATCH 2/4] plymouth: Enable systemd-ask-password-plymouth --- nixos/modules/system/boot/plymouth.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nixos/modules/system/boot/plymouth.nix b/nixos/modules/system/boot/plymouth.nix index 23fce22366d..55e5b07ed61 100644 --- a/nixos/modules/system/boot/plymouth.nix +++ b/nixos/modules/system/boot/plymouth.nix @@ -102,6 +102,8 @@ in systemd.services.plymouth-poweroff.wantedBy = [ "poweroff.target" ]; systemd.services.plymouth-reboot.wantedBy = [ "reboot.target" ]; systemd.services.plymouth-read-write.wantedBy = [ "sysinit.target" ]; + systemd.services.systemd-ask-password-plymouth.wantedBy = ["multi-user.target"]; + systemd.paths.systemd-ask-password-plymouth.wantedBy = ["multi-user.target"]; boot.initrd.extraUtilsCommands = '' copy_bin_and_libs ${pkgs.plymouth}/bin/plymouthd @@ -146,6 +148,7 @@ in # We use `mkAfter` to ensure that LUKS password prompt would be shown earlier than the splash screen. boot.initrd.preLVMCommands = mkAfter '' mkdir -p /etc/plymouth + mkdir -p /run/plymouth ln -s ${configFile} /etc/plymouth/plymouthd.conf ln -s $extraUtils/share/plymouth/plymouthd.defaults /etc/plymouth/plymouthd.defaults ln -s $extraUtils/share/plymouth/logo.png /etc/plymouth/logo.png From 05f8cba1b63629737749d8c6f34c6456fb3b105d Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 30 Jun 2020 21:35:35 -0400 Subject: [PATCH 3/4] ZFS: Pipe /dev/null into the stage 2 load-key script Just in case something reads stdin, so that `while read ds kl` doesn't miss anything --- nixos/modules/tasks/filesystems/zfs.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 3cdfcebe1b0..0d2f624a455 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -521,7 +521,7 @@ in if poolImported "${pool}"; then ${optionalString cfgZfs.requestEncryptionCredentials '' ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while read ds kl; do - case "$kl" in + (case "$kl" in none ) ;; prompt ) @@ -530,7 +530,7 @@ in * ) ${packages.zfsUser}/sbin/zfs load-key "$ds" ;; - esac + esac) < /dev/null # To protect while read ds kl in case anything reads stdin done ''} echo "Successfully imported ${pool}" From e2f1594695c3795c09f40ed7556af2bbc49b8fdc Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Thu, 2 Jul 2020 13:35:05 -0400 Subject: [PATCH 4/4] ZFS: Set IFS=$'\t' for the read command in stage 2 load-key Co-authored-by: Graham Christensen --- nixos/modules/tasks/filesystems/zfs.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index 0d2f624a455..cb8947fd986 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -520,7 +520,7 @@ in poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. if poolImported "${pool}"; then ${optionalString cfgZfs.requestEncryptionCredentials '' - ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while read ds kl; do + ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do (case "$kl" in none ) ;;