Rsnapshot
Rsnapshot is a filesystem backup utility based on rsync.
Contents |
[edit] 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.
[edit] 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.
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:
#!/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:
Now for the second script:
#!/bin/sh /usr/bin/sudo /usr/bin/rsync "$@";
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:
rbackup ALL = NOPASSWD: /usr/bin/rsync
Note that the rbackup user is not allowed to call any other commands with sudo - only rsync.
[edit] 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:
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:
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):
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:
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.
[edit] Testing the SSH connection
To test the SSH connection we set up, run the following commands:
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.
[edit] Rsnapshot Setup
Install rsnapshot with:First of all, we want to set up a basic configuration using the rsnapshot example:
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/ +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.
[edit] Testing rsnapshot
Next we ask rsnapshot to check our configuration file with:
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:
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:
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.
[edit] 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.
[edit] (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:
Next, create the exclude-from list file as /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
[edit] Troubleshooting
[edit] 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).
[edit] Related Links
- Eric Hameleers rsnapshot backup solution (basis for remote instructions in this guide)
- rsnapshot Official HOWTO