Using rsnapshot for File and Database Backups

posted in: backup, database, linux | 0

rsnapshot is my favorite tool for doing automated distributed backups on Linux machines. It saves you a lot of headaches – and it finally replaced all those hundreds of hand-made backup scripts I previously used.

rsnapshot itself is easy to use. But setting up the infrastructure for it – namely password-less ssh logins and database dumps – always requires some work. Here’s how I do it.

There are to parties involved in distributed backups: The source and the destination. The source is where the data is and the destination is where the backup will be stored. rsnapshot will run on the destination and pull the data from the source using rsync and ssh.

The Destination

Let’s start with the destination. First install rsnapshot. On Debian/Ubuntu:

sudo aptitude install rsnapshot

Next we create a backup user. This is not required, however it helps me to have all configuration at one spot: The home directory of that user.

sudo useradd -d /home/rsnapshot -s /bin/bash rsnapshot
sudo passwd rsnapshot
sudo mkdir /home/rsnapshot
sudo chown rsnapshot:rsnapshot /home/rsnapshot

Now we log in as this user, e.g. via

sudo -i -u rsnapshot

For password-less ssh logins the rsnapshot user requires an ssh key:

ssh-keygen

Per default this key will be stored under ~rsnapshot/.ssh/id_rsa – this is fine. Make sure you don’t enter any password for this key.

The Source

The source host requires rsync to be installed. It doesn’t hurt however to install rsnapshot as well. It also requires an rsnapshot user. Please follow the steps from “The Destination” on the source to install rsnapshot and create the user.

Now login as rsnapshot user:

sudo -i -u rsnapshot

Up to now, our source host is ready to accept ssh logins. Let’s setup the password-less login:

Copy the public key from the destination host, e.g. using scp, and append it to the authorized keys:

scp rsnapshot@destination_host:.ssh/id_rsa.pub .
cat id_rsa.pub >> ~/.ssh/authorized_keys
rm id_rsa.pub

Now edit the authorized_keys file to only allow specific commands be run by the rsnapshot user:

command="/home/rsnapshot/.ssh/validate-ssh.sh" ssh-rsa AAAAB3Nz...

And here is the script to filter commands. It will only allow rsync --server and mysqldump.

chmod +x ~/.ssh/validate-ssh.sh:

#!/bin/sh

case "$SSH_ORIGINAL_COMMAND" in
*\&*)
echo "Rejected"
;;
*\(*)
echo "Rejected"
;;
*\{*)
echo "Rejected"
;;
*\;*)
echo "Rejected"
;;
*\<*)
echo "Rejected"
;;
*\`*)
echo "Rejected"
;;
rsync\ --server*)
# the calling user HAST TO BE in the sudoers list for executing rsync!
sudo $SSH_ORIGINAL_COMMAND
;;
mysqldump\ *)
bash -c "$SSH_ORIGINAL_COMMAND"
;;
*)
echo "Rejected $SSH_ORIGINAL_COMMAND"
;;
esac 

Since this script runs the rsync server as root your rsnapshot user needs the following entry in your /etc/sudoers file:

rsnapshot ALL=NOPASSWD: /usr/bin/rsync

The Destination (Part 2)

Now create or edit the rsnapshot configuration file. Usually at /etc/rsnapshot.conf:

config_version  1.2
#
snapshot_root   /var/cache/rsnapshot/
no_create_root  1

cmd_rm          /bin/rm
cmd_rsync       /usr/bin/rsync
cmd_logger      /usr/bin/logger
cmd_ssh         /usr/bin/ssh

ssh_args        -o BatchMode=yes -i /home/rsnapshot/.ssh/id_rsa

#interval       hourly  6
interval        daily   7
interval        weekly  4
#interval       monthly 3

verbose         2
loglevel        3

lockfile        /var/run/rsnapshot.pid

# backup home directory
backup  rsnapshot@source_host:/etc    source_host/
backup  rsnapshot@source_host:/home   source_host/

rsnapshot_root is where your backup is stored. Via ssh_args you tell rsnapshot where the password-less ssh key for the rsnapshop user resides.

At the end of the configuration file are the backup actions to perform. In the example above the etc and home directories will be backed up.

In order to backup your mysql database. Add the following line before all backup lines to your rsnapshot.conf – it will backup all your MySQL databases via mysqldump (make sure to rsync the home directory of the rsnapshot user afterwards!):

backup_script   /usr/bin/ssh -i /home/rsnapshot/.ssh/id_rsa rsnapshot@source_host 'mysqldump -u root --all-databases | gzip --rsyncable' > all.tar.gz    source_host-mysql/

Make sure that there are tabs between backup_script, the command and the storage directory.

Now you can try your setup by invoking rsnapshot as root:

rsnapshot daily

And we’re almost done! Just one more thing to do: Install a cron job to do everything periodically. Create the file /etc/cron.d/rsnapshot:

30 3    * * *           root    /usr/bin/rsnapshot daily
0  3    * * 1           root    /usr/bin/rsnapshot weekly

That’s it! Happy rsnapshoting 😉