diff --git a/README.md b/README.md index c27241a..f752ec8 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,16 @@ The system uses multiple methods to unlock the LUKS volumes: - Secure boot enabled by default - Redundant boot partition using BTRFS RAID1 +### TPM Updates +After firmware updates (UEFI/BIOS), the TPM bindings need to be updated: +(otherwise the system will not be able to boot without recovery phrase) +1. Use the provided script: `sudo /root/update-tpm-bindings.sh` +2. The script will: + - Show current PCR values + - Update TPM bindings to match new measurements + - Verify all bindings are correct +3. Manual passphrase is available in `/root/luks-passphrase.txt` if needed + ## Repository Structure ``` . diff --git a/build.py b/build.py index 81ce65c..89568be 100644 --- a/build.py +++ b/build.py @@ -57,9 +57,76 @@ def generate_cloud_init(config): 'path': '/etc/clevis/tpm2.conf', 'content': json.dumps(tpm_json), 'permissions': '0644' + }, + { + 'path': '/root/update-tpm-bindings.sh', + 'content': '''#!/bin/bash +# Script to update TPM bindings after firmware updates +# Usage: sudo ./update-tpm-bindings.sh + +set -e + +# Check if running as root +if [ "$EUID" -ne 0 ]; then + echo "Please run as root" + exit 1 +fi + +# Check if TPM is available +if ! tpm2_getcap properties-fixed > /dev/null; then + echo "Error: TPM not available" + exit 1 +fi + +# Check if Tang server is accessible +TANG_URL=$(grep URL /etc/clevis/tang.conf | cut -d= -f2) +if ! curl -s -f "$TANG_URL/adv" > /dev/null; then + echo "Error: Tang server not accessible" + exit 1 +fi + +# Get current PCR values +echo "Current PCR values:" +tpm2_pcrread sha256:$(cat /etc/clevis/tpm2.conf | jq -r '.pcr_ids' | tr -d '[]' | tr ',' ' ') + +# Ask for confirmation +read -p "Have you updated firmware? Continue with TPM binding update? [y/N] " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted" + exit 1 +fi + +# Update TPM bindings +echo "Updating TPM bindings..." +for dev in /dev/sda2 /dev/sdb2; do + echo "Processing $dev..." + + # Unbind old TPM binding + clevis luks unbind -d "$dev" -s 1 || true + + # Create new TPM binding + clevis luks bind -d "$dev" tpm2 -c /etc/clevis/tpm2.conf || { + echo "Error: Failed to bind TPM to $dev" + exit 1 + } + + # Verify Tang binding + if ! clevis luks list -d "$dev" | grep -q "tang"; then + echo "Error: Tang binding not found on $dev" + exit 1 + fi +done + +echo "TPM bindings updated successfully!" +echo "Please reboot to verify the changes." +''', + 'permissions': '0700' } ], 'runcmd': [ + # Check if passphrase is set + '[ -n "$LUKS_PASSPHRASE" ] || { echo "Error: LUKS passphrase not found"; exit 1; }', # Verify Tang server is accessible f'curl -s -f {system["luks"]["tang_url"]}/adv > /dev/null || {{ echo "Tang server not accessible"; exit 1; }}', # Verify TPM is available diff --git a/deploy.py b/deploy.py index 2eceab9..5814cf6 100644 --- a/deploy.py +++ b/deploy.py @@ -111,7 +111,8 @@ def create_server(config, hostname, image_id): 'permissions': '0600' } ], - 'runcmd': [ + 'bootcmd': [ + # Set passphrase before any LUKS operations f'export LUKS_PASSPHRASE="{passphrase}"' ] }