Remote Backup Across the Internet Using rsync and SSH
There's a time for everything, for everyone. So does there's a time when server crashes and your data gone. Off course, that's happened if you don't have any backup.
It's always considered best practice to backup our precious data. As for websites, most important data could be public web directory where the application resides and the database from your website. We'll cover how to do backup from one server to another one.
Before getting started, you'll need these packages installed:
- rsync
- openssh
- cron
Please note these solution might be specific for Linux, some modification or command line parameters might need to be adjusted for another *NIX OS. As always, if in doubt, RTFM.
Terminology
BACKUP_HOST
- The server where you want to store your backup filesBACKUP_USER
- User forBACKUP_NODE
BACKUP_PASS
- Password forBACKUP_USER
REMOTE_HOST
- The server with the files to be backed upREMOTE_USER
- User forREMOTE_NODE
REMOTE_PASS
- Password forREMOTE_USER
Initial Testing
Initial testing to make sure everything is installed, issue this command on your terminal (BACKUP_HOST
)
$ rsync -avz -e ssh REMOTE_USER@REMOTE_HOST:/directory/to/be/backed/up /backup/directory/on/backup/host
If everything went well, you should see the screen will be scrolled up and on the last line it displays something similar like this (with different number, off-course):
sent 44264 bytes received 14880872 bytes 663339.38 bytes/sec
total size is 22964887 speedup is 1.54
Backup Node Configuration
Next step is to generate a private/public key pair to allow ssh connection without asking password. This might seems dangerous, which actually it is, but it still considered as better solution than storing a clear text password somewhere in the script. This method could be secured further by limiting on where connections made with this key can come from and what could be done when connected. Here's how to generate the key:
$ ssh-keygen -t rsa -b 2048 -f backup-rsync-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in backup-rsync-key.
Your public key has been saved in backup-rsync-key.pub.
The key fingerprint is:
0e:98:aa:92:a5:58:03:e0:57:c2:44:bd:ad:62:e7:50 [email protected]
The key's randomart image is:
---snipped---
Please note: Make sure no other user could read the private key, it's the one without the *.pub
extension.
To make this key works, put the public key into the 'authorized_keys' file on REMOTE_HOST
for REMOTE_USER
:
/home/REMOTE_USER/.ssh/authorized_keys
You can use SCP to put the file to REMOTE_HOST
$ scp backup-rsync-key.pub REMOTE_USER@REMOTE_HOST:/home/REMOTE_USER/.ssh
Remote Host Configuration
It's time to move forward with remote host configuration. Make sure you have the directory and files you need to authorize with this key.
$ if [ ! -d .ssh ]; then mkdir .ssh ; chmod 700 .ssh ; fi$ mv backup-rsync-key.pub .ssh/
$ cd .ssh
$ if [ ! -f authorized_keys ]; then touch authorized_keys ; chmod 600 authorized_keys ; fi
$ cat backup-rsync-key.pub >> authorized_keys
As previously noted that this key would allow connections from everywhere, edit the 'authorized_keys' file and modify the line with 'backup-rsync-key.pub' information on it. Example, this line:
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAswfrVqbshLnGrzK58Bo/h8rSvotk8cdRYoLddqP6UVgh3g9s9Zpq3
/2upzLnrv/4NZcXfg5hyFcjK3El2AHvbgT1cSM5WsAbdcAdpe5tTUDeaTzHavS1TUYsBpMYv+g1+et5InnDGyc2qz
Vf+5IBtog0NL6ftXviI6CG7Pp2dCY0r/7czgTmkJRcEz+wGo7yLMKgjV/A6Su77YIBgEmwVeKK+FqOvrv98BFdmWS
7m9px4Uoq4fA56gV7AoMyJJZhyqyJ8DrN0H/1K1v2Uq/jof2tcNA5UzcD8rwGRzgJdbtYalJRDeCE8lvzR2/2ixj8
ReIDTmvwnrzyz21eEBgbWw== BACKUP_USER@BACKUP_HOST
should be changed like this:
from="10.0.0.1",command="/home/REMOTE_USER/automatic/validate-rsync" ssh-rsa AAAAB3NzaC1y
c2EAAAABIwAAAQEAswfrVqbshLnGrzK58Bo/h8rSvotk8cdRYoLddqP6UVgh3g9s9Zpq3/2upzLnrv/4NZcXfg5hy
FcjK3El2AHvbgT1cSM5WsAbdcAdpe5tTUDeaTzHavS1TUYsBpMYv+g1+et5InnDGyc2qzVf+5IBtog0NL6ftXviI6
CG7Pp2dCY0r/7czgTmkJRcEz+wGo7yLMKgjV/A6Su77YIBgEmwVeKK+FqOvrv98BFdmWS7m9px4Uoq4fA56gV7AoM
yJJZhyqyJ8DrN0H/1K1v2Uq/jof2tcNA5UzcD8rwGRzgJdbtYalJRDeCE8lvzR2/2ixj8ReIDTmvwnrzyz21eEBgb
Ww== [email protected]
Where the 10.0.0.1
should be changed with your BACKUP_HOST
ipv4, and '/home/REMOTE_USER/automatic/validate-rsync
' file contains:
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
*\&*)
echo "Rejected"
;;
*\(*)
echo "Rejected"
;;
*\{*)
echo "Rejected"
;;
*\;*)
echo "Rejected"
;;
*\<*)
echo "Rejected"
;;
*\>*)
echo "Rejected"
;;
*\`*)
echo "Rejected"
;;
*\|*)
echo "Rejected"
;;
rsync\ --server*)
$SSH_ORIGINAL_COMMAND
;;
*)
echo "Rejected"
;;
esac
Note: Make sure the '/home/REMOTE_USER/automatic/validate-rsync
' script is executable by REMOTE_USER
on REMOTE_HOST
and test it.
Final Testing and Make it Runs on Regular Basis
Now it's the time to test it. Issue this command:
$ rsync -avz -e "ssh -i /home/BACKUP_USER/backup-rsync-key" REMOTE_USER@REMOTE_HOST:/directory/to/be/backed/up /backup/directory/on/backup/host
If above command returns something like this:
receiving incremental file list
sent 420 bytes received 70710 bytes 10943.08 bytes/sec
total size is 22964887 speedup is 322.86
Then it means all steps were done correctly and a cron script could be added. I use this bash script, store it to '/home/BACKUP_USER/rsync-REMOTE_HOST-backups
' and put it on cron task:
#!/bin/sh
RSYNC=/usr/bin/rsync
SSH=/usr/bin/ssh
KEY=/home/BACKUP_USER/backup-rsync-key
RUSER=REMOTE_USER
RHOST=REMOTE_HOST
RPATH=/remote/dir
LPATH=/this/dir/
$RSYNC -az -e "$SSH -i $KEY" $RUSER@$RHOST:$RPATH $LPATH
Crontab to schedule it everyday at 2:00AM:
0 2 * * * /home/BACKUP_USER/rsync-REMOTE_HOST-backups
Note: To make sure the script runs correctly, you can test run it using ./rsync-REMOTE_HOST-backups
Final Words
Well, that's it. I hope that you now know how to backup your server remotely accross the internet using rsync and SSH. If you run into any issues or have any feedback feel free to drop a comment below.