LUKS Header Backup

Overview

LUKS headers contain the encryption metadata. If corrupted, all data is permanently lost - even with the correct passphrase.

LUKS header backups are as sensitive as the encrypted data itself. Store securely and encrypted.

Current Backups

Device Header File Storage Location

Seagate SSD 1

seagate-ssd1-YYYYMMDD-HHMMSS.img.age

~/.secrets/luks-headers/

Seagate SSD 2

seagate-ssd2-YYYYMMDD-HHMMSS.img.age

~/.secrets/luks-headers/

Workstation root

Backed up to Seagate SSDs

/mnt/seagate/luks/

Headers are encrypted with age before storage.

Backup Procedures

Workstation LUKS Partitions

Step 1: Identify LUKS partitions
lsblk -f | grep crypto
Step 2: Backup each header
sudo cryptsetup luksHeaderBackup /dev/nvme0n1p3 \
    --header-backup-file /tmp/workstation-root-$(date +%Y%m%d).img

sudo cryptsetup luksHeaderBackup /dev/nvme0n1p4 \
    --header-backup-file /tmp/workstation-swap-$(date +%Y%m%d).img

sudo cryptsetup luksHeaderBackup /dev/nvme0n1p5 \
    --header-backup-file /tmp/workstation-home-$(date +%Y%m%d).img
Step 3: Encrypt with age
age -e -R ~/.config/age/recipients.txt \
    -o /tmp/workstation-root-$(date +%Y%m%d).img.age \
    /tmp/workstation-root-$(date +%Y%m%d).img
Step 4: Move to secure storage
mv /tmp/*.img.age ~/.secrets/luks-headers/
Step 5: Shred plaintext headers
shred -vzn 3 /tmp/*.img && rm /tmp/*.img

Seagate USB Drives

Backup Seagate SSD headers
# Seagate Primary
sudo cryptsetup luksHeaderBackup /dev/sda1 \
    --header-backup-file /tmp/seagate-ssd1-$(date +%Y%m%d-%H%M%S).img

# Seagate Backup
sudo cryptsetup luksHeaderBackup /dev/sdb1 \
    --header-backup-file /tmp/seagate-ssd2-$(date +%Y%m%d-%H%M%S).img
Encrypt and store
for f in /tmp/seagate-ssd*.img; do
    age -e -R ~/.config/age/recipients.txt -o "${f}.age" "$f"
    shred -vzn 3 "$f" && rm "$f"
done
mv /tmp/seagate-ssd*.img.age ~/.secrets/luks-headers/

Restore Procedures

Restore Corrupted Header

Only use if LUKS header is corrupted. This will overwrite the current header.
Step 1: Decrypt the header backup
age -d -i ~/.config/age/key.txt \
    -o /tmp/header-restore.img \
    ~/.secrets/luks-headers/seagate-ssd1-YYYYMMDD-HHMMSS.img.age
Step 2: Restore header to device
sudo cryptsetup luksHeaderRestore /dev/sdX1 \
    --header-backup-file /tmp/header-restore.img
Step 3: Verify and cleanup
sudo cryptsetup luksDump /dev/sdX1
shred -vzn 3 /tmp/header-restore.img && rm /tmp/header-restore.img

Storage Locations

Tier Location Contents

Hot

~/.secrets/luks-headers/

Age-encrypted headers

Warm

NAS (via Borg)

Backed up with ~/.secrets

Cold

Seagate SSDs

Copy of ~/.secrets/luks-headers/

Archival

M-Disc

Critical headers only

LUKS Passphrases

LUKS passphrases are stored in gopass:

Retrieve LUKS passphrase
gopass show ARCANA/storage/seagate-primary
gopass show ARCANA/storage/seagate-secondary
Never store LUKS passphrases in plaintext files. Always use gopass/pass.

Schedule

Frequency Action

After key change

Backup affected header immediately

Monthly

Verify header backups exist and are readable

Annually

Burn to M-Disc with other archival data

Verification

Test decryption of header backup
age -d -i ~/.config/age/key.txt \
    ~/.secrets/luks-headers/seagate-ssd1-*.img.age | \
    file -

Expected output: LUKS encrypted file, ver 2