Enable booting from nested encrypted datasets
- enable booting from nested encrypted datasets - fix plymouth boot splash passphrase entry - optimize unlock process Co-authored-by: Kash Pande <kash@tripleback.net> Co-authored-by: Matthew Thode <mthode@mthode.org> Signed-off-by: Kash Pande <kash@tripleback.net> Signed-off-by: Matthew Thode <mthode@mthode.org> Closes #7214
This commit is contained in:
parent
bf95a000c4
commit
7280d58197
|
@ -59,28 +59,13 @@ if import_pool "${ZFS_POOL}" ; then
|
||||||
# Load keys if we can or if we need to
|
# Load keys if we can or if we need to
|
||||||
if [ $(zpool list -H -o feature@encryption $(echo "${ZFS_POOL}" | awk -F\/ '{print $1}')) == 'active' ]; then
|
if [ $(zpool list -H -o feature@encryption $(echo "${ZFS_POOL}" | awk -F\/ '{print $1}')) == 'active' ]; then
|
||||||
# if the root dataset has encryption enabled
|
# if the root dataset has encryption enabled
|
||||||
if $(zfs list -H -o encryption "${ZFS_DATASET}" | grep -q -v off); then
|
ENCRYPTIONROOT=$(zfs get -H -o value encryptionroot ${ZFS_DATASET})
|
||||||
# figure out where the root dataset has its key, the keylocation should not be none
|
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
|
||||||
while true; do
|
|
||||||
if [[ $(zfs list -H -o keylocation "${ZFS_DATASET}") == 'none' ]]; then
|
|
||||||
ZFS_DATASET=$(echo -n "${ZFS_DATASET}" | awk 'BEGIN{FS=OFS="/"}{NF--; print}')
|
|
||||||
if [[ "${ZFS_DATASET}" == '' ]]; then
|
|
||||||
rootok=0
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
rootok=1
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
[[ "${rootok}" -eq 0 ]]&& return 1
|
|
||||||
# decrypt them
|
# decrypt them
|
||||||
TRY_COUNT=5
|
ask_for_password \
|
||||||
while [ $TRY_COUNT != 0 ]; do
|
--tries 5 \
|
||||||
zfs load-key "${ZFS_DATASET}"
|
--prompt "Encrypted ZFS password for ${ENCRYPTIONROOT}: " \
|
||||||
[ $? == 0 ] && break
|
--cmd "zfs load-key ${ENCRYPTIONROOT}"
|
||||||
((TRY_COUNT-=1))
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# Let us tell the initrd to run on shutdown.
|
# Let us tell the initrd to run on shutdown.
|
||||||
|
|
|
@ -103,3 +103,75 @@ export_all() {
|
||||||
|
|
||||||
return ${ret}
|
return ${ret}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ask_for_password
|
||||||
|
#
|
||||||
|
# Wraps around plymouth ask-for-password and adds fallback to tty password ask
|
||||||
|
# if plymouth is not present.
|
||||||
|
#
|
||||||
|
# --cmd command
|
||||||
|
# Command to execute. Required.
|
||||||
|
# --prompt prompt
|
||||||
|
# Password prompt. Note that function already adds ':' at the end.
|
||||||
|
# Recommended.
|
||||||
|
# --tries n
|
||||||
|
# How many times repeat command on its failure. Default is 3.
|
||||||
|
# --ply-[cmd|prompt|tries]
|
||||||
|
# Command/prompt/tries specific for plymouth password ask only.
|
||||||
|
# --tty-[cmd|prompt|tries]
|
||||||
|
# Command/prompt/tries specific for tty password ask only.
|
||||||
|
# --tty-echo-off
|
||||||
|
# Turn off input echo before tty command is executed and turn on after.
|
||||||
|
# It's useful when password is read from stdin.
|
||||||
|
ask_for_password() {
|
||||||
|
local cmd; local prompt; local tries=3
|
||||||
|
local ply_cmd; local ply_prompt; local ply_tries=3
|
||||||
|
local tty_cmd; local tty_prompt; local tty_tries=3
|
||||||
|
local ret
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--cmd) ply_cmd="$2"; tty_cmd="$2"; shift;;
|
||||||
|
--ply-cmd) ply_cmd="$2"; shift;;
|
||||||
|
--tty-cmd) tty_cmd="$2"; shift;;
|
||||||
|
--prompt) ply_prompt="$2"; tty_prompt="$2"; shift;;
|
||||||
|
--ply-prompt) ply_prompt="$2"; shift;;
|
||||||
|
--tty-prompt) tty_prompt="$2"; shift;;
|
||||||
|
--tries) ply_tries="$2"; tty_tries="$2"; shift;;
|
||||||
|
--ply-tries) ply_tries="$2"; shift;;
|
||||||
|
--tty-tries) tty_tries="$2"; shift;;
|
||||||
|
--tty-echo-off) tty_echo_off=yes;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
{ flock -s 9;
|
||||||
|
# Prompt for password with plymouth, if installed and running.
|
||||||
|
if type plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
|
||||||
|
plymouth ask-for-password \
|
||||||
|
--prompt "$ply_prompt" --number-of-tries=$ply_tries \
|
||||||
|
--command="$ply_cmd"
|
||||||
|
ret=$?
|
||||||
|
else
|
||||||
|
if [ "$tty_echo_off" = yes ]; then
|
||||||
|
stty_orig="$(stty -g)"
|
||||||
|
stty -echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
local i=1
|
||||||
|
while [ $i -le $tty_tries ]; do
|
||||||
|
[ -n "$tty_prompt" ] && \
|
||||||
|
printf "$tty_prompt [$i/$tty_tries]:" >&2
|
||||||
|
eval "$tty_cmd" && ret=0 && break
|
||||||
|
ret=$?
|
||||||
|
i=$(($i+1))
|
||||||
|
[ -n "$tty_prompt" ] && printf '\n' >&2
|
||||||
|
done
|
||||||
|
|
||||||
|
[ "$tty_echo_off" = yes ] && stty $stty_orig
|
||||||
|
fi
|
||||||
|
} 9>/.console_lock
|
||||||
|
|
||||||
|
[ $ret -ne 0 ] && echo "Wrong password" >&2
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
|
@ -33,21 +33,13 @@ fi
|
||||||
|
|
||||||
# if pool encryption is active and the zfs command understands '-o encryption'
|
# if pool encryption is active and the zfs command understands '-o encryption'
|
||||||
if [[ $(zpool list -H -o feature@encryption $(echo "${root}" | awk -F\/ '{print $1}')) == 'active' ]]; then
|
if [[ $(zpool list -H -o feature@encryption $(echo "${root}" | awk -F\/ '{print $1}')) == 'active' ]]; then
|
||||||
# check if root dataset has encryption enabled
|
# if the root dataset has encryption enabled
|
||||||
if $(zfs list -H -o encryption "${root}" | grep -q -v off); then
|
ENCRYPTIONROOT=$(zfs get -H -o value encryptionroot ${ZFS_DATASET})
|
||||||
# figure out where the root dataset has its key, the keylocation should not be none
|
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
|
||||||
while true; do
|
|
||||||
if [[ $(zfs list -H -o keylocation "${root}") == 'none' ]]; then
|
|
||||||
root=$(echo -n "${root}" | awk 'BEGIN{FS=OFS="/"}{NF--; print}')
|
|
||||||
[[ "${root}" == '' ]] && exit 1
|
|
||||||
else
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# decrypt them
|
# decrypt them
|
||||||
TRY_COUNT=5
|
TRY_COUNT=5
|
||||||
while [ $TRY_COUNT != 0 ]; do
|
while [ $TRY_COUNT != 0 ]; do
|
||||||
zfs load-key "$root" <<< $(systemd-ask-password "Encrypted ZFS password for ${root}: ")
|
zfs load-key "${ENCRYPTIONROOT}" <<< $(systemd-ask-password "Encrypted ZFS password for ${root}: ")
|
||||||
[[ $? == 0 ]] && break
|
[[ $? == 0 ]] && break
|
||||||
((TRY_COUNT-=1))
|
((TRY_COUNT-=1))
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in New Issue