Using rdiff-backup for remote backups

In the previous section we investigated how we could perform local backups using the rdiff-backup application. Performing a backup of a computer system to itself is of limited value however. A failure of a major system component could still result in total data loss as could any number of software malfunctions or malicious actions. A more secure backup strategy would be to backup the contents of one machine to another, preferably in a different physical location.

In this section we shall examine how we can implement such a system using the rdiff-backup application. We shall be making use of the scripts and configurations we developed in the previous section so if you have not followed that section of the guide you will need to refer to it now.

Configuring password-less login over SSH

Before the rdiff-backup application can backup the contents of a remote computer we need to make those contents available over the network. We could do this by simply exposing the entire filesystem using nfs or some other file sharing system. On a trusted network this may be acceptable but should still be strongly discouraged as read access to all files would be essentially granted to everyone with appropriate access rights.

A better approach is to use rdiff-backup over ssh so that the files are encrypted in transit and the access control features of ssh can be leveraged. As the ssh application usually requires a password to log-in the first step is therefore to configure password-less log-in (on each of our client machines) for a new user, called backup, which shall be used to perform remote backups.

Information:
If you have already followed the Using rsnapshot for remote backups section of this guide a great many of the following tasks will have already been completed. There is no need to complete them again, however it is still useful to verify that they have been performed as this section is fairly complex and a small error can lead to a hard to diagnose problem when completing later stages. Obviously, all additional tasks require completion for this guide to work as expected.
 

The first step in this process is to create a new ssh key pair on the backup server as shown in the example below. This key pair will be used to log in to all the client machines we will be backing up without using a password.

backup ssh-keygen -t dsa -N "" -f ~/.ssh/backup_key_dsa

Next we need to create a new user on each of the client machines we shall be backing up so that we can log in using the same login details. In the example below we have called this user backup. As you can see we have specified that they will have a predefined user id, in this case 900, will not have a corresponding group created and will only be a member of the nogroup group. We have also created them a home directory which is critical if we are to log in automatically without a password.

client useradd --create-home --no-user-group --gid nogroup --uid 900 backup

Now that we have created the backup user accounts on all of our client machines we can copy the public part of the key pair we created earlier to the ~/.ssh/authorized_keys file for those user accounts. This will enable us to log-in to that account using the private part of the key pair which we still have only on the backup server.

backup scp ~/.ssh/backup_key_dsa.pub root@client:/home/backup/.ssh/authorized_keys

We can test that the configuration is correct and that password-less log-in is working for the backup user when connecting from the backup server to the clients by using the command shown in the example below.

backup ssh backup@client -i ~/.ssh/backup_key_dsa
backup@client exit

As the rdiff-backup application knows nothing about our password-less log-in configuration we need to make it the default for all connection attempts to the client host. This can be easily accomplished with the following modifications to the ~/.ssh/config file for the root user on the backup server.

~/.ssh/config
host client
user backup
identityfile /root/.ssh/backup_key_dsa

For security reasons only the user who owns the ~/.ssh/config file should have access to it. The permissions can be changed so that this is the case using the chmod command shown below.

lisa chmod 0600 ~/.ssh/config

We can test our configuration one last time to ensure that all connections to the client host from the root user of the backup server connect correctly as the backup user when no username is specified on the command line without asking for a password.

backup ssh client
backup@client exit

Restricting the backup user's abilities

Whilst granting the backup user the ability to log-in without a password is very convenient it does pose a certain security risk. Should the private part of the key pair we have configured for password-less log-in be compromised anyone could log-in to any of our clients and have full run of the system as if they were the backup user. Clearly we cannot prevent anyone with the private key from logging-in, they are as legitimate as anyone else as far as we can tell, but we can restrict where they connect from and what they can do once connected.

The modifications to the ~/.ssh/authorized_keys file shown below will restrict the use of password-less log-in to the machine at 10.0.1.10 (you will need to replace this with the network address of your backup server) and will then further restrict the abilities of that connection by automatically running the command specified instead of providing full shell access.

Information:
If you have already followed the Using rsnapshot for remote backups section of this guide you will already have made the following modification to the /home/backup/.ssh/authorized_keys file and created a /home/backup/validate-backup-cmd.sh script. There is no need to edit this file again as we already know it works so simply skip the remainder of this section.
 
/home/backup/.ssh/authorized_keys
ssh-dss AAAAB3NzaC1kc3MAAACBANmhP/Q19dajVhWDfqe1GSpXZ4sTlLZBYHr85u9mqdd+tj1a/hP9AUjs8vWwrrQYZFgsQnPjQco+Q+BhRc7KcU4ESG+qrJ
from="10.0.1.10",command="/home/backup/validate-backup-cmd.sh" ssh-dss AAAAB3NzaC1kc3MAAACBANmhP/Q19dajVhWDfqe1GSpXZ4sTlLZBYHr8

Clearly we now need to create the script we specified in the command parameter when we made our modification above. The example below, which we shall be using for testing purposes, simply runs the original command that we attempted to execute.

/home/backup/validate-backup-cmd.sh
#! /bin/bash

$SSH_ORIGINAL_COMMAND

We also need to make the script we just created executable as shown below.

client chmod +x /home/backup/validate-backup-cmd.sh

We can now test that our password-less log-in is still functioning as expected using the example command shown below. We have specified that the hostname command should be executed on the remote machine which should provide a good indication that things worked.

backup ssh client hostname
client 

Enabling the backup user to rdiff as root

Although the backup user can now connect to our clients from our server without using a password and can run, at the moment at least, any command they choose they still cannot access all the files that might be required to backup a complete system. To enable the backup user to access these files we must first install the sudo application, if it is not already installed, as shown below.

client emerge -pv sudo
These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild      ] app-admin/sudo-1.7.4_p5  USE="pam -ldap -offensive -skey"
 
client emerge sudo

We can now modify the script we created earlier to validate the passed command to ensure that it is in fact an rdiff-backup command. Assuming that it is we then use sudo to run the rdiff-backup application (with the --server and --restrict-read-only / parameters) as the root user thus enabling secure, read-only access to all files.

/home/backup/validate-backup-cmd.sh
#! /bin/bash

$SSH_ORIGINAL_COMMAND
case "$SSH_ORIGINAL_COMMAND" in
*\&*|*\|*|*\;*|*\>*|*\<*|*\!*)
exit 1
;;
rdiff-backup\ --server*)
sudo /usr/bin/rdiff-backup --server --restrict-read-only /
;;
*)
exit 1
;;
esac
Information:
If you have already followed the Using rsnapshot for remote backups section of this guide you will already have a /home/backup/validate-backup-cmd.sh file. If you wish to continue to use the remote rsnapshot system we implemented in that section then simply add a new entry for the rdiff-backup --server to the existing script. You can also skip the test of sudo below.
 

The script can be tested before we configure sudo to allow the backup user to execute rdiff-backup with root privileges using the command below.

backup ssh client rdiff-backup --server
sudo: no tty present and no askpass program specified 

Assuming that all goes well, and we see the above error message from sudo indicating that we have neither a tty available or an askpass program specified, we can edit the sudoers file on the client using the visudo command as shown below.

client visudo

The example entry below will allow the backup user to execute the /usr/bin/rsync application as the root user with no password.

/etc/sudoers.tmp
# User privilege specification
root ALL=(ALL) ALL

backup ALL=(root) NOPASSWD: /usr/bin/rdiff-backup

We can test that our configuration is correct using the command below. As you can see the rdiff-backup application does not actually start in server mode as we have added the command line option --test-server to prevent this.

backup rdiff-backup --test-server backup@client::/
Testing server started by:  ssh backup@client rdiff-backup --server 
Server OK 

Example remote rdiff-backup

Now that the configuration has been completed actually making a backup using the rdiff-backup application is simplicity itself, as you can see from the example below. To reduce CPU overhead we have disabled compression for the ssh transport (using the --ssh-no-compression option) and, so that we have a better understanding of what the rdiff-backup application has done, have requested that some statistics are displayed when the backup is complete (using the --print-statistics option).

backup rdiff-backup --ssh-no-compression --print-statistics backup@client::/home/user /mnt/rdiffs/user
--------------[ Session statistics ]-------------- 
StartTime 1310052862.00 (Thu Jul  7 15:34:22 2011) 
EndTime 1310055261.51 (Thu Jul  7 16:14:21 2011) 
ElapsedTime 2399.51 (39 minutes 59.51 seconds) 
SourceFiles 4360 
SourceFileSize 24117590719 (22.5 GB) 
MirrorFiles 1 
MirrorFileSize 0 (0 bytes) 
NewFiles 4359 
NewFileSize 24117590719 (22.5 GB) 
DeletedFiles 0 
DeletedFileSize 0 (0 bytes) 
ChangedFiles 1 
ChangedSourceSize 0 (0 bytes) 
ChangedMirrorSize 0 (0 bytes) 
IncrementFiles 0 
IncrementFileSize 0 (0 bytes) 
TotalDestinationSizeChange 24117590719 (22.5 GB) 
Errors 0 
-------------------------------------------------- 

The do-rdiff-backups script we developed in the previous chapter can also be used to further simplify making remote backups using the rdiff-backup application. An example configuration entry for the backup above, with a retention period of one year, is provided below.

/etc/rdiff-backups
# List of source, destination, retention tuples to be backed up using rdiff-backup

backup@client::/home/user /mnt/rdiffs/user 1Y