:.: backups (bupstash)

Hola, I think we all know that backups are important, specially when you wiped your own hdd by mistake, never happened to me, but a friend. My "backup strategy" for any device (laptop, server, phone) is to have a "local" (another drive) or "near" (in the same lan) backup and another in a remote location, some server somewhere.

For quite sometime I used a very simple script with a little config file to send with rsync backups to another drive or server, something like this:

$ cat code/backup.conf
REMOTE_HOST=fart.cloud.com
PORT=8022
SRC=/home/gonzalo
DEST=/home/gonzalo/Backups/`hostname -s`.bck
$ cat code/backup
#
#set -x

. ~/code/backup.conf

TIMESTAMP=$(date -u +%G%m%dT%H%M%SZ)
NAME=$(echo ${SRC} | cut -d'/' -f 2)

ssh gonzalo@${REMOTE_HOST} "mkdir -p ${DEST}/${TIMESTAMP}"

if [[ -d ${SRC} ]]; then
        rsync -avz \
        --port=${PORT} \
        -e ssh ${SRC} \
        gonzalo@${REMOTE_HOST}:${DEST}/${TIMESTAMP}
fi

ssh gonzalo@${REMOTE_HOST} "tar cfz ${DEST}/${TIMESTAMP}-${NAME}.tgz ${DEST}/${TIMESTAMP}"

Sure, it works, it's easy, but not very professional and no deduplication or incremental feature, so after using borg-backup a couple months somehow I ended up trying something else, since for my cases borg-backup was slow, after some research I found bupstash, which is a backup soluction in rust, from the website:

Backups with strict access controls, strong encryption, data deduplication, incremental uploads and offline decryption keys.

We have it of course in OpenBSD and you can install it by doing:

$ doas pkg_add bupstash

bupstash is quite easy to use, you need to create a key for your backups and then just "put" things inside of it, let's create the key first:

$ bupstash new-key -o /home/gonzalo/secret-backup.key
$
$ cat /home/gonzalo/secret-backup.key
# This file contains a cryptographic key used by 'bupstash' to encrypt and decrypt data.
#
# key-id=672867dc7f0ac0ed34112ec88354af12

-----BEGIN BUPSTASH KEY-----
AGcoZ9x/CsDtNBEuyINUrxKxH36ttnv3gOqB561ZfuKErzNv90TSxfjkZhXaASTL
ydQXI2/CeI092BNZ3vILwkvFF3EsLEUkmDap1uEuoRGzy4K9k7vGO0um0sHrKXkk
NA4zNS80sryFfiLaT5d2RBK2mvwsRelbwpwR9xo8TZsuAhZcpxpLfkgNZHYiiLOf
ZxNRUaNk844OqsIexLm0z7rbOuDNmiPedixKSgNKhLsczxcL1QVBBhcmzUVU0fjQ
U6e2/NN3F8eiW9G+Y+3MXo2rcySnOgJhX4FCvKBtFIxnUKvN7SkhJPgLgbznDW3t
iNbXvlYuYrSKhYsqnH687a3ws9XW5xLmyWHExeGGPxeuwWPZ2wE+v+I12LoNx6oe
Fhf3/jToAdA6AoHAZvQN8mwTM+fBFG3p1C02xWqBIjvbhqTpamclnczw0Dq9BKfZ
Rx4aOqhhgKmHszWIKk6jTOaJUlWVOI72QS3gWUMIITJVP+4dROBafu6r6T+GtTE4
ANkRQ3HK5BlSvVutSTAVvAI6azkNi+1GMSr3m3TgynAhSI+aujKlhrZ+ta0h9Chh
Zy00A+4o+T1h2AVmuKRFhPjsWSvJxyQlUQuDIHlF3RYg
-----END BUPSTASH KEY-----

I am gonna cover just the basic usage by making a backup of a full directory, if you need more options or variation of it, you should go to the oficial documentation which is really cool and easy, they even have videos!

I will make a backup of my /usr/ports/mystuff directory on /home/gonzalo/Backups which is another drive, and then the same but in a remote server, remember for this, you must have bupstash also in the remote server

Local backup

We need to export our key and destination directory, then we "init" (only the first time) the backup, which means create the repository where the backup will live, and the necesary files for it

$ export BUPSTASH_REPOSITORY=/home/gonzalo/Backups/mystuff
$ export BUPSTASH_KEY=/home/gonzalo/secret-backup.key
$ ls -al /home/gonzalo/Backups/mystuff
ls: /home/gonzalo/Backup/mystuff: No such file or directory
$ bupstash init
$ ls -al /home/gonzalo/Backups/mystuff                                                                                                                  
total 16
drwxr-xr-x  4 gonzalo  gonzalo   512B Jan 17 19:47 ./
drwxr-xr-x  3 gonzalo  gonzalo   512B Jan 17 19:47 ../
drwxr-xr-x  2 gonzalo  gonzalo   512B Jan 17 19:47 items/
drwxr-xr-x  2 gonzalo  gonzalo   512B Jan 17 19:47 meta/
-rw-r--r--  1 gonzalo  gonzalo     0B Jan 17 19:47 repo.lock
-rw-r--r--  1 gonzalo  gonzalo     0B Jan 17 19:47 repo.oplog
-rw-r--r--  1 gonzalo  gonzalo     0B Jan 17 19:47 tx.lock

Let's make the backup now!

$ bupstash put host="$(hostname)" name=mystuff.tar /usr/ports/mystuff/
... some magic ...
baf9f314fb756e0bfe7e0b83cb54614c

Done! Easy right? Let's check if there is something there:

$ bupstash list name='*.tar'
id="baf9f314fb756e0bfe7e0b83cb54614c" name="mystuff.tar" host="ports.x61.home" size="26.60MiB" timestamp="2022/01/17 19:52:17"
$ bupstash list-contents name='*.tar'
... a lot of files ...
$ bupstash get name=mystuff.tar and timestamp=2022* > /home/gonzalo/Backups/Restores/mystuff-restored.tar
$ du -sh /home/gonzalo/Backups/Restores/mystuff-restored.tar
27.1M   /home/gonzalo/Backups/Restores/mystuff-restored.tar

Those are basic ones, but you can even get single files or directories, and it is fast.

Remote backup

For the remote backups the concept is the same, but we use ssh to play with it.The /home/gonzalo/Backups/mystuff directory now is a remote one in the server.

$ export BUPSTASH_REPOSITORY_COMMAND="ssh gonzalo@100.100.0.1 bupstash serve /home/gonzalo/Backups/mystuff"
$ export BUPSTASH_KEY=/home/gonzalo/secret-backup.key
$ bupstash init
$ bupstash put host="$(hostname)" name=mystuff.tar /usr/ports/mystuff/
... some magic ...
b3h4j5h2g1h3j4h2h5gj21g1k6lh231g

So, that's it, now we have backups in 2 different locations, remember that "bupstash init" you need to do it only the first time to initialize the backup, then to send new files or new backups, let's say every night, you should run the "bupstash put..." line.