BorgBackup in the Cloud

Using the Hetzner Storage Box
Published on June 06, 2022.

To back up my NAS I was shopping around for different cloud storage providers that I could use with BorgBackup.

Here are some yearly prices, calculated for a storage requirement of ~22TB (22.000GB).

Name
Fixed Price / y
Free GB
Cost add. GB / y
Cost / y
Borgbase Small
24
100
1,2
26304
Borgbase Medium
80
1000
0,084
1844
Borgbase Large
150
2000
0,06
1350
rsync.net <1TB
0
0
0,18
3960
rsync.net <100TB
0
0
0,096
2112
rsync.net >100TB
0
0
0,06
1320
Wasabi Storage
0
0
0,0708
1557,6
Google Storage Std
0
0
0,276
6072
Google Storage NL
0
0
0,12
2640
Hetzner 20TB Storage
526,92
0
0,026346
526,92

As you can tell, most providers I looked at are actually pretty expensive. One reason for this are their guarantees against data-loss.

One of the rows in the table above is not like the others, and that is the Hetzner Storage Box. These do not provide a dynamically growing storage, like the others. Instead you get a fixed amount of memory, depending on the amount of money you pay. The largest available size is 20TB, which is less than the 22TB I calculated with. But in reality I only need ~16TB currently for backups.

Because this is only used as an offsite backup for me, I decided to go with it for it's far lower price, because I can live with the possibility of losing data when their DC burns down or something 🚒 🧑‍🚒

Ordering a new storage box instance is straight-forward. You get a username, DNS name and auto-generated password in the Hetzner Web UI. In there you can also enable different access methods; we need SSH for Borg.

Setting up SSH authentication and using Borg are described in the Hetzner docs.

The workflow is a bit strange, I have to admit. While you can use Borg or rsync over SSH with the storage box, interactive logins are not possible and you can also not use ssh-copy-id. Instead, commands need to be executed via sftp. These are the steps I had to do to enable public-key authentication and initialize a borg repo.

cat .ssh/KEY.pub >> storagebox
echo -e "mkdir .ssh \n chmod 700 .ssh \n put storagebox .ssh/authorized_keys \n chmod 600 .ssh/authorized_keys" | sftp USER@USER.your-storagebox.de
rm storagebox
echo -e "mkdir backups \n mkdir backups/NAME" | sftp USER@USER.your-storagebox.de
BORG_RSH='ssh -i /home/USER/.ssh/KEY' borg init --encryption=repokey ssh://USER@USER.your-storagebox.de:23/./backups/NAME
BORG_RSH='ssh -i /home/USER/.ssh/KEY' borg key export ssh://USER@USER.your-storagebox.de:23/./backups/NAME keyfile
mv keyfile SOMEWHERE_SAFE

Then I simply adapted my existing backup scripts to add a BORG_RSH export.

#!/bin/sh

export BORG_REPO=ssh://USER@USER.your-storagebox.de:23/./backups/NAME
export BORG_PASSPHRASE='PASSWORD'
export BORG_RSH='ssh -i /home/USER/.ssh/KEY'

export BACKUP_PATH=/PATH_TO_BACKUP
export BACKUP_EXCLUDES="      \
    --exclude=/EXCLUDED_PATHS \
"

backup-borg

backup_exit=$?
exit ${backup_exit}