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 <rlaager@wiktel.com> Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Antonio Russo <antonio.e.russo@gmail.com> Closes #8750 Closes #8848
This commit is contained in:
parent
6993e01202
commit
f88d069cbb
|
@ -47,7 +47,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
|
||||||
# Only act if one of the tracked properties is altered.
|
# Only act if one of the tracked properties is altered.
|
||||||
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
|
case "${ZEVENT_HISTORY_INTERNAL_STR%%=*}" in
|
||||||
canmount|mountpoint|atime|relatime|devices|exec| \
|
canmount|mountpoint|atime|relatime|devices|exec| \
|
||||||
readonly|setuid|nbmand) ;;
|
readonly|setuid|nbmand|encroot|keylocation) ;;
|
||||||
*) exit 0 ;;
|
*) exit 0 ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
@ -62,7 +62,7 @@ zed_lock zfs-list
|
||||||
trap abort_alter EXIT
|
trap abort_alter EXIT
|
||||||
|
|
||||||
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec,readonly"
|
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}"
|
"${ZFS}" list -H -t filesystem -o $PROPS -r "${ZEVENT_POOL}" > "${FSLIST_TMP}"
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ process_line() {
|
||||||
p_readonly="${8}"
|
p_readonly="${8}"
|
||||||
p_setuid="${9}"
|
p_setuid="${9}"
|
||||||
p_nbmand="${10}"
|
p_nbmand="${10}"
|
||||||
|
p_encroot="${11}"
|
||||||
|
p_keyloc="${12}"
|
||||||
|
|
||||||
# Check for canmount=off .
|
# Check for canmount=off .
|
||||||
if [ "${p_canmount}" = "off" ] ; then
|
if [ "${p_canmount}" = "off" ] ; then
|
||||||
|
@ -168,6 +170,54 @@ process_line() {
|
||||||
"${dataset}" >/dev/kmsg
|
"${dataset}" >/dev/kmsg
|
||||||
fi
|
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 the mountpoint has already been created, give it precedence.
|
||||||
if [ -e "${dest_norm}/${mountfile}" ] ; then
|
if [ -e "${dest_norm}/${mountfile}" ] ; then
|
||||||
printf 'zfs-mount-generator: %s already exists\n' "${mountfile}" \
|
printf 'zfs-mount-generator: %s already exists\n' "${mountfile}" \
|
||||||
|
@ -183,8 +233,8 @@ process_line() {
|
||||||
SourcePath=${cachefile}
|
SourcePath=${cachefile}
|
||||||
Documentation=man:zfs-mount-generator(8)
|
Documentation=man:zfs-mount-generator(8)
|
||||||
Before=local-fs.target zfs-mount.service
|
Before=local-fs.target zfs-mount.service
|
||||||
After=zfs-import.target
|
After=${wants}
|
||||||
Wants=zfs-import.target
|
Wants=${wants}
|
||||||
|
|
||||||
[Mount]
|
[Mount]
|
||||||
Where=${p_mountpoint}
|
Where=${p_mountpoint}
|
||||||
|
|
|
@ -26,7 +26,7 @@ information on ZFS mountpoints must be stored separately. The output
|
||||||
of the command
|
of the command
|
||||||
.PP
|
.PP
|
||||||
.RS 4
|
.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
|
.RE
|
||||||
.PP
|
.PP
|
||||||
for datasets that should be mounted by systemd, should be kept
|
for datasets that should be mounted by systemd, should be kept
|
||||||
|
|
Loading…
Reference in New Issue