Remote Backup Using rsync

Mar 22, 2007

My company runs a web server without any real backup. Lately we’ve seen some strange file system stuff going on (we use reiserfs) and decided it’s high time to fix some kind of backup solution.

rsync came to the rescue!

This is a straight forward “guide” (or something) on how to set it up. We have a machine which initiates the backups every day at 05:00. This computer is the backup. Let’s call it thishost.

We want this to be secure thus we’ll use ssh. So, first we need to create a key pair so rsync doesn’t need to prompt for a password each time we run it.

$ cd $ ssh-keygen -t rsa

Accept the default path (~/.ssh/id…) and specify and empty passphrase.

$ ssh-keygen -t dsa

(Same procedure as with -t rsa)

$ cat .ssh/id_*.pub > .ssh/thisuser-thishost.pub $ scp .ssh/thisuser-thishost.pub [email protected]:~/.ssh/ $ rm .ssh/thisuser-thishost.pub $ ssh [email protected] $ cat .ssh/thisuser-thishost.pub >> .ssh/authorized_keys $ rm .ssh/thisuser-thishost.pub $ logout

Try connecting to remotehost and see if it lets you in:

$ ssh [email protected]

If it worked, log out and continue on thishost. If not, you did something wrong. Log out and try again from the beginning.

Scheduling

Now you can setup a cron job running something like this:

$ crontab -e $ 0 5 * * * /usr/bin/rsync -avz -e ssh [email protected]:/some/dir/ /backups/host/some--dir/ >> /backups/host/some--dir.log

This will backup the /some/dir on remotehost to the /backups/host/some–dir on thishost at 05:00 (5 AM) every day.

A more flexible scheduling solution

In my case, I needed to backup quite a few things on remotehost, so I wrapped all backup runs in a script which is triggered by cron.

#!/bin/sh RSYNC=/usr/bin/rsync BACKUP_BASE=/Volumes/Stuff/backup # remote user, remote host, remote path modersynk() { RHOST=$1 RUSER=$2 RPATH=$3 LNAME=`echo "$RPATH"|sed 's/^\///g'|sed 's/\//--/g'` LDIR="$BACKUP_BASE/$RHOST" LLOGFILE="$LDIR/$LNAME.log" mkdir -pm 775 "$LDIR" date '+%Y-%m-%d %H:%M:%S --mark--' >> "$LLOGFILE" $RSYNC -avz -e ssh "[email protected]:$RPATH/" "$LDIR/$LNAME/" | grep -Ev '(^$|^total size is|receiving file list)' >> "$LLOGFILE" } modersynk hunch.se root /var/www modersynk hunch.se root /etc modersynk hunch.se root /var/svn modersynk hunch.se root /var/mail/virtual modersynk hunch.se root /var/lib/mysql

The modersynk function takes the following arguments:

modersynk <REMOTE HOST> <REMOTE USER> <REMOTE PATH>

I setup cron like this:

$ crontab -e $ 0 5 * * * /etc/modersynk.sh

Simple as that! Works great and the level of complexity is, in my point of view, very low.