Edit this page | Blame

Backup Drops

To make backups we use a combination of sheepdog, borg, sshfs, rsync. sheepdog is the monitor and status is tracked using a redis queue. borg does incremental backups as a local user. Next we drop the backup to a remote machine using a special user on the remote with very limited access - only one directory can be mounted with sshfs and there is no ssh login. Finally the data gets rsync'd across.

This system proves pretty resilient over time. Only on the synology server I can't get it to work because of some CRON permission issue.

For doing the actual backups see

Tags

Info

Borg backups

Despite our precautions it is advised to use a backup password and *not* store that on the remote.

Running sheepdog on rabbit

Create a drop user on remote

adduser bacchus

Disable the password, just to be sure. Next add the following to /etc/ssh/sshd.conf:

-# override default of no subsystems
-Subsystem      sftp    /usr/lib/openssh/sftp-server
+Subsystem      sftp    internal-sftp -f AUTH -l VERBOSE
+
+Match User bacchus
+    # ChrootDirectory /export/backup/%u
+    ChrootDirectory /export/backup/%u
+    X11Forwarding no
+    AllowTcpForwarding no
+    ForceCommand internal-sftp
+    PasswordAuthentication no
+    PubkeyAuthentication yes

And run

systemctl reload ssh

You may need to add to allowusers for ssh access. If you use allowusers (recommended) you can even specify the sending host with

AllowUsers bacchus@remote

where remote can be an IP address.

Warning: if you introduce this `AllowUsers` command all users should be listed or people may get locked out of the machine.

Next create a special password-less key on the backup machine's ibackup user (just hit enter):

su ibackup
ssh-keygen -t ecdsa -f $HOME/.ssh/id_ecdsa_backup

and copy the public key into the remote /home/bacchus/.ssh/authorized_keys.

Now test it from the backup server with

ssh -v bacchus@dropserver

it should give a Permission denied (publickey).

On the drop server you can track messages by

tail -40 /var/log/auth.log

or on recent linux with systemd

journalctl -r

Next

ssh -v -i ~/.ssh/id_ecdsa_backup bacchus@dropserver

should give a Broken pipe(!) or -- more recently -- it says `This service allows sftp connections only`. When running sshd with a verbose switch you may see something like

fatal: bad ownership or modes for chroot directory component "/export/backup/"

This is a tricky bit. This directory should be owned by root and have permissions. The inside user directory has different permissions:

ls -ld /export/backup/
drwxr-xr-x 3 root root 4096 Oct 21 02:08 /export/backup/
drwxr-xr-x 3 root root 4096 Oct 21 02:07 /export/backup/bacchus
drwx------ 3 bacchus bacchus 4096 Oct 21 02:26 /export/backup/bacchus/drop

So, as root

cd /export
mkdir -p backup/bacchus/drop
chown bacchus:bacchus backup/bacchus/drop/
chmod 0700 backup/bacchus/drop/

Another error may be:

fusermount3: mount failed: Operation not permitted

This means you need to set the suid on the fusermount3 command. Bit nasty in Guix.

apt-get install fuse(3) sshfs
chmod 4755 /usr/bin/fusermount

If auth.log says error: /dev/pts/11: No such file or directory on ssh, or received disconnect (...) disconnected by user we are good to go!

Note: at this stage it may pay to track the system log with

journalctl -u ssh -f

and, in a pinch, increase DEBUG output in sshd_config with

LogLevel DEBUG3

In my case I had to disable PAM!

Next try sshfs

su ibackup
mkdir -p ~/mnt/dropserver
sshfs -o IdentityFile=~/.ssh/id_ecdsa_backup bacchus@dropserver:/ ~/mnt/dropserver/
df -h|grep mnt
touch ~/mnt/dropserver/drop/HELLO

And the remote directory should be ready for dropping files!

rsync  -vrltDP  /export2/backup/borg/borg-tux01 ~/mnt/balg01/drop/ --delete

To unmount the dir

fusermount -u ~/mnt/dropserver

IMPORTANT: it is important to try ssh and read /var/log/auth.log to deal with permission issues. sshfs and the underlying sftp protocol are fussy.

Using rsync over sshfs with sheepdog

A backup script with sheepdog may look like

sheepdog_run.rb -h rabbit --always -v --tag "drop-mount-dropserver" -c "sshfs -o IdentityFile=~/.ssh/id_ecdsa_backup bacchus@dropserver:/ ~/mnt/this"

sheepdog_run.rb -h rabbit --always -v --tag "drop-rsync-dropserver" -c "rsync -vrltDP this/* borg/* ~/mnt/this/drop/this/ --delete"

sheepdog_run.rb -h rabbit --always -v --tag "drop-unmount-dropserver" -c "fusermount -u ~/mnt/this"

It may be useful to add the following options to sshfs:

sshfs -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,IdentityFile=~/.ssh/id_ecdsa_backup ...

The recent scripts can be found at

borg-borg

Backups work for production according to sheepdog. They run at 5am CST. Which (I guess) is OK. On the remote server we are going to forward the backup to a server on a different continent at 4pm GMT. I have been running that by hand lately, so time to sheepdog it!

The manual command is

rsync -e "ssh -i ~/.ssh/id_ecdsa_borgborg" -vaP tux03 $HOST:/export/backup/bacchus/drop/

With sheepdog we can make it:

sheepdog_run.rb -v --tag "drop-mount-$name" -c "sshfs -o $SFTP_SETTING,IdentityFile=~/.ssh/id_ecdsa_backup bacchus@$host:/ ~/mnt/$name"
sheepdog_run.rb --always -v --tag "drop-rsync-$name" -c "rsync -vrltDP borg/* ~/mnt/$name/drop/$HOST/ --delete"
sheepdog_run.rb -v --tag "drop-unmount-$name" -c "fusermount -u ~/mnt/$name"

For some reason this took a while to figure out. Part of it is that the machine on the other end has a rather slow CPU! An Intel(R) Celeron(R) CPU J1900 @ 1.99GHz launched over 10 years ago. We still use it because of its low energy consumption. Once it starts pumping a file it is up to speed

tux03/tux03-containers/data/0/239
    154,501,120  29%   11.20MB/s    0:00:32

So one backup of a backup has started running and I made it a CRON job. Next stop is borgborg on the receiving HOST. The CRON job looks like

0 3 * * * env BORG_PASSPHRASE=none /home/wrk/iwrk/deploy/deploy/bin/sheepdog_borg.rb -t borgborg --always -v -b /export/backup/bacchus/borgborg/drop /export/backup/bacchus/drop --args '--stats' >> ~/cron.log 2>&1

note the backups are already password protected. No need to do that again. Now this backup is going to go onto optical media twice a year with the password printed on the backup. That should keep it for 100 years.

You can track this backup progress daily on the sheepdog status

i.e. in reverse order the flow is:

2025-09-18 08:35:00 +0200	FAIL	host	borgborg-backup
2025-09-18 16:19:45 -0500	SUCCESS	balg01	drop-rsync-zero
2025-09-18 05:59:46 +0000	SUCCESS	tux03	mariadb-check
2025-09-18 05:26:01 +0000	SUCCESS	tux03	drop-rsync-balg01
2025-09-18 05:25:48 +0000	SUCCESS	tux03	borg-tux03-sql-backup
2025-09-18 04:44:38 +0000	SUCCESS	tux03	mariabackup-make-consistent
2025-09-18 04:44:25 +0000	SUCCESS	tux03	mariabackup-dump

The borgborg should be fixed now. I am missing the container backups. What is going on there? These were last backed up on 'Sun, 2025-09-14 00:00:52'. Ah, I set the CRON job to runs once a week. That should be fixed now and it should show up.

(made with skribilo)