Haydn Cowley

Write-ups

Finding a weak spot in my own backups

My nightly backups held my most sensitive keys, unencrypted, on the same drive as my films. So I fixed it and proved I could still restore.

2 min readBy Haydn
Goal
Keep nightly backups safe even if someone takes the drive
Result
Encrypted, restore tested
Tools
age, tar, systemd timers, SHA-256

The problem

Every night at 4am a script backs up the Pi's settings to the 1TB drive. Those backups contain the things an attacker would want most: my Tailscale key (which would let them pretend to be my Pi on my private network), my Cloudflare Tunnel token (which could let them hijack my website) and password hashes.

The backup folder was root-only. That sounds safe, but file permissions only work while the drive is plugged into the Pi. Anyone who took the drive could read it on their own computer.

The fix: encrypt before it touches the drive

I used age, a simple modern encryption tool. The clever part is that it uses a key pair:

  • The public key is on the Pi. It can lock backups but can't open them.
  • The private key is on my Mac and in my password manager. It never touches the Pi or GitHub.

So even someone who broke into the Pi couldn't read my old backups. The archive goes straight from tar into age, so an unencrypted copy is never saved anywhere, and if the public key is missing the backup refuses to run instead of saving it unencrypted.

Proving it still works

A backup you've never restored is just a hope. I copied the first encrypted backup to my Mac, decrypted it and compared one file with the real one on the Pi:

# on the Pi
$ sudo sha256sum /etc/ufw/user.rules
fcbe9693...  /etc/ufw/user.rules

# on my Mac, from the encrypted backup
$ age -d -i key.txt backup.tar.gz.age | tar -xzf - -O etc/ufw/user.rules | shasum -a 256
fcbe9693...  -

Identical. Then I deleted the old unencrypted backup with shred, which overwrites it first so it can't be recovered from the drive.

Mistake I made: my first delete did nothing. The backup folder is root-only, so my own shell couldn't see inside it to expand the *. Running it as sudo sh -c '...' let root expand it instead.

What I learned

  • Permissions protect files from other users, not from someone holding the disk.
  • Public key encryption means the machine making backups doesn't have to be trusted with reading them.
  • Next step: copy the encrypted backups off-site. Because they're encrypted, they're safe to keep anywhere.

How I used AI: I spotted the risk and asked about it. Claude wrote the new backup script and talked me through making the key. I ran the restore test myself. The full, unedited notes are in my build log.