Initial commit
This commit is contained in:
commit
1a7da418ba
5 changed files with 84 additions and 0 deletions
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
@ -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
|
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Data Volumes
|
||||
/data
|
||||
/snapshots
|
||||
/repo
|
||||
|
||||
# Key
|
||||
/static-passphrase-key
|
||||
/static-passphrase-key.pub
|
38
README.md
Normal file
38
README.md
Normal file
|
@ -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)
|
19
backup.sh
Executable file
19
backup.sh
Executable file
|
@ -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!"
|
10
create-passphrase-file.sh
Executable file
10
create-passphrase-file.sh
Executable file
|
@ -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!"
|
Loading…
Reference in a new issue