Rsnapshot

From Gentoo-en
Jump to: navigation, search

Rsnapshot is a filesystem backup utility based on rsync.

Secure Remote Backups

The following instructions deal with setting up secure backups of remote servers over SSH using an minimally privileged user. These instructions will work equally well over a LAN or the Internet.

The following instructions will set up a user ('rbackup') who is only allowed to run the commands we specify over the SSH connection, so even if an attacker were to gain access to this account, they would not be able to run any commands other than rsync.

This guide assumes that the remote server is already set up with SSH Public Key Authentication and that sudo is set up on the remote server.

rsnapshot runs as root on the backup server so that it has full permissions to change the ownership and permissions on backed up files to match those on the remote server.

Terminology used:

  • remote server: The server that is being backed up.
  • backup server: The server which performs the backups.

The following instructions can be easily repeated to setup backups for as many remote servers as desired.

Remote Server Setup

The commands in the following section are all executed on the remote server.

The rsync utility is used by portage for syncing the package tree, so every Gentoo system has it installed by default.

This guide uses 'rbackup' for the remote username. You can replace this with another username. It is suggested you avoid 'backup' as this is a common username tested for by attackers.

useradd -s /bin/bash -m rbackup

Next we set up some utility scripts which are used to check the command being called over SSH connections.

The first script sets up the rbackup user so they can only call the rsync_wrapper.sh script over the SSH connection:

File: /home/rbackup/validate-rsync.sh
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
  *\&*)
    echo "Rejected 1"
    ;;
  *\;*)
    echo "Rejected 2"
    ;;
  /usr/local/bin/rsync_wrapper*)
    $SSH_ORIGINAL_COMMAND
    ;;
  *true*)
    echo $SSH_ORIGINAL_COMMAND
    ;;
  *)
    echo "Rejected 3"
    ;;
esac

Set the permissions on the script:

chown rbackup:rbackup /home/rbackup/validate-rsync.sh chmod 755 /home/rbackup/validate-rsync.sh

Now for the second script:

File: /usr/local/bin/rsync_wrapper.sh
#!/bin/sh
/usr/bin/sudo /usr/bin/rsync "$@";
chmod 755 /usr/local/bin/rsync_wrapper.sh


Next we set up sudo to allow the rbackup user to call rsync as root without a password by adding the following to the end of /etc/sudoers:

File: /etc/sudoers
rbackup ALL = NOPASSWD: /usr/bin/rsync

Note that the rbackup user is not allowed to call any other commands with sudo - only rsync.

Remote User Authentication

As a final step for setting up the user, we need to set up a password-less authentication key. While password-less keys are considered less secure than passworded keys, they provide the best level of security that allows us to run non-interactive scripts.

We generate the key on the backup server so that the private portion of the key never leaves this server. This will be the only server where both portions of the key are present as files.

Execute the following commands on the backup server to create the key and move it to a unique filename so that we don't accidentally overwrite it:

ssh-keygen -t rsa mv /root/.ssh/id_rsa.pub /root/.ssh/id_rsa_rsnapshot.pub mv /root/.ssh/id_rsa /root/.ssh/id_rsa_rsnapshot

Copy the public key (.pub file) only to /home/rbackup/.ssh/id_rsa_rsnapshot.pub on the remote server and then run the following commands on the remote server:

cat /home/rbackup/.ssh/id_rsa_rsnapshot.pub >> /home/rbackup/.ssh/authorized_keys rm /home/rbackup/.ssh/id_rsa_rsnapshot.pub chown rbackup:rbackup /home/rbackup/.ssh/authorized_keys chmod 600 /home/rbackup/.ssh/authorized_keys

Note that if you do not set the permissions correctly on the authorized_keys file, SSH will consider it insecure and refuse to read it.

Edit the /home/rbackup/.ssh/authorized_keys file and prepend the following to the last line (up to but not including the 'ssh-rsa' text):

File: /home/rbackup/.ssh/authorized_keys
from="192.168.1.11",command="/home/rbackup/validate-rsync.sh" ssh-rsa ...

Replace 192.168.1.11 with the actual IP address of the backup server (Note that for backups over the Internet, this will be the backup servers Internet connection IP address, not its LAN IP address).


Finally, we set up the SSH client config on the backup server so we don't have to retype it everywhere:

File: /root/.ssh/config
Host remote-server
	HostName remote-server.fqdn
	User rbackup
        IdentityFile ~/.ssh/id_rsa_rsnapshot

Replace the HostName value with the domain name or IP address of the backup server.

You can replace the Host value with whatever you like.

Testing the SSH connection

Warning: You must run at least one test to add the remote server to the known_hosts file or the rsnapshot backup will fail.

To test the SSH connection we set up, run the following commands:

ssh remote-server ssh remote-server /usr/local/bin/rsync_wrapper.sh --version

You will be asked if you want to add the remote server to the known_hosts file. Accept this otherwise the rsnapshot backup will fail.

The first command should respond with Rejected 3. This means the we set up scripts successfully rejected an attempt to open a normal console connection.

The second command should respond with the output of rsync --version, which will look something like this:

rsync  version 3.0.8  protocol version 30
Copyright (C) 1996-2011 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 32-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
    append, ACLs, no xattrs, iconv, symtimes

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.

This indicates that we're allowed to run rsync as root using our wrapper script.

Rsnapshot Setup

Install rsnapshot with:
emerge -a rsnapshot

First of all, we want to set up a basic configuration using the rsnapshot example:

cp /etc/rsnapshot.conf.default /etc/rsnapshot.conf

Set the snapshot_root value to the location where you want backups to be stored (making sure that this directory exists):

rsnapshot_root /mnt/backup/snapshots/

Remove the '#' from the beginning of the lines for cmd_cp, cmd_ssh and cmd_du.

Uncomment the cmd_rsnapshot_diff line and set it to the actual location of rsnapshot-diff:

cmd_rsnapshot_diff /usr/bin/rsnapshot-diff

Comment out the default backup lines by adding a # to the beginning (these backup the local machine, which we're not worried about for the purpose of this guide):

#backup       /home/          localhost/
#backup       /etc/           localhost/
#backup       /usr/local/     localhost/

Now set up the backup line for the remote server. The following example line backs up only /etc/:

backup rbackup@remote-server:/etc/ remote-server/ +rsync_long_args=--rsync-path=/usr/local/bin/rsync_wrapper.sh

Note the + in front of rsync_long_args. This modifier tells rsync to add the extra arguments to the default value, instead or replacing the default value.

Testing rsnapshot

Next we ask rsnapshot to check our configuration file with:

rsnapshot configtest

This command checks that rsnapshot can read the config file correctly. It does not check SSH connections or rsync.

Next we can check the commands that rsnapshot will run:

rsnapshot -t hourly

If you have already set up rsnapshot for other servers, you can skip the final test.

Finally we can perform our first backup. Note that this may take a while:

rsnapshot hourly

After performing the first backup you can check the backup location on the backup server. You should check that the file permissions and ownership look like they match the remote server.


Set up the rsnapshot Cron

Finally we want to set up rsnapshot to run on a regular basis by adding the following to the end of /etc/crontab on the backup server:

0 */4 * * * /usr/local/bin/rsnapshot hourly
50 23 * * * /usr/local/bin/rsnapshot daily
40 23 * * 6 /usr/local/bin/rsnapshot weekly
30 23 1 * * /usr/local/bin/rsnapshot monthly 

See rsnapshots man page for further details on these.

(Optional) Using an Rsync Exclude List

Specifying several backup entries per host to backup different directories can get messy. Instead, you can use the exclude-from feature of rsync to specify a list of files and directories to backup.

First we want a directory to keep our exclude files in:

mkdir /etc/rsnapshot.d/

Next, create the exclude-from list file as /etc/rsnapshot.d/exclude-remote-server:

File: /etc/rsnapshot.d/exclude-remote-server
+ /etc**
+ /root**
+ /home**
+ /var/
+ /var/lib/
+ /var/lib/ip**
+ /var/lib/munin**
+ /var/lib/portage**
+ /var/spool/
+ /var/spool/cron**
+ /var/spool/mail**
+ /var/www**
- *

To summarize, this exclude list will backup all of /etc, /root, /home and selected directories under /var. The final entry excludes all other files.

Finally, add the backup entry to /etc/rsnapshot.conf:

backup rbackup@remote-server:/ +rsync_long_args=--rsync-path=/usr/local/bin/rsync_wrapper.sh --exclude-from=/etc/rsnapshot.d/exclude-remote-server


Troubleshooting

Protocol Version Mismatch

If the backup fails with the message protocol version mismatch -- is your shell clean?, this is likely because either the scripts set up are rejecting the command or another application or script is printing text to the SSH connection (for example a log on message).


Related Links