clevis/SOURCES/Use-one-clevis-luks-askpass...

238 lines
7.9 KiB
Diff

From 523f1361c759d5af0952b0137d4dbd51be1e7b3d Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Sun, 22 Dec 2019 17:01:09 -0500
Subject: [PATCH] Use one clevis-luks-askpass per device
This should improve the reliability of the boot unlocking, especially
when unlocking multiple devices upon boot.
It also greatly simplifies the configuration, as three is no need to
enable any systemd units manually nor add _netdev to either fstab or
crypttab.
---
src/luks/clevis-luks-unlockers.7.adoc | 16 +++----------
src/luks/systemd/clevis-luks-askpass | 7 +++++-
src/luks/systemd/clevis-luks-askpass.path | 10 --------
.../systemd/clevis-luks-askpass.service.in | 8 -------
src/luks/systemd/clevis-luks-askpass@.path | 12 ++++++++++
.../systemd/clevis-luks-askpass@.service.in | 9 +++++++
src/luks/systemd/dracut/module-setup.sh.in | 24 +++++++++++++++++++
src/luks/systemd/meson.build | 8 +++----
8 files changed, 58 insertions(+), 36 deletions(-)
delete mode 100644 src/luks/systemd/clevis-luks-askpass.path
delete mode 100644 src/luks/systemd/clevis-luks-askpass.service.in
create mode 100644 src/luks/systemd/clevis-luks-askpass@.path
create mode 100644 src/luks/systemd/clevis-luks-askpass@.service.in
diff --git a/src/luks/clevis-luks-unlockers.7.adoc b/src/luks/clevis-luks-unlockers.7.adoc
index 161b73a..e8d47ba 100644
--- a/src/luks/clevis-luks-unlockers.7.adoc
+++ b/src/luks/clevis-luks-unlockers.7.adoc
@@ -26,7 +26,7 @@ You can unlock a LUKS volume manually using the following command:
For more information, see link:clevis-luks-unlock.1.adoc[*clevis-luks-unlock*(1)].
-== EARLY BOOT UNLOCKING
+== BOOT UNLOCKING
If Clevis integration does not already ship in your initramfs, you may need to
rebuild your initramfs with this command:
@@ -34,23 +34,13 @@ rebuild your initramfs with this command:
$ sudo dracut -f
Once Clevis is integrated into your initramfs, a simple reboot should unlock
-your root volume. Note, however, that early boot integration only works for the
-root volume. Non-root volumes should use the late boot unlocker.
+your clevis-bound volumes. Root volumes will be unlocked in early-boot, while the
+remaining volumes will be unlocked after dracut switch-root.
Dracut will bring up your network using DHCP by default. If you need to specify
additional network parameters, such as static IP configuration, please consult
the dracut documentation.
-== LATE BOOT UNLOCKING
-
-You can enable late boot unlocking by executing the following command:
-
- $ sudo systemctl enable clevis-luks-askpass.path
-
-After a reboot, Clevis will attempt to unlock all *_netdev* devices listed in
-*/etc/crypttab* when systemd prompts for their passwords. This implies that
-systemd support for *_netdev* is required.
-
== DESKTOP UNLOCKING
When the udisks2 unlocker is installed, your GNOME desktop session should
diff --git a/src/luks/systemd/clevis-luks-askpass b/src/luks/systemd/clevis-luks-askpass
index b01d93a..feebb1a 100755
--- a/src/luks/systemd/clevis-luks-askpass
+++ b/src/luks/systemd/clevis-luks-askpass
@@ -24,15 +24,17 @@ UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
shopt -s nullglob
path=/run/systemd/ask-password
-while getopts ":lp:" o; do
+while getopts ":lpu:" o; do
case "$o" in
l) loop=true;;
p) path=$OPTARG;;
+ u) device_uuid=$OPTARG;;
esac
done
while true; do
todo=0
+ [ -n "${device_uuid}" ] && todo=1 && loop=true
for question in $path/ask.*; do
metadata=false
@@ -48,6 +50,8 @@ while true; do
done < "$question"
[ -z "$d" -o -z "$s" ] && continue
+ [[ -n "${device_uuid}" ]] && [[ "${d}" != *"${device_uuid}"* ]] \
+ && continue
if cryptsetup isLuks --type luks1 "$d"; then
# If the device is not initialized, sliently skip it.
@@ -79,6 +83,7 @@ while true; do
done
fi
+ [ -n "${device_uuid}" ] && [ "${unlocked}" == true ] && todo=0 && break
[ $metadata == true ] || continue
[ $unlocked == true ] && continue
todo=$((todo + 1))
diff --git a/src/luks/systemd/clevis-luks-askpass.path b/src/luks/systemd/clevis-luks-askpass.path
deleted file mode 100644
index a4d01ba..0000000
--- a/src/luks/systemd/clevis-luks-askpass.path
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Clevis systemd-ask-password Watcher
-Before=remote-fs-pre.target
-Wants=remote-fs-pre.target
-
-[Path]
-PathChanged=/run/systemd/ask-password
-
-[Install]
-WantedBy=remote-fs.target
diff --git a/src/luks/systemd/clevis-luks-askpass.service.in b/src/luks/systemd/clevis-luks-askpass.service.in
deleted file mode 100644
index 2c6bbed..0000000
--- a/src/luks/systemd/clevis-luks-askpass.service.in
+++ /dev/null
@@ -1,8 +0,0 @@
-[Unit]
-Description=Clevis LUKS systemd-ask-password Responder
-Requires=network-online.target
-After=network-online.target
-
-[Service]
-Type=oneshot
-ExecStart=@libexecdir@/clevis-luks-askpass -l
diff --git a/src/luks/systemd/clevis-luks-askpass@.path b/src/luks/systemd/clevis-luks-askpass@.path
new file mode 100644
index 0000000..3f23665
--- /dev/null
+++ b/src/luks/systemd/clevis-luks-askpass@.path
@@ -0,0 +1,12 @@
+[Unit]
+Description=Clevis systemd-ask-password Watcher for %i
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=basic.target shutdown.target
+
+[Path]
+DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
+
+[Install]
+WantedBy=basic.target
diff --git a/src/luks/systemd/clevis-luks-askpass@.service.in b/src/luks/systemd/clevis-luks-askpass@.service.in
new file mode 100644
index 0000000..cd26eb2
--- /dev/null
+++ b/src/luks/systemd/clevis-luks-askpass@.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=Clevis LUKS systemd-ask-password Responder for luks-%i
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+ExecStart=@libexecdir@/clevis-luks-askpass -u %i
diff --git a/src/luks/systemd/dracut/module-setup.sh.in b/src/luks/systemd/dracut/module-setup.sh.in
index 841f7a8..1877715 100755
--- a/src/luks/systemd/dracut/module-setup.sh.in
+++ b/src/luks/systemd/dracut/module-setup.sh.in
@@ -29,6 +29,29 @@ is_bound_to_tang() {
return 1
}
+configure_passwd_watchers() {
+ if ! command -v systemctl >/dev/null; then
+ return 1
+ fi
+
+ local proc_cmdline
+ proc_cmdline=$(</proc/cmdline)
+
+ local luks_uuid
+ local cfg
+ for dev in $(lsblk -p -n -s -r \
+ | awk '$6 == "crypt" { getline; print $1 }' | sort -u); do
+ luks_uuid=$(cryptsetup luksUUID "${dev}")
+ [[ "${proc_cmdline}" == *"rd.luks.uuid=luks-${luks_uuid}"* ]] && continue
+
+ if cfg=$(clevis luks list -d "${dev}" 2>/dev/null); then
+ local action=enable
+ [ -z "${cfg}" ] && action=disable
+ systemctl "${action}" "clevis-luks-askpass@${luks_uuid}.path" 2>/dev/null
+ fi
+ done
+}
+
depends() {
local depends="crypt systemd"
if is_bound_to_tang; then
@@ -84,6 +107,7 @@ install() {
inst_libdir_file "libtss2-tcti-device.so*"
fi
+ configure_passwd_watchers
dracut_need_initqueue
}
diff --git a/src/luks/systemd/meson.build b/src/luks/systemd/meson.build
index 108e9d8..334e84c 100644
--- a/src/luks/systemd/meson.build
+++ b/src/luks/systemd/meson.build
@@ -6,14 +6,14 @@ if systemd.found()
unitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
configure_file(
- input: 'clevis-luks-askpass.service.in',
- output: 'clevis-luks-askpass.service',
+ input: 'clevis-luks-askpass@.service.in',
+ output: 'clevis-luks-askpass@.service',
install_dir: unitdir,
configuration: data,
)
- install_data('clevis-luks-askpass.path', install_dir: unitdir)
+ install_data('clevis-luks-askpass@.path', install_dir: unitdir)
install_data('clevis-luks-askpass', install_dir: libexecdir)
else
warning('Will not install systemd support due to missing dependencies!')
-endif
\ No newline at end of file
+endif
--
2.18.1