|
| 1 | +#!/bin/bash |
| 2 | +set -e |
| 3 | +set -x |
| 4 | + |
| 5 | +machine_id=$(cat /etc/machine-id) |
| 6 | + |
| 7 | +# Auto-detect first LUKS partition for testing |
| 8 | +test_device=$(lsblk -nlo NAME,TYPE,FSTYPE | awk '$2 == "part" && $3 == "crypto_LUKS" {print $1; exit}') |
| 9 | +if [ -z "$test_device" ]; then |
| 10 | + echo "No LUKS partitions found, skipping recovery test" |
| 11 | + exit 0 |
| 12 | +fi |
| 13 | + |
| 14 | +test_partition=$(lsblk -nlo PARTLABEL /dev/$test_device | tr -d '\n') |
| 15 | +mapper_name=$(lsblk -nlo NAME /dev/$test_device | awk 'NR==2') |
| 16 | + |
| 17 | +echo "Testing recovery unlock for ${test_partition} (device: ${test_device}, mapper: ${mapper_name})..." |
| 18 | + |
| 19 | +# Get recovery key from Vault |
| 20 | +recovery_key=$(mangosctl sudo -- vault kv get -field=key "secrets/mangos/recovery-keys/${machine_id}/${test_partition}") |
| 21 | + |
| 22 | +# Find TPM keyslot number |
| 23 | +tpm_slot=$(cryptsetup luksDump /dev/$test_device | \ |
| 24 | + awk '/Tokens:/,/Keyslots:/ {if (/systemd-tpm2/) found=1; if (found && /^ [0-9]+:/) {print $1; exit}}' | \ |
| 25 | + tr -d ':') |
| 26 | + |
| 27 | +echo "Removing TPM keyslot ${tpm_slot} (simulating TPM failure)..." |
| 28 | +PASSWORD="$recovery_key" systemd-cryptenroll --wipe-slot=tpm2 /dev/$test_device |
| 29 | + |
| 30 | + |
| 31 | +# Get mount point for this partition |
| 32 | +mount_point=$(findmnt -n -o TARGET /dev/mapper/$mapper_name) |
| 33 | + |
| 34 | +# Unmount and close |
| 35 | +if [ -n "$mount_point" ]; then |
| 36 | + systemctl stop $(systemd-escape -p --suffix=mount "$mount_point") |
| 37 | +fi |
| 38 | +cryptsetup close $mapper_name |
| 39 | + |
| 40 | +# THE CRITICAL TEST: Unlock with recovery key |
| 41 | +echo "Unlocking with recovery key..." |
| 42 | +echo -n "$recovery_key" | systemd-cryptsetup attach $mapper_name /dev/$test_device - |
| 43 | + |
| 44 | +# Remount |
| 45 | +if [ -n "$mount_point" ]; then |
| 46 | + mount /dev/mapper/$mapper_name "$mount_point" |
| 47 | +fi |
| 48 | + |
| 49 | +# Verify device is accessible |
| 50 | +if [ ! -b /dev/mapper/$mapper_name ]; then |
| 51 | + echo "ERROR: Device not accessible after recovery" |
| 52 | + exit 1 |
| 53 | +fi |
| 54 | + |
| 55 | +echo "Data accessible after recovery: OK" |
| 56 | + |
| 57 | +# Re-enroll TPM (cleanup for future tests) |
| 58 | +echo "Re-enrolling TPM keyslot..." |
| 59 | +echo -n "$recovery_key" | systemd-cryptenroll /dev/$test_device \ |
| 60 | + --tpm2-device=auto \ |
| 61 | + --tpm2-pcrs=7 \ |
| 62 | + --tpm2-public-key-pcrs=11 \ |
| 63 | + --unlock-key-file=/dev/stdin |
| 64 | + |
| 65 | +echo "Recovery test: PASSED" |
0 commit comments