Introduction

I needed a backup solution that would back up multiple servers to a single location. In order to accomplish this task I created a small Linux machine running CentOS with a cron job that will remotely connect to these machines using SSH and run the backups. Once the backup job is complete it will then push the files out on a network share to be stored.

Overview

The way I implemented the backup solution is through a multiple step process. The process begins by kicking off a bash script via cron job. The script will remote in to the client machine using SSH without a password. It will then run rsync to copy any changes from the client machine to the backup directory on the server. Once the rsync process is finished it will then archive the files. Finally the script will then mount a network share, copy the archive over and then disconnect that share.

Backup Server

  1. I setup SSH to connect to the client machines using password-less SSH (see Login to Linux machine using SSH without a password)
  2. I created a directory that will house the backups. Lets use \home\backups as an example.
  3. Inside of \home\backups I placed my backup scripts that cron will kick off. I am going to call this script JOB1.sh for this tutorial (see below).
  4. Set the cron job to kick off the script.

The Script

Below is the actual script that is used for this job.

#!/bin/bash
#Version 3

BACKUP_ROOT=/home/backups/
BACKUP_NAME=JOB1

# change DIR to backup root.
cd $BACKUP_ROOT

#This will get the timestamp in the following format: YYYYMMDD-HHMM (20130923-0300)
TIME=$(date +”%Y%m%d-%H%M”)

#rsync the changes down to base folder JOB1 backup.
echo RUNNING BACKUP SCRIPTS…

#Backup the /home directory of the client and place it in /home/backup/JOB1
rsync -avhq –delete -e ssh backup@<client>:/home $BACKUP_ROOT$BACKUP_NAME

#Backup the /etc/httpd directory of the client and place it in /home/backup/JOB1/etc
rsync -avhq –delete -e ssh backup@<client>:/etc/httpd $BACKUP_ROOT$BACKUP_NAME/etc

#enter zip here.
echo COMPRESSING…
cd $BACKUP_ROOT$BACKUP_NAME
zip -rq ../$BACKUP_NAME-$TIME.zip .

echo TRANSFERRING….

#mount the backup FS
mount -t cifs //<network_share_ip>/net_backup -o username=Everyone /mnt/net_backup
mv ../$BACKUP_NAME-$TIME.zip /mnt/net_backup
umount /mnt/net_backup

echo DONE…

You may have noticed a few things about this backup script. The script is placed in the same folder as the backup folder. When this job runs it will create a backup of this script as well. When the script runs it will rsync any changes to the server and will archive it using zip. The reason I approached it this way was due to save time in the backup process (Space-time tradeoff). Each time the script runs it only looks at the local copy of the files compared to the remote copy. If the remote files changed since the last backup it will only copy those files to the backup server, in essence the backup server will have an identical copy of files from the client. It will then compress the backup directory into the zip file, mount the network share (in this case a shared folder from Windows) then disconnects from the share.

This script is designed to be somewhat modular as in a couple of changes you can change the root directory of the backup and the backup name. It is a simple script that gets the job done with no supervision.

Setting the Cron (in CentOS/RHEL)

To setup the cron job all you have to do is run ‘crontab -e’ under the current user or ‘crontab -u backup’ assuming there is a user called backup.  Inside the cron job I set my script to run every night at midnight.

#JOB1 Backup
0 0 * * * /home/backups/JOB1.sh

When you are finished just type :wq to write quit (or :q! to quit without saving)

Script Improvements

I plan on making a few improvements to this script and when I do I will add them here. The plan is to make the script more modular by using more variables to adjust the paths of the script. Also, I plan on changing the way the script handles the zip files (or if I decide to switch over to the tar method) by only updating the zip file without recreating it each time. By doing this it will help speed up the backup process by not creating a new zip file each time.

Caveats

As you can probably guess one of the downsides of this type of script is that it requires that you have plenty of disk space available. The script could be modified to remove the backup files after they are archived to free up the space but would increase the time the backup runs.

Alternative to Rsync

You may wish to use SSH with tar to get a true archive (timestamps, permissions, etc.) of the files from the client machine. You can run this script instead of rsync and backup directly to the network share. By doing it this way it will cut down on the amount of storage required per backup by writing the backup directly to the share without storing any data locally.

tar zcvf - /etc/httpd | ssh backup@&lt;client&gt; "cat &gt; /mnt/net_backup/website.tar.gz"