Sauvegarde incrémentale de fichiers avec RSYNC et SSH
Voici un script que j'ai écrit il y a quelques années pour un besoin de sauvegarde de fichiers que j'avais à l'époque. Le principe est très simple et la méthode est efficace: utilser l'utilitaire rsync avec ses options extraordinaires pour faire une copie complète ou incrémentielle à travers un tunnel ssh depuis le client vers le serveur de sauvegarde.
En effet, rsync permet grâce à ses nombreuses options de manipuler soigneusement l'opération de copie de fichiers. Il permet, entre autres, de minimiser le volume copié et économiser la bande passante en cas de copie distante puisqu'il utilise un protocole de mise à jour qui ne copie que les nouveautés ou les modifications au lieu de la totalité du fichier. Il permet aussi d'effectuer une synchronisation unidirectionnelle du client vers le serveur de sauvegarde tout en archivant sur ce dernier les anciennes versions qui n'existent plus sur le client.
Le script ci-dessous permet de sauvegarder une liste de fichiers et ou répertoires depuis le client vers le serveur avec le cycle suivant:
- Une sauvegarde complète le jour J (par défaut lundi).
- Une sauvegarde incrémentale du jour J+1 au jour J+6.
- Une sauvegarde complète le jour J+7 (soit une sauvegarde complète par semaine).
Notez qu'il faudra créer un cronjob qui exécute le script quotidiennement. D'autres actions sont à prévoir également, comme la génération de la clé ssh, bien lire les commentaires pour plus de détails, adaptez également les variables à votre cas.
Voila le script à copier quelque part sur le client à sauvegarder.Pour l'instant les commentaires sont en anglais, je les mettrais en français dès que possible.
#!/bin/sh
#############################################################################
# Script to do weekly full backup and daily incremental backup using rsync #
# over SSH #
# Adapted from script by Brian Hone found here: #
# http://linuxfocus.org/English/March2004/article326.shtml #
# Which adapted from script found on the rsync.samba.org #
# #
# Kadimi Mohamed-Amine 08-08-2007 #
# This script is freely distributed under the GPL #
#############################################################################
#
# - By default, the full backup is made monday, you can specify another day
# by entering a number from 1 to 7 (1 is monday, 2 is tuesday ...)
#
#FULL_DAY=1
#
# - BACKUP_ROOT is the parent directory from which you want rsync to start the backup
#
# - BACKUP_LIST is a text file where you specify files/directories you
# want to backup (one per line), the paths on this file must be relative
# to the path set in BACKUP_ROOT
#
# For example, if you want to backup only /home/user1 and /home/user2
#
# You can do it this way :
# BACKUP_ROOT=/home
# and the content of the file specified in BACKUP_LIST is:
# user1
# user2
#
# You can also do it this way :
# BACKUP_ROOT=/
# and the content of the file specified in BACKUP_LIST is:
# home/user1
# home/user2
#
BACKUP_ROOT=/
BACKUP_LIST="/root/backup_list"
#
# excludes file - contains one wildcard pattern per line of files to exclude
# - This is a rsync exclude file. See the rsync man page.
#
EXCLUDES_LIST="/root/backup_exclude"
#
# Hostname or IP adress of the remote backup server
#
BACKUP_SRV=server_hostname
#
# Root directory that stores backups on the remote server
#
ARCHIVE_ROOT=/mnt/backup/
#
# Log file; must be writable by the user who executes this script
#
LOGFILE="/var/log/backup-rsync.log"
#
# Remote user. Used by ssh. This is the user who connects to the remote backup server
# Must have write access on $ARCHIVE_ROOT
#
# - You should generate and share a ssh key to connect securely through ssh
# without providing a password. Procedure to do that is (tested on debian):
# 1- Generate the key (e.g. backup_key) on the local host by running :
# ssh-keygen -f ~/.ssh/backup_key
# backup_key and backup_key.pub are created in ~/.ssh/
#
# 2- Add the generated public key to the file ~/.ssh/authorized_keys on the remote host:
# cat ~/.ssh/backup_key.pub | ssh remoteuser@remotehost "cat - >>.ssh/authorized_keys"
#
# For security reasons, avoid backing up using the remote root account
#
REMOTE_USER=username
#
# mail address for status updates
# - This is used to email you a status report
# - Comment it if you don't want to mail the report
#
MAILADDR=yourmail@yourdomain.com
#
# HOSTNAME
# This is used for creating a directory specific to this host on the remote host
#
HOSTNAME=client_hostname
#########################################
# From here on out, you probably don't #
# want to change anything unless you #
# know what you're doing. #
#########################################
#
# Calculate WEEK_NUM
# - This is the week number of year, it depends on the variable FULL_DAY
# the value of FULL_DAY is considered as the first day of week
#
# - By default the command `date +%W` considers monday as first day of week, so if the day of
# the full backup is different from monday then we must make additional operations
#
#
if [ $FULL_DAY ] && [ $FULL_DAY -le 7 ] && [ `date +%u` -ge $FULL_DAY ] ; then
WEEK_NUM=`expr $(date +%W) + 1`
else
WEEK_NUM=`date +%W`
fi
#
# ARCHIVE_DIR
# This is the directory (full path) of the current week backups (on the remote host)
# The name of directory indicates the number of the week in the year (e.g 2007-32)
#
ARCHIVE_DIR="$ARCHIVE_ROOT/$HOSTNAME/`date +%Y`-$WEEK_NUM"
#
# Directory which holds our current datastore
#
CURRENT=main
#
# Directory which we save incremental changes to (e.g monday_06-08-2007)
#
INCREMENTDIR=`date +%A_%d-%m-%Y`
#
# Options to pass to rsync
# -r for recursivity must be explicite in spite of -a because --files-from (see man rsync)
#
OPTIONS="--force --ignore-errors --delete --delete-excluded \
--exclude-from=$EXCLUDES_LIST --backup --backup-dir=$ARCHIVE_DIR/$INCREMENTDIR \
-arhv --files-from=$BACKUP_LIST"
# our actual rsyncing function
do_rsync()
{
rsync $OPTIONS $BACKUP_ROOT $REMOTE_USER@$BACKUP_SRV:$ARCHIVE_DIR/$CURRENT >> $LOGFILE 2>&1
return
}
# our post rsync accounting function
do_accounting()
{
if [ $1 ] ; then
echo "Backup Accounting for Day $INCREMENTDIR on $HOSTNAME:">/tmp/rsync_script_tmpfile
echo >> /tmp/rsync_script_tmpfile
echo "################################################">>/tmp/rsync_script_tmpfile
ssh $REMOTE_USER@$BACKUP_SRV du -s $ARCHIVE_DIR/* >> /tmp/rsync_script_tmpfile
echo "Mail $1 -s "$HOSTNAME Backup Report" < /tmp/rsync_script_tmpfile"
Mail $1 -s "$HOSTNAME Backup Report" < /tmp/rsync_script_tmpfile
echo "rm /tmp/rsync_script_tmpfile"
rm /tmp/rsync_script_tmpfile
fi
}
# some error handling and/or run our backup and accounting
if [ $BACKUP_LIST ]; then
if [ $EXCLUDES_LIST ]; then
if [ -f $BACKUP_LIST ]; then
if [ -f $EXCLUDES_LIST ] ; then
# make sure our backup tree exists
ssh $REMOTE_USER@$BACKUP_SRV install -d $ARCHIVE_DIR/$CURRENT
echo >> $LOGFILE
echo "=========================================================" >> $LOGFILE
echo "`date` : Backup started." >> $LOGFILE
do_rsync
if [ $? -eq 0 ] ; then
echo "OK. Backup succeeded" | tee -a $LOGFILE
do_accounting $MAILADDR
exit 0
else
echo "Backup failed. See $LOGFILE for debug info." | tee -a $LOGFILE
do_accounting $MAILADDR
exit 1
fi
else
echo "$EXCLUDES_LIST: File not found or not a regular file. Backup aborted" | tee -a $LOGFILE;
exit 1
fi
else
echo "$BACKUP_LIST: File not found or not a regular file. Backup aborted" | tee -a $LOGFILE
exit 1
fi
else
echo "You must edit the script file and set the variable EXCLUDES_LIST" | tee -a $LOGFILE
exit 1
fi
else
echo "You must edit the script file and set the variable BACKUP_LIST" | tee -a $LOGFILE
exit 1
fi
exit 2

Poster un nouveau commentaire