From 1a7da418ba08bf920979c31e3ee31cb8fea45235 Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Fri, 26 Nov 2021 11:37:06 +0000 Subject: [PATCH] Initial commit --- .editorconfig | 9 +++++++++ .gitignore | 8 ++++++++ README.md | 38 ++++++++++++++++++++++++++++++++++++++ backup.sh | 19 +++++++++++++++++++ create-passphrase-file.sh | 10 ++++++++++ 5 files changed, 84 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 README.md create mode 100755 backup.sh create mode 100755 create-passphrase-file.sh diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3838095 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4c2c9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Data Volumes +/data +/snapshots +/repo + +# Key +/static-passphrase-key +/static-passphrase-key.pub diff --git a/README.md b/README.md new file mode 100644 index 0000000..34a9856 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# `btrfs` Backup Solution + +Encrypted incremental backups utilizing +[`btrfs send`](https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs-send) +and [`age`](https://age-encryption.org/). + +## Setup + +At `/media/storage/backup`, we have: + +``` +backup/ + data/ [a btrfs **subvolume** containing the data] + ... + snapshots/ [btrfs snapshots of the 'data' subvolume] + repo/ [where encrypted backup files will go] + + [an age-encryption v1 key for the at-rest passphrase] + static-passphrase-key + static-passphrase-key.pub + + [the contents of this repo:] + backup.sh + create-passphrase-file.sh +``` + +You can generate the `static-passphrase-key` and `static-passphrase-key.pub` with +`rage-keygen -o static-passphrase-key` and by manually populating the pubkey file. + +## Requirements + +**Note:** Make sure that `data` is actually a btrfs subvolume!! + +- `btrfs` +- `bash` +- `zstd` +- [`rage`](https://github.com/str4d/rage) +- [`simple-age-encryptor`](https://git.lavender.software/charlotte/simple-age-encryptor) diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..be70a0b --- /dev/null +++ b/backup.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +echo "[+] Finding latest snapshot..." +latest_snapshot=$(ls /media/storage/backup/snapshots | sort | tail -n1) +passphrase=$(rage -d -i /media/storage/backup/static-passphrase-key /dev/shm/backup-passphrase) + +echo "[+] Creating new snapshot..." +new_snapshot=$(date -Iminutes) +btrfs subvolume snapshot -r '/media/storage/backup/data' "/media/storage/backup/snapshots/$new_snapshot" + +echo "[+] Encrypting new snapshot..." +btrfs send \ + -p "/media/storage/backup/snapshots/$latest_snapshot" \ + "/media/storage/backup/snapshots/$new_snapshot" \ + | zstd - \ + | simple-age-encryptor "$passphrase" \ + > "/media/storage/backup/repo/$new_snapshot.zstd.age" + +echo "[+] Done!" diff --git a/create-passphrase-file.sh b/create-passphrase-file.sh new file mode 100755 index 0000000..5b3cf7a --- /dev/null +++ b/create-passphrase-file.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +read -e -p "Passphrase: " -s passphrase +echo + +touch /dev/shm/backup-passphrase +chmod 600 /dev/shm/backup-passphrase +echo $passphrase | rage -R static-passphrase-key.pub > /dev/shm/backup-passphrase + +echo "Done!"