Using rsnapshot with a Raspberry Pi to create a backup device

In this posting we are going to turn a Raspberry Pi into a backup device, using the excellent rsnapshot utility to save full and incremental backups to an external USB hard drive. More information about rsnapshot can be found at http://www.rsnapshot.org/.

Preparation of the Raspberry Pi

  • Follow the instructions at How to install the Raspbian OS on a Raspberry Pi.
  • Change the hostname of your Raspberry Pi to something more meaningful by logging on to the device as user “pi” and issuing the command:

    sudo raspi-config

  • Select “Advanced Options” and set the following:
    • Hostname = pi-rsync (or whatever you want to call it).
  • Select Finish
  • Reboot the Raspberry Pi

Install rsnapshot

  • Installing the rsnapshot package is as easy as entering the command:

    sudo apt-get install rsnapshot

  • On completion, create a directory in which the backups will be stored. For the moment we will back up to the /tmp/ directory on the Raspberry Pi’s SD card, but once we are happy it is working, we will mount an external hard disk and back up to that. For now, type:


    mkdir /tmp/backup

    This directory will be lost whenever the Raspberry Pi is rebooted, so it should not be used as a permanent storage location. Also, we want to avoid writing to the SD card as much as possible, as this will shorten it’s working life.

Configure the backup

  • Create an rsnapshot configuration file by entering the command:


    sudo vi /etc/rsnapshot.conf.pi-rsync

    …and paste the following into the file (note that tab characters are used between the parameters, NOT spaces. Spaces will cause rsnapshot to fail when you test it):

    #################################################
    # rsnapshot.conf - rsnapshot configuration file #
    #################################################
    # #
    # PLEASE BE AWARE OF THE FOLLOWING RULES: #
    # #
    # This file requires tabs between elements #
    # #
    # Directories require a trailing slash: #
    # right: /home/ #
    # wrong: /home #
    # #
    #################################################

    #######################
    # CONFIG FILE VERSION #
    #######################

    config_version 1.2
    ###########################
    # SNAPSHOT ROOT DIRECTORY #
    ###########################

    # All snapshots will be stored under this root directory.
    snapshot_root /tmp/backup/
    # If no_create_root is enabled, rsnapshot will not automatically create the
    # snapshot_root directory. This is particularly useful if you are backing
    # up to removable media, such as a FireWire or USB drive.
    no_create_root 1
    cmd_cp /bin/cp
    cmd_rm /bin/rm
    cmd_rsync /usr/bin/rsync
    cmd_ssh /usr/bin/ssh
    cmd_logger /usr/bin/logger
    cmd_du /usr/bin/du
    #interval hourly 6
    interval daily 7
    interval weekly 4
    interval monthly 12
    interval yearly 2
    verbose 2
    loglevel 3
    logfile /var/log/rsnapshot
    lockfile /var/run/rsnapshot.pid
    ssh_args -o BatchMode=yes
    #include ???
    #include ???
    #exclude ???
    #exclude ???
    #include_file /path/to/include/file
    #exclude_file /path/to/exclude/file
    backup /home/pi/ pi-rsync/

  • Test that the backup works with the command:


    sudo /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync daily

    The last line of the configuration file told rsnapshot to copy the /home/pi/ directory to the directory pi-rsync/ under /tmp/backup/ (which is the “snapshot_root” directory).

  • If the test succeeded, you will find the backup by typing the command:


    sudo ls -l /tmp/backup/pi-rsync

    Below this you will find the directory daily.0 which contains a complete replica of the /home/pi/ directory. If you run the test again, daily.0 will be moved to daily.1, and a new daily.0 will be created with the same files. However, because the files are linked, and they haven’t changed, the backup will be no larger than before. Clever, eh?

Change the backup destination to an external USB drive

Once you have confirmed that rsnapshot is working correctly, an external USB hard disk can be mounted on the Pi to allow for far greater storage capacity for backups. Ideally, the USB hard drive that you choose should be mains powered, as the Pi cannot provide much power to external devices. Alternatively, a powered USB hub could be used as an intermediary between the Pi and the USB drive.

  • Follow the instructions at How to mount and automount a USB hard drive on the Raspberry Pi.
  • Ensure that the USB drive is mounted to /mnt/USB/
  • Change the rsnapshot configuration file by entering the command:


    sudo vi /etc/rsnapshot.conf.pi-rsync

    …and change the line:

    snapshot_root /tmp/backup/

    …to:

    snapshot_root /mnt/USB/

  • Test that the backup still works with the command:


    sudo /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync daily

    Because we changed “snapshot_root” directory, you should now fine the backup under /mnt/USB/pi-rsync/daily.0

Add pi-owncloud to the backup

In the next set of instructions, we will configure backing up the ownCloud server we created in How to install ownCloud on a Raspberry Pi. Here, we will backup the /var/www/owncloud/ directory owned by the user “www-data” and an export of the database, which is saved to the /home/pi/ directory and owned by the user "pi".

On the pi-rsync device:

  • Open a command shell as the root user, create a directory in which to store our key pairs, and then change to that directory:


    sudo bash
    mkdir -p ~/.ssh
    cd ~/.ssh

  • Create a key pair which will be used for authorizing access from pi-rsync to pi-owncloud:


    ssh-keygen -t dsa -b 1024 -f ./pi-owncloud-rsnapshot-key

    (Press "Enter" when asked for a passphrase, leaving the passphrase empty).

  • Now type the command:


    vi ~/.ssh/config

    ...and paste the following to the end of the file:

    Host remotehost-rsnapshot-pi-owncloud
    Hostname 192.168.0.129
    IdentityFile /root/.ssh/pi-owncloud-rsnapshot-key

    Save it, and exit vi.

  • Change the permissions, to increase security:


    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/*-rsnapshot-key

  • Exit the root user:

    exit

On the pi-owncloud device:

  • Schedule a backup of the owncloud SQLLite database to occur every day at 10:50, by opening the crontab file:


    sudo crontab -e

    ...and adding the following:


    50 10 * * * sqlite3 /var/www/owncloud/data/owncloud.db .dump > /home/pi/owncloud-sqlbkp.bak

    Save it, and exit vi. Note that this backup will be overwritten every day on the Raspberry Pi, but that's fine because it will be backed up daily to pi-rsync.

  • Add the content of the file /root/.ssh/pi-owncloud-rsnapshot-key.pub on pi-rsync to the file /home/pi/.ssh/authorized_keys on pi-owncloud
  • Add the content of the file /root/.ssh/pi-owncloud-rsnapshot-key.pub on pi-rsync to the file /var/www/.ssh/authorized_keys on pi-owncloud
  • Ensure that user "www-data" can connect to the pi-owncloud device via ssh. Issue the following command:


    sudo vi /etc/ssh/sshd_config

    ...and change the "AllowUsers" line to include "www-data", for example:

    AllowUsers pi www-data

  • Restart ssh by running the command:

    sudo service ssh restart

On the pi-rsync device:

  • Test that you can connect to pi-owncloud as user "pi" from pi-rsync with the command:


    sudo ssh pi@remotehost-rsnapshot-pi-owncloud

    ...and test that you can also connect to pi-owncloud as user "www-data" from pi-rsync with the command:

    sudo ssh www-data@remotehost-rsnapshot-pi-owncloud

    ...and when you have confirmed that you have opened a shell on the remote server, quit the remote shell with the command:

    exit

Restrict access to pi-owncloud by IP address

  • Tighten up the security a little, so that only the IP address of pi-rsync can connect to pi-owncloud using this key. You need to know the IP address of pi-rsync, which you can get by entering the command:


    ifconfig

  • Edit the authorized_keys file for user "pi" on the pi-owncloud device by entering the command:


    sudo vi /home/pi/.ssh/authorized_keys

    ...and insert the following at the very start of the key you just pasted in the previous section. Note that there is a trailing space character after the last double-quote, and that you need to replace the IP address with that of your own pi-rsync:

    from="192.168.0.105"

  • Test the connection again from pi-rsync with the command:


    sudo ssh pi@remotehost-rsnapshot-pi-owncloud

    ...and when you have confirmed that you have opened a shell on the remote server, quit the remote shell with:

    exit

  • Now do the same for the "www-data" user. Edit the authorized_keys file for user "pi" on the pi-owncloud device by entering the command:


    sudo vi /var/www/.ssh/authorized_keys

    ...and insert the following at the very start of the key you just pasted in the previous section. Note that there is a trailing space character after the last double-quote, and that you need to replace the IP address with that of your own pi-rsync:

    from="192.168.0.105"

  • Test the connection again from pi-rsync with the command:


    sudo ssh www-data@remotehost-rsnapshot-pi-owncloud

    ...and when you have confirmed that you have opened a shell on the remote server, quit the remote shell with:

    exit

Restrict the commands that can be run by pi-rsync on pi-owncloud

  • To tighten up security further, so that only rsync commands can be run on pi-owncloud using this key, edit the authorized_keys file on pi-owncloud with:


    sudo vi /home/pi/.ssh/authorized_keys

    ...and change the command at the start of the key with the following. Note that there is a trailing space character after the last double-quote, and that you need to replace the IP address with that of your own pi-rsync:

    from="192.168.0.105",command="/usr/local/sbin/validate-rsync"

  • Now do the same for the key in www-data.edit the authorized_keys file on pi-owncloud with:


    sudo vi /var/www/.ssh/authorized_keys

    , and change the command at the start of the key with the following. Note that there is a trailing space character after the last double-quote, and that you need to replace the IP address with that of your own pi-rsync:

    from="192.168.0.105",command="/usr/local/sbin/validate-rsync"
    .

  • Now run the following on pi-owncloud:


    sudo vi /usr/local/sbin/validate-rsync

    ...and paste the following into the file:

    #!/bin/sh

    case "$SSH_ORIGINAL_COMMAND" in
    *\&*)
    echo "Rejected"
    ;;
    *\(*)
    echo "Rejected"
    ;;
    *\{*)
    echo "Rejected"
    ;;
    *\;*)
    echo "Rejected"
    ;;
    *\<*)
    echo "Rejected"
    ;;
    *\`*)
    echo "Rejected"
    ;;
    *\|*)
    echo "Rejected"
    ;;
    rsync\ --server*)
    $SSH_ORIGINAL_COMMAND
    ;;
    *)
    echo "Rejected"
    ;;
    esac

  • Change the permission with: sudo chmod +x /usr/local/sbin/validate-rsync

Configure rsnapshot to run

  • Add the following 3 lines to the bottom of /etc/rsnapshot.conf.pi-rsync on pi-rsync (the spaces between the fields must actually be tabs)


    # pi-owcloud = ownCloud server on pi
    backup www-data@remotehost-rsnapshot-pi-owncloud:/var/www/owncloud pi-owncloud/
    backup pi@remotehost-rsnapshot-pi-owncloud:/home/pi/ pi-owncloud/

  • Test that the backup works with:


    sudo /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync daily

Configure cron

  • open the crontab by typing the command:


    sudo crontab -e

    ...and paste the following into the file:


    45 22 * * * /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync daily
    30 22 * * 0 /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync weekly
    15 22 1 * * /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync monthly
    0 22 1 12 * /usr/bin/rsnapshot -c /etc/rsnapshot.conf.pi-rsync yearly

    Save and exit the file

Leave a comment