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 directorypi-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 directorydaily.0
which contains a complete replica of the/home/pi/
directory. If you run the test again,daily.0
will be moved todaily.1
, and a newdaily.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/shcase "$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