After installing Debian buster on my GnuBee , I set it up for receiving backups from my other computers.
I started by configuring it like a typical server but without a few packages that either take a lot of memory or CPU:
I changed the default hostname:
127.0.0.1 foobar.example.com vogar localhost
and then installed the
package to be able to reach this box
I noticed the presence of a world-writable
and so I
tightened the security of some of the default mount points by putting the following
mount -o remount,nodev,nosuid /etc/network mount -o remount,nodev,nosuid /lib/modules chmod 755 /etc/network exit 0
My OS drive (
) is a small SSD so that the GnuBee can run silently when the
spinning disks aren't needed. To hold the backup data on the other hand, I
got three 4-TB drives drives which I setup in a RAID-5
If the data were valuable, I'd use RAID-6
since it can survive two drives failing at the same time, but in this case
since it's only holding backups, I'd have to lose the original machine at
the same time as two of the 3 drives, a very unlikely scenario.
I created new gpt partition tables on
to create a single partition of
(Linux RAID) on
each of them.
Then I created the RAID array:
mdadm /dev/md127 --create -n 3 --level=raid5 -a /dev/sdb1 /dev/sdc1 /dev/sdd1
and waited more than 24 hours for that operation to finish. Next, I formatted the array:
mkfs.ext4 -m 0 /dev/md127
and added the following to
/dev/md127 /mnt/data/ ext4 noatime,nodiratime 0 2
Finally I setup smartmontools
the following in
/dev/sda -a -o on -S on -s (S/../.././02|L/../../6/03) /dev/sdb -a -o on -S on -s (S/../.././02|L/../../6/03) /dev/sdc -a -o on -S on -s (S/../.././02|L/../../6/03) /dev/sdd -a -o on -S on -s (S/../.././02|L/../../6/03)
and restarting the daemon:
systemctl restart smartd.service
I started by using duplicity since I have been using that tool for many years, but a 190GB backup took around 15 hours on the GnuBee with gigabit ethernet.
I created a user account for each machine needing to backup onto the GnuBee:
adduser machine1 adduser machine1 sshuser
and then a matching directory under
mkdir /mnt/data/machine1 chown machine1:machine1 /mnt/data/machine1
Then I created a custom ssh key for each machine:
ssh-keygen -f /root/.ssh/foobar_backups -t ed25519
and placed it in
on the GnuBee.
On each machine, I added the following to
Host foobar.local User machine1 Compression no Ciphers aes128-ctr IdentityFile /root/backup/foobar_backups IdentitiesOnly yes ServerAliveInterval 60 ServerAliveCountMax 240
# Configure for each host PASSWORD="XXXX" # use `pwgen -s 64` to generate a good random password BACKUP_HOME="/root/backup" REMOTE_URL="sftp:foobar.local:/mnt/data/machine1" RETENTION_POLICY="--keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 2" # Internal variables SSH_IDENTITY="IdentityFile=$BACKUP_HOME/foobar_backups" EXCLUDE_FILE="$BACKUP_HOME/exclude" PKG_FILE="$BACKUP_HOME/dpkg-selections" PARTITION_FILE="$BACKUP_HOME/partitions" # If the list of files has been requested, only do that if [ "$1" = "--list-current-files" ]; then RESTIC_PASSWORD=$PASSWORD restic --quiet -r $REMOTE_URL ls latest exit 0 # Restore the given file elif [ "$1" = "--file-to-restore" ]; then if [ "$2" = "" ]; then echo "You must specify a file to restore" exit 2 fi RESTORE_DIR="$(mktemp -d ./restored_XXXXXXXX)" RESTIC_PASSWORD=$PASSWORD restic --quiet -r $REMOTE_URL restore latest --target "$RESTORE_DIR" --include "$2" || exit 1 echo "$2 was restored to $RESTORE_DIR" exit 0 # Delete old backups elif [ "$1" = "--prune" ]; then # Expire old backups RESTIC_PASSWORD=$PASSWORD restic --quiet -r $REMOTE_URL forget $RETENTION_POLICY # Delete files which are no longer necessary (slow) RESTIC_PASSWORD=$PASSWORD restic --quiet -r $REMOTE_URL prune exit 0 # Catch invalid arguments elif [ "$1" != "" ]; then echo "Invalid argument: $1" exit 1 fi # Check the integrity of existing backups RESTIC_PASSWORD=$PASSWORD restic --quiet -r $REMOTE_URL check || exit 1 # Dump list of Debian packages dpkg --get-selections > $PKG_FILE # Dump partition tables from harddrives /sbin/fdisk -l /dev/sda > $PARTITION_FILE /sbin/fdisk -l /dev/sdb > $PARTITION_FILE # Do the actual backup using Duplicity RESTIC_PASSWORD=$PASSWORD restic --quiet -r $REMOTE_URL backup / --exclude-file $EXCLUDE_FILE
I run it with the following cronjob in
30 8 * * * root ionice nice nocache /root/backup/backup-machine1-to-foobar 30 2 * * Sun root ionice nice nocache /root/backup/backup-machine1-to-foobar --prune
in a way that doesn't impact the rest of the system too much .
Finally, I printed a copy of each of my backup script, using enscript , to stash in a safe place:
enscript --highlight=bash --style=emacs --output=- backup-machine1-to-foobar | ps2pdf - > foobar.pdf
This is actually a pretty important step since without the password, you won't be able to decrypt and restore what's on the GnuBee .