summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
authorAntonio Russo <[email protected]>2019-06-02 08:57:10 -0400
committerBrian Behlendorf <[email protected]>2019-07-15 16:31:47 -0700
commitf88d069cbbbdff9a67a9be523cfb470cef707e07 (patch)
tree217fbde73bf8b3f58dcc3d76e68ff3a4c97ec1fb /etc
parent6993e012025c68e4ce0657f84fb47fe96c436735 (diff)
systemd encryption key support
Modify zfs-mount-generator to produce a dependency on new zfs-import-key-*.service units, dynamically created at boot to call zfs load-key for the encryption root, before attempting to mount any encrypted datasets. These units are created by zfs-mount-generator, and RequiresMountsFor on the keyfile, if present, or call systemd-ask-password if a passphrase is requested. This patch includes suggestions from @Fabian-Gruenbichler, @ryanjaeb and @rlaager, as well an adaptation of @rlaager's script to retry on incorrect password entry. Reviewed-by: Richard Laager <[email protected]> Reviewed-by: Fabian Grünbichler <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Antonio Russo <[email protected]> Closes #8750 Closes #8848
Diffstat (limited to 'etc')
-rwxr-xr-xetc/systemd/system-generators/zfs-mount-generator.in54
1 files changed, 52 insertions, 2 deletions
diff --git a/etc/systemd/system-generators/zfs-mount-generator.in b/etc/systemd/system-generators/zfs-mount-generator.in
index 5428eb25d..ae208c965 100755
--- a/etc/systemd/system-generators/zfs-mount-generator.in
+++ b/etc/systemd/system-generators/zfs-mount-generator.in
@@ -71,6 +71,8 @@ process_line() {
p_readonly="${8}"
p_setuid="${9}"
p_nbmand="${10}"
+ p_encroot="${11}"
+ p_keyloc="${12}"
# Check for canmount=off .
if [ "${p_canmount}" = "off" ] ; then
@@ -168,6 +170,54 @@ process_line() {
"${dataset}" >/dev/kmsg
fi
+ # Minimal pre-requisites to mount a ZFS dataset
+ wants="zfs-import.target"
+ if [ -n "${p_encroot}" ] &&
+ [ "${p_encroot}" != "-" ] ; then
+ keyloadunit="zfs-load-key-$(systemd-escape "${p_encroot}").service"
+ if [ "${p_encroot}" = "${dataset}" ] ; then
+ pathdep=""
+ if [ "${p_keyloc%%://*}" = "file" ] ; then
+ pathdep="RequiresMountsFor='${p_keyloc#file://}'"
+ keyloadcmd="@sbindir@/zfs load-key '${dataset}'"
+ elif [ "${p_keyloc}" = "prompt" ] ; then
+ keyloadcmd="sh -c 'set -eu;"\
+"count=0;"\
+"while [ \$\$count -lt 3 ];do"\
+" systemd-ask-password --id=\"zfs:${dataset}\""\
+" \"Enter passphrase for ${dataset}:\"|"\
+" @sbindir@/zfs load-key \"${dataset}\" && exit 0;"\
+" count=\$\$((count + 1));"\
+"done;"\
+"exit 1'"
+ else
+ printf 'zfs-mount-generator: (%s) invalid keylocation\n' \
+ "${dataset}" >/dev/kmsg
+ fi
+ cat > "${dest_norm}/${keyloadunit}" << EOF
+# Automatically generated by zfs-mount-generator
+
+[Unit]
+Description=Load ZFS key for ${dataset}
+SourcePath=${cachefile}
+Documentation=man:zfs-mount-generator(8)
+DefaultDependencies=no
+Wants=${wants}
+After=${wants}
+${pathdep}
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=${keyloadcmd}
+ExecStop=@sbindir@/zfs unload-key '${dataset}'
+EOF
+ fi
+ # Update the dependencies for the mount file to require the
+ # key-loading unit.
+ wants="${wants},${keyloadunit}"
+ fi
+
# If the mountpoint has already been created, give it precedence.
if [ -e "${dest_norm}/${mountfile}" ] ; then
printf 'zfs-mount-generator: %s already exists\n' "${mountfile}" \
@@ -183,8 +233,8 @@ process_line() {
SourcePath=${cachefile}
Documentation=man:zfs-mount-generator(8)
Before=local-fs.target zfs-mount.service
-After=zfs-import.target
-Wants=zfs-import.target
+After=${wants}
+Wants=${wants}
[Mount]
Where=${p_mountpoint}