Linux.com

Feature

Making secure remote backups with Rsync

By Brice Burgess on November 04, 2004 (8:00:00 AM)

Share    Print    Comments   

Backups are more important than ever these days, as our digital information collections expand. Many Linux users know rsync as a file transfer utility, but rsync can also be an efficient tool for automating remote backups of your Linux, Windows, and even Mac OS X systems.

Providing all went well, it's time to make a real backup. We'll modify the backup.sh script from my earlier article to allow our backup to be stored remotely. Create an rbackup.sh script by copying the code below into your favorite text editor. Decide on the files and directories you'd like to back up and add them to the $SOURCES variable in the script:

#!/bin/sh
# Author: Brice Burgess - bhb@iceburg.net
# rbackup.sh -- secure backup to a remote machine using rsync.

# Directories to backup. Separate with a space. Exclude trailing slash!
SOURCES="/home/wendy /home/daisy /var/mail"

# IP or FQDN of Remote Machine
RMACHINE=192.168.0.2

# Remote username
RUSER=brice

# Location of passphraseless ssh keyfile
RKEY=/home/user/rsync-key

# Directory to backup to on the remote machine. This is where your backup(s) will be stored
# Exclude trailing slash!
RTARGET="/home/user/backups/my_machine"

# Your EXCLUDE_FILE tells rsync what NOT to backup. Leave it unchanged, missing or
# empty if you want to backup all files in your SOURCES. If performing a
# FULL SYSTEM BACKUP, ie. Your SOURCES is set to "/", you will need to make
# use of EXCLUDE_FILE. The file should contain directories and filenames, one per line.
# An example of a EXCLUDE_FILE would be:
# /proc/
# /tmp/
# /mnt/
# *.SOME_KIND_OF_FILE
EXCLUDE_FILE="/path/to/your/exclude_file.txt"

# Comment out the following line to disable verbose output
VERBOSE="-v"

#######################################
########DO_NOT_EDIT_BELOW_THIS_POINT#########
#######################################

if [ ! -f $RKEY ]; then
  echo "Couldn't find ssh keyfile!"
  echo "Exiting..."
  exit 2
fi

if ! ssh -i $RKEY $RUSER@$RMACHINE "test -x $RTARGET"; then
  echo "Target directory on remote machine doesn't exist or bad permissions."
  echo "Exiting..."
  exit 2
fi

echo "Verifying Sources..."
for source in $SOURCES; do
	echo "Checking $source..."
	if [ ! -x $source ]; then
     echo "Error with $source!"
     echo "Directory either does not exist, or you do not have proper permissions."
     exit 2
   fi
done

if [ -f $EXCLUDE_FILE ]; then
EXCLUDE="--exclude-from=$EXCLUDE_FILE"
fi

echo "Sources verified. Running rsync..."
for source in $SOURCES; do

  # Create directories in $RTARGET to mimick source directory hiearchy
  if ! ssh -i $RKEY $RUSER@$RMACHINE "test -d $RTARGET/$source"; then
    ssh -i $RKEY $RUSER@$RMACHINE "mkdir -p $RTARGET/$source"
  fi

  rsync $VERBOSE $EXCLUDE -a --delete -e "ssh -i $RKEY" $source/ $RUSER@$RMACHINE:$RTARGET/$source/

done

exit 0

Change the $RMACHINE, $RTARGET, $RUSER, and $RKEY variables to appropriate values. Save the script (as rbackup.sh) to your computer and make it executable by typing: chmod +x backup.sh.

If your local machine uses Mac OS X, these methods should work for you within the terminal program. If you're using Windows, the cwRsync installer creates a file named cwrsync.cmd that you can customize as a backup script. Save this file as a batch (.bat) file.

Execute your backup script by typing ./rbackup.sh on the Linux or OS X terminal, or run your batch script from the Windows command prompt. It will take a long time for the script to complete the first time it runs, because rsync must make a copy of each file rather than solely updating changed files. Later runs will complete much faster.

If you notice something is wrong, press Ctrl-C to stop the process. Upon completion of the script, there should be a replica of your $SOURCES on the remote machine.

Automating the process

Assuming rbackup.sh ran successfully, it's time to automate the process. Use the Scheduled Task accessory to run your batch file under Windows. For Linux and OS X, use the cron daemon to schedule backups. The cron daemon uses crontab files to schedule tasks. You can edit the system's main crontab file by becoming the superuser (either by logging in as root or typing su in the terminal) and executing crontab -e to edit the file with your system's default editor.

You'll want to schedule a time for your rbackup.sh to execute. Crontab syntax is:

[minute] [hour] [day] [month] [dow] [command]

Thus, adding the line

0 4 * * * /path/to/rbackup.sh

will execute rbackup.sh at 4:00 a.m. every day, and

0 4 * * 5 /path/to/rbackup.sh

will execute rbackup.sh at 4:00 a.m. every Friday. When you've finished adding the line, save the file and exit.

Keeping multiple backups

You may want to implement multiple remote backups if there is enough space at the destination to hold them. Multiple backups, known as 'snapshots' are important to have in case you've accidently deleted files you'd like to retain. Check the size of your backup by executing:du -sh /rsync/target_directory on the machine holding your backups. You can estimate the number of days to retain by dividing the amount of space you're willing to allocate to backups by your backup size and rounding down to the integer value. If you have the space, keep snapshots of your five past backups.

I've modified the above script to accommodate for multiple backup rotation. The modifications keep a designated number of backups in the remote machine's target directory named after the date they were executed (YYYY-MM-DD_Hour-Minute). Here's the modified script:

#!/bin/sh
# Author: Brice Burgess - bhb@iceburg.net
# multi_rbackup.sh -- secure backup to a remote machine using rsync.
# Uses hard-link rotation to keep multiple backups on the remote machine.

# Directories to backup. Separate with a space. Exclude trailing slash!
SOURCES="/home/wendy /home/daisy /var/mail"

# IP or FQDN of Remote Machine
RMACHINE=192.168.0.2

# Remote username
RUSER=brice

# Location of passphraseless ssh keyfile
RKEY=/home/user/rsync-key

# Directory to backup to on the remote machine. This is where your backup(s) will be stored
# :: NOTICE :: -> Make sure this directory is empty or contains ONLY backups created by
#	                        this script and NOTHING else. Exclude trailing slash!
RTARGET="/home/user/backups/my_machine"

# Set the number of backups to keep (greater than 1). Ensure you have adaquate space.
ROTATIONS=3

# Your EXCLUDE_FILE tells rsync what NOT to backup. Leave it unchanged, missing or
# empty if you want to backup all files in your SOURCES. If performing a
# FULL SYSTEM BACKUP, ie. Your SOURCES is set to "/", you will need to make
# use of EXCLUDE_FILE. The file should contain directories and filenames, one per line.
# An example of a EXCLUDE_FILE would be:
# /proc/
# /tmp/
# /mnt/
# *.SOME_KIND_OF_FILE
EXCLUDE_FILE="/path/to/your/exclude_file.txt"

# Comment out the following line to disable verbose output
VERBOSE="-v"

#######################################
########DO_NOT_EDIT_BELOW_THIS_POINT#########
#######################################

if [ ! -f $RKEY ]; then
  echo "Couldn't find ssh keyfile!"
  echo "Exiting..."
  exit 2
fi

if ! ssh -i $RKEY $RUSER@$RMACHINE "test -x $RTARGET"; then
  echo "Target directory on remote machine doesn't exist or bad permissions."
  echo "Exiting..."
  exit 2
fi

# Set name (date) of backup.
BACKUP_DATE="`date +%F_%H-%M`"

if [ ! $ROTATIONS -gt 1 ]; then
  echo "You must set ROTATIONS to a number greater than 1!"
  echo "Exiting..."
  exit 2
fi

#### BEGIN ROTATION SECTION ####

BACKUP_NUMBER=1
# incrementor used to determine current number of backups

# list all backups in reverse (newest first) order, set name of oldest backup to $backup
# if the retention number has been reached.
for backup in `ssh -i $RKEY $RUSER@$RMACHINE "ls -dXr $RTARGET/*/"`; do
	if [ $BACKUP_NUMBER -eq 1 ]; then
		NEWEST_BACKUP="$backup"
	fi

	if [ $BACKUP_NUMBER -eq $ROTATIONS ]; then
		OLDEST_BACKUP="$backup"
		break
	fi

	let "BACKUP_NUMBER=$BACKUP_NUMBER+1"
done

# Check if $OLDEST_BACKUP has been found. If so, rotate. If not, create new directory for new backup.
if [ $OLDEST_BACKUP ]; then
  # Set oldest backup to current one
  ssh -i $RKEY $RUSER@$RMACHINE "mv $OLDEST_BACKUP $RTARGET/$BACKUP_DATE"
else
  ssh -i $RKEY $RUSER@$RMACHINE "mkdir $RTARGET/$BACKUP_DATE"
fi

# Update current backup using hard links from the most recent backup
if [ $NEWEST_BACKUP ]; then
  ssh -i $RKEY $RUSER@$RMACHINE "cp -al $NEWEST_BACKUP. $RTARGET/$BACKUP_DATE"
fi

#### END ROTATION SECTION ####

# Check to see if rotation section created backup destination directory
if ! ssh -i $RKEY $RUSER@$RMACHINE "test -d $RTARGET/$BACKUP_DATE"; then
  echo "Backup destination not available."
  echo "Make sure you have write permission in RTARGET on Remote Machin  e."
  echo "Exiting..."
  exit 2
fi

echo "Verifying Sources..."
for source in $SOURCES; do
	echo "Checking $source..."
	if [ ! -x $source ]; then
     echo "Error with $source!"
     echo "Directory either does not exist, or you do not have proper permissions."
     exit 2
   fi
done

if [ -f $EXCLUDE_FILE ]; then
EXCLUDE="--exclude-from=$EXCLUDE_FILE"
fi

echo "Sources verified. Running rsync..."
for source in $SOURCES; do

  # Create directories in $RTARGET to mimick source directory hiearchy
  if ! ssh -i $RKEY $RUSER@$RMACHINE "test -d $RTARGET/$BACKUP_DATE/$source"; then
    ssh -i $RKEY $RUSER@$RMACHINE "mkdir -p $RTARGET/$BACKUP_DATE/$source"
  fi

  rsync $VERBOSE $EXCLUDE -a --delete -e "ssh -i $RKEY" $source/ $RUSER@$RMACHINE:$RTARGET/$BACKUP_DATE/$source/

done

exit 0

Rsync is a powerful tool not only for file transfers, but also for advanced and secure backups to remote machines. If you would like to learn more about backing up with rsync, Mike Rubel provides a great tutorial and reference section on his Web site.

 

Share    Print    Comments   

Comments

on Making secure remote backups with Rsync

Note: Comments are owned by the poster. We are not responsible for their content.

validate-rsync.sh needs password?

Posted by: Anonymous Coward on November 19, 2004 06:43 PM
Your instructions work very well. Thank you for that. However, when I include command="../validate-rsync.sh" in authorized_keys I am prompted for a password.

#

Re:validate-rsync.sh needs password?

Posted by: Anonymous Coward on February 21, 2005 08:17 PM
You can solve this problem by removing the blank space between from and command. Only the comma is allowed as separator.

Another thing I ran into was that the rotational backup is not working with the validate-rsync.sh. Unfortunately I have no experience in shell scripts, so I would be glad if someone could fix this.

#

Re:validate-rsync.sh needs password?

Posted by: Administrator on December 01, 2004 11:50 AM
For the security purpose can't we have all the source file and module restrictions in the rsyncd.conf file on the server side. This will make sure that no files are written or pulled out by the wrong person. Correct me if i am wrong.

#

great article, very useful script, keep it up!

Posted by: Anonymous Coward on January 17, 2006 02:02 AM
subject says it all<nobr> <wbr></nobr>;).

#

indentity file issues

Posted by: Anonymous Coward on September 10, 2006 08:17 AM
After following the directions I'm able to issue this command and reach my remote server w/out a password.
<tt>ssh -i ~/.ssh/rsync-key user@remotehost.com</tt>
but I get an error if I try:
<tt>rsync -avz -e "ssh -i ~/.ssh/rsync-key"<nobr> <wbr></nobr>/local/dir/ user@remotehost.com:/remote/dir/</tt>
The error is:
<tt>Warning: Identity file ~/.ssh/rsync-key not accessible: No such file or directory.</tt>
Why would the first work but not the second?

#

Re:indentity file issues

Posted by: Anonymous Coward on November 01, 2006 03:49 AM
I too am having this issue. did you ever find your answer? Anyone else able to help?

It works fine with the ssh connection command but fails in the rsync connection attempt.

#

Re:indentity file issues

Posted by: Anonymous Coward on December 10, 2006 08:28 AM
The reason is the ~ in the string. On the position it want be expanded by the shell. Replace it with $HOME or direct with you home dir name.

#

Re:indentity file issues

Posted by: Anonymous Coward on November 15, 2006 01:42 PM
Hi
my solution was
this<nobr> <wbr></nobr>:rsync -avz -e "ssh -i<nobr> <wbr></nobr>/root/rsync-key"<nobr> <wbr></nobr>/local/dir/ user@remotehost.com:/remote/dir/

if it's not working try
rsync -avz -e "ssh -v -i<nobr> <wbr></nobr>/root/rsync-key"<nobr> <wbr></nobr>/local/dir/ user@remotehost.com:/remote/dir/

I hop I help you

#

had to modify your script to get it working

Posted by: Anonymous Coward on October 02, 2006 12:26 PM
I had an error with your multi_rbackup.sh script and had to modify it slightly.

The fix was simply to add a trailing slash to this line:

ssh $RUSER@$RMACHINE "cp -al $NEWEST_BACKUP. $RTARGET/$BACKUP_DATE/"

Without the trailing slash, this command would create a time-stamped backup directory based on $NEWEST_BACKUP _inside_ the new $BACKUP_DATE directory.

Otherthan that this script works perfectly.

Thanks for sharing!

#

Do not recommend passphrase-less SSH keys, please!

Posted by: Administrator on November 10, 2004 11:09 AM
A fine article, but telling people to use no passphrase on their SSH keys is unwise at best. It certainly does not make a "secure" backup. A good passphrase on a key (SSH, GPG, whatnot) makes all the difference.


Using tools like <A HREF="http://www.gentoo.org/proj/en/keychain/index.xml" title="gentoo.org">keychain</a gentoo.org> or some other manipulation of ssh-agent on the backup repository and pulling the data negates the temptation to use such an insecure method.

#

ravindra mudumby--Rsync

Posted by: Administrator on August 17, 2005 11:23 AM
Want to automate your backups? Want to do it securely? Want it to be efficient and fast? Then Rsync backups over SSH using public/private keys are for you.

The following script will setup a nightly rsync backup of a directory you specify on your host to another Unix server (whatever you use as remote_host). The remote host must be running SSHd.

remote_host=ahostname.com
directory_to_backup=/a/directory/to/backup

{
cd<nobr> <wbr></nobr>/root
# create a private key with no pass phrase.
# You want to make sure no one ever gets access to this file
# (else they'll be able to log into your remote host)
ssh-keygen -f backup.private.key -t rsa -C "backupkey" -N ""
# pop the public key into a variable
public_key=`cat backup.private.key.pub`
# add a backup user on the remote machine, install the public key
ssh $remote_host "adduser backupuser;mkdir ~backupuser/backups; mkdir ~backupuser/.ssh;echo \"$public_key\" > ~backupuser/.ssh/authorized_keys"
# back on the localhost setup a job that will do the backup

echo "
#!/bin/bash
# invoked by<nobr> <wbr></nobr>/etc/cron.daily/rsyncbackupcronjob.sh
ssh-add<nobr> <wbr></nobr>/root/backup.private.key

# copy a directory to the backup server
rsync --delete --compress --archive --rsh=ssh $directory_to_backup backupuser@$remote_host:backups/
" ><nobr> <wbr></nobr>/root/rsyncbackup.sh
chmod +x<nobr> <wbr></nobr>/root/rsyncbackup.sh

# and then you need a job to lauch the previous one. This job will execute nightly via cron
echo '#!/bin/bash' ><nobr> <wbr></nobr>/etc/cron.daily/rsyncbackupcronjob.sh
echo "ssh-agent<nobr> <wbr></nobr>/root/rsyncbackup.sh" >><nobr> <wbr></nobr>/etc/cron.daily/rsyncbackupcronjob.sh
chmod +x<nobr> <wbr></nobr>/etc/cron.daily/rsyncbackupcronjob.sh
}

Edit<nobr> <wbr></nobr>/root/rsyncbackup.sh if you want to change the files/directories you need backed up

#

rsync.net

Posted by: Administrator on June 08, 2006 05:11 AM
The above configuration (including the use of ssh keys to automate) is exactly what I use to backup my important personal data.

The difference is that the server I back them up to does not belong to me - it is an rsync.net server, and the data gets replicated to both California and Colorado.

I highly recommend this service. Read their corporate philosophy and privacy/warrant policy if you like pleasant surprises...

#

Some Sample Scripts

Posted by: Administrator on June 08, 2006 07:49 AM

Based in part on the above, we've put together a series of how-tos, including sample scripts, for using rsync on Linux, Windows & Mac OS X. Might be of some help to folks.

<a href="http://www.exavault.com/rsync_setup_unix_linux_bsd.shtml" title="exavault.com">rsync on Linux/Unix/BSD</a exavault.com>

<a href="http://www.exavault.com/rsync_setup_mac_osx.shtml" title="exavault.com">rsync on Mac OS X</a exavault.com>

<a href="http://www.exavault.com/rsync_setup_windows.shtml" title="exavault.com">rsync on Windows (All Versions)</a exavault.com>

These are for our online backup service, <a href="http://www.exavault.com/" title="exavault.com">ExaVault</a exavault.com>, but if you want to use them for your own purposes you are welcome to. You just need to change the name of the server (username.exavault.com) to your own server, and you need to add your keys to your authorized_keys file manually, instead of using our 'addkeys'.

#

Making secure remote backups with Rsync

Posted by: Anonymous [ip: 124.43.251.154] on August 13, 2007 06:33 AM
This is cool! I've got it using without the additional security part. I found other articles related to this but this is the only article has discribed about the environmet variable passing to start SSH -e "ssh -i ~/rsync-key". Thanks :-)
W.M.T. Manjula

#

Making secure remote backups with Rsync

Posted by: Anonymous [ip: 217.128.184.142] on February 26, 2008 11:12 AM
Very good paper! Thanks a lot. Work very well

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya