diff --git a/confluent_osdeploy/el7/profiles/default/scripts/pre.sh b/confluent_osdeploy/el7/profiles/default/scripts/pre.sh index 65b3da0e..2e28de23 100644 --- a/confluent_osdeploy/el7/profiles/default/scripts/pre.sh +++ b/confluent_osdeploy/el7/profiles/default/scripts/pre.sh @@ -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 diff --git a/confluent_osdeploy/el7/profiles/default/scripts/tpm_luks.sh b/confluent_osdeploy/el7/profiles/default/scripts/tpm_luks.sh index df9c857f..51d8d084 100644 --- a/confluent_osdeploy/el7/profiles/default/scripts/tpm_luks.sh +++ b/confluent_osdeploy/el7/profiles/default/scripts/tpm_luks.sh @@ -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 diff --git a/confluent_osdeploy/el8/profiles/default/scripts/pre.sh b/confluent_osdeploy/el8/profiles/default/scripts/pre.sh index 53d30208..ed656805 100644 --- a/confluent_osdeploy/el8/profiles/default/scripts/pre.sh +++ b/confluent_osdeploy/el8/profiles/default/scripts/pre.sh @@ -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())') diff --git a/confluent_osdeploy/el8/profiles/default/scripts/tpm_luks.sh b/confluent_osdeploy/el8/profiles/default/scripts/tpm_luks.sh index 19cf9630..a46304b5 100644 --- a/confluent_osdeploy/el8/profiles/default/scripts/tpm_luks.sh +++ b/confluent_osdeploy/el8/profiles/default/scripts/tpm_luks.sh @@ -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 diff --git a/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/post.sh b/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/post.sh index 78e6b411..4b1d92f2 100755 --- a/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/post.sh +++ b/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/post.sh @@ -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 diff --git a/confluent_server/confluent/config/attributes.py b/confluent_server/confluent/config/attributes.py index 72ceaced..cb088302 100644 --- a/confluent_server/confluent/config/attributes.py +++ b/confluent_server/confluent/config/attributes.py @@ -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 ' diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index 9245d38a..88894e3e 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -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: