Skip to content

Commit

Permalink
systemd encryption key support
Browse files Browse the repository at this point in the history
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 openzfs#8750
Closes openzfs#8848
  • Loading branch information
aerusso authored and tonyhutter committed Sep 16, 2019
1 parent ef84dce commit 54314ca
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
4 changes: 2 additions & 2 deletions cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
# Only act if one of the tracked properties is altered.
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
canmount|mountpoint|atime|relatime|devices|exec| \
readonly|setuid|nbmand) ;;
readonly|setuid|nbmand|encroot|keylocation) ;;
*) exit 0 ;;
esac
;;
Expand All @@ -62,7 +62,7 @@ zed_lock zfs-list
trap abort_alter EXIT

PROPS="name,mountpoint,canmount,atime,relatime,devices,exec,readonly"
PROPS="${PROPS},setuid,nbmand"
PROPS="${PROPS},setuid,nbmand,encroot,keylocation"

"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"

Expand Down
54 changes: 52 additions & 2 deletions etc/systemd/system-generators/zfs-mount-generator.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}" \
Expand All @@ -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}
Expand Down
2 changes: 1 addition & 1 deletion man/man8/zfs-mount-generator.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ information on ZFS mountpoints must be stored separately. The output
of the command
.PP
.RS 4
zfs list -H -o name,mountpoint,canmount,atime,relatime,devices,exec,readonly,setuid,nbmand
zfs list -H -o name,mountpoint,canmount,atime,relatime,devices,exec,readonly,setuid,nbmand,encroot,keylocation
.RE
.PP
for datasets that should be mounted by systemd, should be kept
Expand Down

0 comments on commit 54314ca

Please sign in to comment.