2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-02 15:36:05 +00:00

Add support for specifying tpm2 pcrs in the encryptboot attribute

This allows a user to opt into pcrs if they understand what they are doing.

Some PCRs are sensitive to firmware updates and some are sensitive to boot loader, kernel, boot config, or initramfs.  All of these are an opportunity for an unsuspecting update to remove access to the boot volume.  There are update processes that can be put into place to make this work,
but it is up to the OS update process to address that, and
OS update processes are likely not to address that at this time.
This commit is contained in:
Jarrod Johnson
2026-08-06 16:07:19 -04:00
parent e1839b6c6e
commit 94c1683663
7 changed files with 47 additions and 12 deletions
@@ -60,7 +60,7 @@ done
cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}')
LUKSPARTY=''
touch /tmp/addonpackages
if [ "$cryptboot" == "tpm2" ]; then
if [ "$cryptboot" == "tpm2" ] || [ "${cryptboot#tpm2:}" != "$cryptboot" ]; then
LUKSPARTY="--encrypted --passphrase=$(cat /etc/confluent/confluent.apikey)"
echo $cryptboot >> /tmp/cryptboot
fi
@@ -1,4 +1,16 @@
#!/bin/sh
cryptdisk=$(blkid -t TYPE="crypto_LUKS"|sed -e s/:.*//)
clevis luks bind -f -d $cryptdisk -k - tpm2 '{}' < /etc/confluent/confluent.apikey
pcrs=""
if [ -f /tmp/cryptboot ]; then
# syntax of /tmp/cryptboot is e.g. tpm2:pcrs=1,7
pcrs=$(sed -e 's/^tpm2:pcrs=//' /tmp/cryptboot)
fi
if [ -n "$pcrs" ]; then
clevispcrs=$(echo "$pcrs" | sed -e 's/,/, /g')
clevis luks bind -f -d $cryptdisk -k - tpm2 "{\"pcr_ids\":\"$clevispcrs\"}" < /etc/confluent/confluent.apikey
else
clevis luks bind -f -d $cryptdisk -k - tpm2 '{}' < /etc/confluent/confluent.apikey
fi
cryptsetup luksRemoveKey $cryptdisk < /etc/confluent/confluent.apikey
@@ -89,7 +89,8 @@ LUKSPARTY=''
touch /tmp/cryptpkglist
touch /tmp/pkglist
touch /tmp/addonpackages
if [ "$cryptboot" == "tpm2" ]; then
if [ "$cryptboot" == "tpm2" ] || [ "${cryptboot#tpm2:}" != "$cryptboot" ]; then
lukspass=$(python3 /opt/confluent/bin/apiclient /confluent-api/self/profileprivate/pending/luks.key 2> /dev/null)
if [ -z "$lukspass" ]; then
lukspass=$(python3 -c 'import os;import base64;print(base64.b64encode(os.urandom(66)).decode())')
@@ -1,11 +1,19 @@
#!/bin/sh
cryptdisk=$(blkid -t TYPE="crypto_LUKS"|sed -e s/:.*//)
pcrs=$(sed -n -e 's/.*tpm2:pcrs=\([0-9,]*\).*/\1/p' /tmp/cryptboot)
if [ -x /bin/systemd-cryptenroll ]; then
PASSWORD=$(cat /etc/confluent/luks.key) systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="" $cryptdisk
PASSWORD=$(cat /etc/confluent/luks.key) systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="$pcrs" $cryptdisk
sed -e 's/ discard/ tpm2-device=auto,discard/' -i /etc/crypttab
dracut -f
else
clevis luks bind -f -d $cryptdisk -k - tpm2 '{}' < /etc/confluent/luks.key
if [ -n "$pcrs" ]; then
clevispcrs=$(echo "$pcrs" | sed -e 's/,/, /g')
clevis luks bind -f -d $cryptdisk -k - tpm2 "{\"pcr_ids\":\"$clevispcrs\"}" < /etc/confluent/luks.key
else
clevis luks bind -f -d $cryptdisk -k - tpm2 "{}" < /etc/confluent/luks.key
fi
#cryptsetup luksRemoveKey $cryptdisk < /etc/confluent/confluent.apikey
fi
chmod 000 /etc/confluent/luks.key
@@ -112,7 +112,16 @@ if [ -f /etc/confluent_lukspass ]; then
chmod 000 /target/etc/confluent/luks.key
lukspass=$(cat /etc/confluent_lukspass)
chroot /target apt install libtss2-rc0
PASSWORD=$lukspass chroot /target systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="" $CRYPTTAB_SOURCE
tpm2pcrs=""
encryptboot=$(grep ^encryptboot: /target/etc/confluent/confluent.deploycfg | sed -e 's/^encryptboot://' -e 's/ //g')
case "$encryptboot" in
*pcrs=*)
tpm2pcrs=$(echo "$encryptboot" | sed -e 's/.*pcrs=//' -e 's/:.*//')
;;
esac
PASSWORD=$lukspass chroot /target systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="$tpm2pcrs" $CRYPTTAB_SOURCE
fetch_remote systemdecrypt
mv systemdecrypt /target/etc/initramfs-tools/scripts/local-top/systemdecrypt
fetch_remote systemdecrypt-hook
@@ -122,7 +122,7 @@ node = {
'Trusted Platform Module is available to decrypt the '
'volume. Note that versions earlier than 8.2 may malfunction '
'at boot time if this feature is attempted, depending on configuration.'),
'validvalues': ('tpm2', 'none', ''),
'validvalues': ('tpm2', 'tpm2:*', 'none', ''),
},
'deployment.apiarmed': {
'description': ('Indicates whether the node authentication token interface '
+10 -5
View File
@@ -19,6 +19,7 @@
# Things are defined here to 'encourage' developers to coordinate information
# format. This is also how different data formats are supported
import base64
from fnmatch import fnmatch
import os
import confluent.exceptions as exc
import confluent.config.configmanager as cfm
@@ -874,11 +875,15 @@ class InputAttributes(ConfluentMessage):
# use that as cue to put it into config as an expr
nodeattr[attr] = {'expression': nodeattr[attr]}
if validattrs and 'validvalues' in validattrs.get(attr, []):
if (nodeattr[attr] and
nodeattr[attr] not in validattrs[attr]['validvalues']):
raise exc.InvalidArgumentException(
'Attribute {0} does not accept value {1} (valid values would be {2})'.format(
attr, nodeattr[attr], ','.join(validattrs[attr]['validvalues'])))
if nodeattr[attr]:
for validvalue in validattrs[attr]['validvalues']:
if nodeattr[attr] == validvalue or fnmatch(
nodeattr[attr], validvalue):
break
else:
raise exc.InvalidArgumentException(
'Attribute {0} does not accept value {1} (valid values would be {2})'.format(
attr, nodeattr[attr], ','.join(validattrs[attr]['validvalues'])))
elif validattrs and 'validlist' in validattrs.get(attr, []) and nodeattr[attr]:
req = nodeattr[attr].split(',')
for v in req: