Mastodon

restic backups on Storm Buckets

restic encrypts your files on your machine, deduplicates them, and stores
snapshots in a bucket. That gives you something Storm Buckets does not do on its
own: history. Garage keeps the latest copy of an object, and restic keeps every
snapshot you tell it to, so a file overwritten on Tuesday is still in Monday's
snapshot.

Every command below was run with restic 0.18.1 against Garage v2.1.0, the engine
behind Storm Buckets, on a throwaway node. Run them once against your own bucket
before you trust a schedule.

What you need first

  • restic. This page was tested on 0.18.1, and restic version tells you yours.

  • A bucket for the backups and nothing else. See
    Getting Started.

  • A Read / Write key scoped to that bucket. See
    Managing Access Keys. restic prunes old data,
    so it needs delete, which Read / Write includes.

The settings

Setting Value
RESTIC_REPOSITORY s3:https://YOUR_ENDPOINT/your-bucket
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY your key
-o s3.region=YOUR_REGION your endpoint's name, for example montreal-1
-o s3.bucket-lookup=path path-style addressing

The endpoint is on the Connection panel of your bucket page. restic can usually
work out the region and the addressing style on its own. Setting both removes the
guess.

Put the secrets in a file only you can read:

cat > ~/.restic-storm.env <<'EOF'
export RESTIC_REPOSITORY=s3:https://YOUR_ENDPOINT/your-bucket
export STORM_REGION=YOUR_REGION
export AWS_ACCESS_KEY_ID=YOUR_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_SECRET
export RESTIC_PASSWORD_FILE=~/.restic-storm.pw
EOF
chmod 600 ~/.restic-storm.env

RESTIC_PASSWORD_FILE holds the repository password, which encrypts everything.
Lose it and the backup is unreadable, by you and by Storm. Keep a copy
somewhere that is not the machine you are backing up.

Create the repository

source ~/.restic-storm.env
restic -o s3.region=$STORM_REGION -o s3.bucket-lookup=path init

To save typing, alias the two options:

alias rs='restic -o s3.region=$STORM_REGION -o s3.bucket-lookup=path'

The rest of this page uses rs.

Back up

rs backup ~/documents --tag nightly
rs snapshots

The second run uploads only what changed. Each run is a snapshot with its own ID.

Check the backup

rs check --read-data-subset=10%

check alone verifies the repository structure. --read-data-subset downloads
and decrypts a slice of the actual data, which is the part that tells you a
restore will work. Rotate the slice: 10% a night reads everything in ten days.

restic restore

Restore the latest snapshot into an empty directory and compare it:

rs restore latest --target /tmp/restore-test
diff -r ~/documents /tmp/restore-test/home/you/documents

No output from diff means the restore matches. A backup you have never
restored is a guess.

Get an older version back

This is the history Garage does not keep for you. Find the snapshot from before
the change and restore one file from it:

rs snapshots
rs restore 807010a3 --target /tmp/old --include /home/you/documents/report.txt

Keep it tidy

Snapshots accumulate. Decide how many to keep and let restic drop the rest:

rs forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

--prune deletes the data no remaining snapshot needs. Pruning is what frees
capacity in your bucket.

Put it on a schedule

A nightly cron entry, backup then check:

30 2 * * * . ~/.restic-storm.env && restic -o s3.region=$STORM_REGION -o s3.bucket-lookup=path backup ~/documents --tag nightly --quiet && restic -o s3.region=$STORM_REGION -o s3.bucket-lookup=path check --read-data-subset=10\% --quiet

% must be escaped in crontab. Run forget --prune weekly rather than nightly.

What this does not cover

  • A key that can prune can delete. Anyone holding this key can destroy the
    repository. Keep the key on the machine being backed up and nowhere else.

  • Borg needs an SSH server at the other end, so it cannot write to a bucket
    directly. Kopia, Duplicati and Backrest (a web UI for restic) also
    speak S3. They are not covered here yet.

Next steps