Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 21/11/2013, à 17:12

sauthess

[Script backup] Sauvegarde basée sur SSH et rsync

Bonjour,

Voici un script que j'ai réalisé qui permet de faire des backups en utilisant rsync et ssh.
Pour se faire, il faut mettre en place une clé partagée entre la machine à backuper et la machine où la sauvegarde sera réalisée (je ne reviens pas sur la procédure, il y a des moteurs de recherches pour ceux qui ne connaissent pas).

Ce script permet de faire des différentiels entre 2 exécutions, a savoir :
- Lors de la première exécution, il copie tout (durée dépendant du volume de données et de la liaison réseau...mais cela peut être très long...) dans un répertoire backup.0
- lors de la seconde, il déplace backup.0 en backup.1, créé des liens symboliques dans backup.0 pour les fichiers qui n'ont pas changés et copie les nouveaux, supprime ceux qui ont été supprimés...(très rapide)
- lors de la troisième, il déplace backup.0 en backup.1 et backup.1 en backup.2, créé des liens symboliques dans backup.0 pour les fichiers qui n'ont pas changés et copie les nouveaux, supprime ceux qui ont été supprimés...(très rapide)
- etc...

Les avantages sont multiples : une donnée n'est stockée qu'une fois même si vous la voyez plusieurs fois (dans backup.0 et backup.1, backup.2 dans mon exemple pour une donnée qui n'aurait pas changé pendant les 3 executions)

Cela permet de mettre en place une tâche planifiée quotidienne et conserver X sauvegardes sans que cela prenne une place importante inutilement.

Le script est en anglais car je fais toujours tout en anglais et que je l'ai déjà partagée à d'autres...

Tout est configurable via les variables en début de scripts (nombre de backup, répertoires, ip, port,....).

#!/bin/sh

#========= !!!! Prerequisite : local and distant user must have a ssh shared keys without password 
#============================= if not password will be asked at each execution

########################################################
# ENVIRONMENT VARIABLES                                #
########################################################
# Name of the user on the destination host (the server where backups will be located)
TARGET_USER=myuser
TARGET_IP=172.16.0.2
TARGET_PORT=22

# Name of the proprietary of the local files to backup (you can replace this by LOCAL_USER=`$USER` if you use the same user to execute this script)
LOCAL_USER=djiit-debian
# Hostname of the computer to backup
PC_NAME=`hostname`

# Name of the file used to verify is previous backup was successfull
CHECKBACKUP_FILE_NAME=backup_date.txt

#Number of retries
NUM_RETRIES=5

# Options to pass to rsync
RSYNC_OPTIONS="-a -v -k --delete" 

#####################################################################################
# backup configuration                                          		    #
# backup will be putted on BACKUP_DIR/$PC_NAME/$BACKUP_PREFIX/$NAME_OF_DIR_TO_BACKUP#
#####################################################################################
TARGET_BACKUP_DIR=/media/data/Backups
BACKUP_PREFIX=daily
# how many backup should we keep in supplement of master backup (backup.0)
BACKUP_NUMBER=3

#List of local directories to backups
BACKUP_DIR_LIST="/etc /home/test/Documents /home/test/Images"

#logger configuration
LOGGER_NAME=SAU
LOGGER_SCRIPT_NAME=$0


#####################################################################################
# SYSTEM VARIABLES                                                                  #
#####################################################################################
TARGET_SERVER=${TARGET_USER}@${TARGET_IP}
TARGET_LOCAL_DIR=${TARGET_BACKUP_DIR}/${PC_NAME}/${BACKUP_PREFIX}


for i in ${BACKUP_DIR_LIST}; do
	#######################################################
	# Checks if last backup was successfull               #
	#######################################################

	# we remove potential old local copy of the check file : 
	if [ -f /tmp/${CHECKBACKUP_FILE_NAME} ]; then
        	rm /tmp/${CHECKBACKUP_FILE_NAME}
	fi
	# we try to get CHECKBACKUP File on target server :
	scp -P${TARGET_PORT} ${TARGET_SERVER}:${TARGET_LOCAL_DIR}${i}/backup.0/${CHECKBACKUP_FILE_NAME} /tmp
	# we remove it in case of a problem during this execution : 
	ssh -p${TARGET_PORT} ${TARGET_USER}@${TARGET_IP} "rm -f $TARGET_LOCAL_DIR/${i}/backup.0/${CHECKBACKUP_FILE_NAME}"

#Sauvegarde du HOME

if [ -f /tmp/${CHECKBACKUP_FILE_NAME} ]; then 
	# We remove the oldest backup :
	COMMAND="rm -Rf ${TARGET_LOCAL_DIR}${i}/backup.${BACKUP_NUMBER}"
	ssh -p${TARGET_PORT} ${TARGET_USER}@${TARGET_IP} $COMMAND
	EXITCODE=$?
        if [ $EXITCODE -ne 0 ]; then
                logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : Problem during remove of oldest backup : ${TARGET_LOCAL_DIR}${i}/backup.${BACKUP_NUMBER}"
                exit 1
        fi

	#we rotate others backups : 
	x=$((${BACKUP_NUMBER} - 1))
	while [ ${x} -ge 0 ]
	do
		y=$(( $x + 1 ))
		COMMAND="mv ${TARGET_LOCAL_DIR}${i}/backup.${x} ${TARGET_LOCAL_DIR}${i}/backup.${y}"
		ssh -p${TARGET_PORT} ${TARGET_USER}@${TARGET_IP} $COMMAND
		EXITCODE=$?
	        if [ $EXITCODE -ne 0 ]; then
       	        	logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : Problem during rotation of ${TARGET_LOCAL_DIR}${i}/backup.${x} to {TARGET_LOCAL_DIR}${i}/backup.${y}"
                	exit 1
        	fi

 		x=$(( $x - 1 ))
	done
else
        logger -t {LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : last backup failed for ${i}, no rotation launched."
	# in case of first backup, we create necessary directory :
	COMMAND="mkdir -p ${TARGET_LOCAL_DIR}${i}/backup.0"
	ssh -p${TARGET_PORT} ${TARGET_USER}@${TARGET_IP} $COMMAND
        EXITCODE=$?
        if [ $EXITCODE -ne 0 ]; then
             logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : Problem creating dir {TARGET_LOCAL_DIR}${i}/backup.0, please create it manually !"
             exit 1
        fi
	COMMAND="mkdir -p ${TARGET_LOCAL_DIR}${i}/backup.1"
        ssh -p${TARGET_PORT} ${TARGET_USER}@${TARGET_IP} $COMMAND
        EXITCODE=$?
        if [ $EXITCODE -ne 0 ]; then
             logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : Problem creating dir {TARGET_LOCAL_DIR}${i}/backup.1, please create it manually !"
             exit 1
        fi

	
fi

EXITCODE=300
TEST=0
while [ ${EXITCODE} -ne 0 ]; do
               rsync ${RSYNC_OPTIONS} -e "ssh -l ${TARGET_USER}" --link-dest=${TARGET_LOCAL_DIR}${i}/backup.1 ${i}  ${TARGET_IP}:${TARGET_LOCAL_DIR}${i}/backup.0/
        EXITCODE=$?
        TEST=$((${TEST} + 1))
        if [ ${EXITCODE} -ne 0 ]; then
                if [ ${TEST} -eq ${NUM_RETRIES} ]; then
                        logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : ${NUM_RETRIES} done for ${i} - stop."
                        exit 1
                fi
                logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : Error during backup of ${i}, new try..."
        fi

done

#we create backup control file 
date > /tmp/${CHECKBACKUP_FILE_NAME}
scp -P${TARGET_PORT} /tmp/${CHECKBACKUP_FILE_NAME} ${TARGET_USER}@${TARGET_IP}:${TARGET_LOCAL_DIR}${i}/backup.0/
rm /tmp/${CHECKBACKUP_FILE_NAME}

logger -t ${LOGGER_NAME} "${LOGGER_SCRIPT_NAME} : backup finished succesfully."


done

Les plus attentifs auront surement vu la variable BACKUP_PREFIX...Elle permet de créer différents types de sauvegarde. Dans mon cas, je lance un script tous les jours (préfixe daily et nombre de sauvegarde 3) et une autre toutes les semaines (préfixe weekly et nombre de sauvegarde 2). Cela me donne une bonne visibilité sur les données et la possibilité de revenir à une situation stable en cas de besoin facilement (après chacun fait comme il l'entend).
Par exemple j'ai cette arborescence pour mon répertoire Documents :
mon_pc/daily/home/mon_user/Documents/backup.0 (sauvegarde du jour)
mon_pc/daily/home/mon_user/Documents/backup.1 (sauvegarde d'hier)
mon_pc/daily/home/mon_user/Documents/backup.2 (sauvegarde d'avant hier)
mon_pc/weekly/home/mon_user/Documents/backup.0 (dernière sauvegarde hebdo)
mon_pc/weekly/home/mon_user/Documents/backup.1 (celle de la semaine d'avant)

Pour arriver à ce résultat j'ai englobé ce script avec d'autres qui passent en paramètres les bonnes valeurs (plutôt qu'un copié/coller mal propre...). C'est très simple à faire et cela dépend du besoin de chacun donc je vous laisse faire wink

Dernier point, le script utilise "logger" pour envoyer des messages à syslog (regardez donc /var/log/syslog si vous pensez qu'il y a eu un problème... les variables LOGGER_ peuvent vous aider pour cela...)

En espérant que cela servira à quelqu'un wink

Dernière modification par sauthess (Le 22/11/2013, à 17:45)


Serveur : Debian openvz, Portable 1 : Arch linux, Portable 2 et 3 : Ubuntu

Hors ligne

#2 Le 21/11/2013, à 23:13

tiramiseb

Re : [Script backup] Sauvegarde basée sur SSH et rsync

Salut,

Quel est l'intérêt de ta solution par rapport à rdiff-backup ou à rsnapshot ?

Hors ligne

#3 Le 22/11/2013, à 08:39

sauthess

Re : [Script backup] Sauvegarde basée sur SSH et rsync

Salut,

Je n'en sais rien wink J'utilise rsync depuis des années c'est tout. Comme on m'a demandé mon script, je l'ai nettoyé et je me suis dis que cela pourrait servir à d'autres.
A l'époque où j'ai commencé à mettre en place des backups, il n'y avait pas de solution qui me convenait...peut être est-ce un peu tard aujourd'hui...
Bonne remarque en tout cas, même si mon script ne sert à rien, la liaison entre mon titre et ta réponse peut en aider certains et au pire, cela pourra servir de base à quelqu'un qui aurait des besoins très spécifiques auquels ces softs ne répondent peut être pas wink


Serveur : Debian openvz, Portable 1 : Arch linux, Portable 2 et 3 : Ubuntu

Hors ligne