I ❤️ rsync
Finally after many many conversations with friends, I have a working backup solution setup and in place.
This uses rsync and automatically copies files from 2 different directories on one machine and places them in a directory on another machine.
This is a long way off from the recommended 3,2,1 backup logic (which I think is 3 backups, 2 on different mediums and 1 off-site) but its a start.
Connecting to other machines using SSH, I do so using keys. My SSH key has a passphrase associated with it. For automated back-ups using rsync (which uses ssh) this wouldn't be suitable. I therefore first created a new keypair that can be used for my rsync backup purpose.
On the server I am backing up "from" I ran the following command:
ssh-keygen -t ed25519 -f ~/.ssh/newly-created-key -N "" -C "insert-useless-comment-here"This created a private and public key, The public key was copied over to the server I was backing up "to" and placed inside the "authorized_keys" file which was prefixed with the following:
no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...This provides some additional hardening by blocking ssh tunneling attacks and prevents remote forwarding.
I did start out by trying to restrict the key to only being able to run rsync and to and from specific locations on the remote and host machines by entering the following command at the start:
command="rsync --server . /disk4/backup-main/"This however presented some errors which I couldn't at the time work around. For my use case though, what I have currently is suffice for now.
I now turned my attention to creating a script which will copy data from 2 directories and use rsync, with the newly created key and place them into a directory on another server.
With the help of ChatGPT, I came up with the following:
#!/bin/bash
set -euo pipefail
SRC_DIRS=(
"/data/app"
"/data/media"
)
DEST="xander@phobos:/backups/titan"
SSH_KEY="/home/xander/.ssh/newly-created-key"
rsync -av \
-e "ssh -i $SSH_KEY" \
"${SRC_DIRS[@]}" \
"$DEST"I ensured this had executable permissions and ran it with ./name-of-script to test its functionallity.
Once it was working, I let it run. The first time running this took quite some time as it had to copy across all the files and directories in the specified SRC_DIRS
rsync has many different flags (https://linux.die.net/man/1/rsync) but I opted for a simple archive option and ommited the --delete option. I wanted the abillity to recover a file should it get deleted from source. I may not notice for a couple of days/weeks and my plan was to have this run every morning at 2:30am
Subsequent runs would only transfer (or sync) the difference (or delta) between source and destination.
This was now working well and my next step was to automate this by creating a simple cronjob. This was created on the user that was going to be running the script and, more importantly, owned the ssh keypair previously created.
crontab -eThis opened up in my text editor of choice which for me is vim and at the bottom of the file, I entered in the following line:
30 2 * * * /location/of/backup/script/name/of/scriptThis now runs the script at 2:30am every morning.
Job done 👍
I will now turn my attention to improving the hardening of this. Maybe i'll create a totally separate user for this task and look further into why the command at the start of the authorized_keys file wasn't working as expected.