Créer des sauvegardes Linux avec rsync

Vous avez plusieurs serveurs et machines Linux dans un réseau local LAN et vous désirez sauvegarder.
Pour cela, on peut créer un serveur de sauvegarde avec rsync.
Chaque machine va alors synchroniser ses fichiers vers le serveur de sauvegarde Linux.
Ensuite, on peut utiliser un logiciel de sauvegarde pour dupliquer cela vers des bandes.

Cet article vous guide pour créer un serveur de sauvegardes avec rsync où les clients synchronisent et transfèrent les fichiers pour sauvegarder les données.

Créer des sauvegardes Linux avec rsync

Introduction

Dans cet article vous trouverez les éléments suivants :

  • L'installation et la configuration d'un serveur rsyncd
  • La configuration des clients pour sauvegarder vers ce dernier
  • Un script qui permet de créer une rotation des sauvegardes

Plusieurs scripts sont donnés à adapter chez vous.
Vous pouvez les réutiliser, les modifier, bref en faire ce que vous voulez.
Par contre, si vous devez rédiger un tutoriel sur un site ou un PDF merci de créditer malekal.com conformément à la licence Creative Commons BY-NC-SA.

Créer des sauvegardes avec rsync

Installer et configurer rsyncd sur le serveur

Créer l'utilisateur et les répertoires

On créé un user sans mot de passe et avec lequel on ne peut pas se connecter.
Ce dernier n'aura pas de shell, donc impossible de se connecter par SSH avec.

adduser sauvegarde --shell /bin/false --disabled-password

Puis on créé l'arborescence qui va bien :

mkdir /home/sauvegarde/jour
mkdir /home/sauvegarde/jour/current
mkdir /home/sauvegarde/semaine
mkdir /home/sauvegarde/mois
chown -R sauvegarde.sauvegarde /home/sauvegarde/
chmod 770 -R /home/sauvegarde/

On installe rsync :

sudo apt-get install rsync

Configurer rsynd du serveur

Puis éditez le fichier /etc/default/rsync afin que le service et daemon se lance, mettre RSYNC_ENABLE à true.

Ensuite créez/éditez le fichier /etc/rsyncd.conf afin de configurer les entrées de sauvegarde

Voici un exemple, on configure à l'intérieur les dossiers des rsync.

max connections = 2
log file = /var/log/rsync.log
timeout = 300

auth users = sauvegarde
secrets file = /etc/rsyncd.secrets

uid = sauvegarde
gid = sauvegarde

[home]
path = /home/sauvegarde/jour/current
hosts allow=* <== si vous avez une ip fixe pour le client, la mettre à la place de *
hosts deny = *
comment = svg
read only = false

Quelques explications :

  • auth users et secrets files : les sauvegardes se feront avec l'utilisateur sauvegarde et le mot de passe de secrets files
  • uid et guid : rsync va utiliser les uid de ce derneir lors de la création des fichiers
  • log file chemin du fichier journal qui historique les tentatives de connexion

Puis les entrées de sauvegardes qui seront utilisées dans la commande rsync, à adapter chez vous :

  • [home] c'est le nom de l'entrée de sauvegarde qui fonctionne comme une section avec un nom entre crochets
  • path le chemin de destination de la sauvegarde
  • host allow= permet de filtrer l'accès par IP. A mettre en place pour sécuriser le sreveur rsync. Dans le cas d'une ip dynamique mettre *
  • host deny = interdire des adresses IP
Si vous désirez utiliser le script de rotation donné plus bas, il faut que la sauvegarde se fasse dans un dossier current.

Puis on créé le fichier d'authentification /etc/rsyncd.secrets
Ce dernier va contenir le mot de passe de l'utilisateur sauvegarde.
Le contenu est de la forme :

sauvegarde:monmotdepasse

Enfin on met les permissions de fichiers qui vont bien :

chown root.root /etc/rsyncd.*
chmod 700 /etc/rsyncd.*

Redémarrer le service rsync

Tout est prêt pour relancer le service rsync :

/etc/init.d/rsync restart
Le serveur de sauvegarde rsync est maintenant configuré et en place.

Configurer le rsync sur le client

Ensuite on configure le client pour synchroniser et sauvegarder les données vers le serveur rsync.

Pour cela, on créé un script sur le client afin d'automatiser la sauvegarde et synchronisation vers le serveur de sauvegarde.

Voici un script que vous pouvez utiliser :

#!/bin/bash
mail="[email protected]"
hostrsync="50.xx.xx.xx"
utilisateurrsync=sauvegarde
export RSYNC_PASSWORD=xxxxx

if [ -f /tmp/rsync.pid ] ;
then
        echo "une synchronisation est deja en cours... annulation"
        echo "Une synchronisation est deja en cours... la synchro a ete annulee" > /tmp/rsync_mail.txt
        mail -s "synchro `hostname` - Probleme!" $mail < /tmp/rsync_mail.txt
        rm -f /tmp/rsync_mail.txt
else
        touch /tmp/rsync.pid

        echo `date` -- Synchro de `hostname` >> /tmp/rsync_mail.txt
        echo >> /tmp/rsync_mail.txt
        echo >> /tmp/rsync_mail.txt

        echo "Synchro des site WEB (/home/www/)" >> /tmp/rsync_mail.txt
        echo >> /tmp/rsync_mail.txt
        echo >> /tmp/rsync_mail.txt

        #Sauvegarde WEB
        rsync -rlptD --stats --delete /home/www/ [email protected]$hostrsync::siteweb >> /tmp/rsync_mail.txt 2>> /tmp/rsync_mail.txt
        rsync -rlptD --stats --delete /etc /root/script [email protected]$hostrsync::home >> /tmp/rsync_mail.txt 2>> /tmp/rsync_mail.txt


        if [[ `cat /tmp/rsync_mail.txt` =~ "rsync error" ]]
        then
                 mail -s "synchro `hostname` - ERREUR" $mail < /tmp/rsync_mail.txt
        else
                 mail -s "synchro `hostname`" $mail < /tmp/rsync_mail.txt
        fi

        rm -f /tmp/rsync_mail.txt
        rm -f /tmp/rsync.pid
fi

A adapter :

  • hostrsync mettre l'adresse IP ou nom d'hôte du serveur rsync
  • utilisateurrsync : c'est l'utilisateur rsync du serveur, normalement sauvegarde
  • export RSYNC_PASSWORD le mot de passe de l'utilisateur sauvegarde rsync configuré dans /etc/rsyncd.secrets

La sauvegarde se fait avec la commande rsync.
Celle-ci supprime les fichiers en trop sur le serveur pour avoir un miroir parfait.
Enfin la commande rsync appelle les sauvegardes configurées dans le fichier /etc/rsyncd.conf du serveur. Ici home.

rsync -rlptD --stats --delete /etc /root/script [email protected]$hostrsync::home
chmod +x /root/script/rsync.sh

Puis on lance le script, aucune écriture n'apparaîtra dessus.
Par contre, on peut regarder ce qui se passe sur le serveur rsync :

tail -f /var/log/rsyncd.log

Le contenu donne ceci :

2020/12/12 12:12:37 [9831] connect from UNKNOWN (50.xx.xx.xx)
2020/12/12 12:12:37 [9831] rsync to siteweb/ from [email protected]
2020/12/12 12:12:37 [9831] receiving file list
2020/12/12 12:24:52 [9831] sent 20854488 bytes  received 2804049294 bytes  total size 262197606333
2020/12/12 12:25:03 [16832] name lookup failed for 50.xx.xx.xx: Temporary failure in name resolution
2020/12/12 12:25:03 [16832] connect from UNKNOWN (50.xx.xx.xx)
2020/12/12 12:25:03 [16832] rsync to autres/ from [email protected]
2020/12/12 12:25:03 [16832] receiving file list
2020/12/12 12:25:04 [16832] sent 314 bytes  received 94582 bytes  total size 15054065

La partie receiving file list est le processus qui compare les fichiers de part et d'autres.
Le premier coup, il va directement copier et transférer les fichiers puisque le serveur est vide.
Après cela, il y aura cette comparaison pour mettre à jour les différences. Cela peut prendre beaucoup de temps si vous avez des milliers de fichiers.

Le script de sauvegarde rsync est prévu pour envoyer un mail avec ces informations :

Enfin si tout fonctionne, on met en place un cron pour exécuter le script automatiquement :

0 1 * * * /root/script/rsync.sh
Les sauvegardes rsync sont en place sur le client.

Mettre en place une sauvegarde avec rotation

Vous avez réussi à mettre en place une sauvegarde qui consiste à synchroniser les clients vers le serveur rsync.
Mais cela ne procure pas un historique de fichiers.
Ainsi on ne peut pas restaurer un fichier de plus de deux jours.

Grâce à ce script à mettre en place sur le serveur rsync, il est possible de mettre en place une sauvegarde avec des reotations.
Il prévoit de copier les sauvegardes avec un roulement sur X jours.
On peut aussi faire une sauvegarde sur la semaine ou mois.

Le script parcourt la configuration du rsync /etc/rsyncd.conf, pour créer les décalages des sauvegardes.
Il est juste prévu que les sauvegardes soient dans un dossier current.

#!/bin/bash
DIR=($(ls -d $1/*))
KEEP=2
DATE=`date --date=yesterday "+%Y-%m-%d"`
MAIL="[email protected]"
REP="/home/sauvegarde/jour"
SEMAINE="/home/sauvegarde/semaine"
MOIS="/home/sauvegarde/mois"


function decallage {

echo "$DATE - Lancement des sauvegardes incrementales....." > /tmp/rapport_incr.txt
echo >> /tmp/rapport_incr.txt

echo >> /tmp/rapport_incr.txt
echo "################### SAVE-ROTATE DU $DATE ####################"
echo

for line in `cat /etc/rsyncd.conf |grep current| grep -Eo "\/.*current"|sed 's/current//g'`
do
        # arborescence :
        # /home/backup/xxxx/xx-xx-xx
        # /home/backup/xxxx/current

        # calcule date du jour
        echo -n "Sauvegarde du dossier "
        echo -n `echo $line | cut -d / -f 5`
        echo " en cours..."

        echo "Sauvegarde incrementale de $line vers $line/$DATE" >> /tmp/rapport_incr.txt
        # supprime les vieilles sauvegardes
        ls -d $line/2* | sort | head --lines=-$KEEP | xargs rm -rf

        # créle rértoire pour les backups de la veille s'il n'existe pas dé
        if [ -d $DATE ]; then
                echo "Erreur: le dossier de sauvegarde existe deja" >> /tmp/rapport_incr.txt
                echo
                continue
        fi
        mkdir $line/$DATE >> /tmp/rapport_incr.txt 2>> /tmp/rapport_incr.txt

        # copie (hard links) les donné
        cp -al $line/current/* $line/$DATE >> /tmp/rapport_incr.txt 2>> /tmp/rapport_incr.txt

        echo
        echo >> /tmp/rapport_incr.txt
        echo >> /tmp/rapport_incr.txt

done

echo "Etat des disques..." >> /tmp/rapport_incr.txt
df -H|grep svgd >> /tmp/rapport_incr.txt

mail -s "Sauvegarde incrementale..." $MAIL < /tmp/rapport_incr.txt
rm -f /tmp/rapport_incr.txt

}

function semaine {
        for rsync in `cat /etc/rsyncd.conf |grep current| grep -Eo "\/.*current"|sed 's/current//g'`
        do
                save=$(echo $rsync|awk -F"/" '{print $(NF-1)}')
                echo "Sauvegarde de $SEMAINE/$save.tar.gz ($rsync/current) -- $save"
                rm -f $SEMAINE/${save}_3.tar.gz
                mv $SEMAINE/${save}_2.tar.gz $SEMAINE/${save}_3.tar.gz
                mv $SEMAINE/${save}.tar.gz $SEMAINE/${save}_2.tar.gz
                tar cfz $SEMAINE/${save}.tar.gz $rsync/current
        done
#       mail -s "Sauvegarde incrementale (semaine)..." $MAIL < /tmp/rapport_incr.txt
}

function mois {
        for save in `ls $REP`
        do
                echo "On est le premier du mois -- decallage des sauvegarde..."
                rm -f $MOIS/${save}_3.tar.gz
                mv $MOIS/${save}_2.tar.gz $MOIS/${save}_3.tar.gz
                mv $MOIS/${save}.tar.gz $MOIS/${save}_2.tar.gz
                echo "Copie de $SEMAINE/${save}.tar.gz vers $MOIS/${save}.tar.gz.."
                cp $SEMAINE/${save}.tar.gz $MOIS/${save}.tar.gz
        done
}

###### MAIN
jour=$(date|awk '{print $1}')

if [[ $jour == "dimanche" || $1 == "force" ]]
then
        semaine
        echo
else
        decallage
        echo
fi

jmois=$(date|awk '{print $2}')
if [[ $jmois -eq 1 ]]
then
        mois
        echo
fi

Quelques explications :

  • KEEP= est le nombre de roulement, ici il va garder 3 jours en arrière.
  • MAIL= le ou les adresses mails de réception des notifications par mail
  • REP= le répertoire où se trouvent les sauvegardes
  • SEMAINE= l'emplacement où stocker les sauvegardes de la semaine
  • MOIS= l'emplacement où stocker les sauvegardes de la semaine

Le script garde 3 rotations de sauvegardes du mois et semaine.
Ce qui permet de revenir à 3 semaines ou 3 mois en arrière.

On obtient alors ceci :

  • Dans jour on trouve les sauvegardes, ici il y a du MySQL et Tomcat
  • Dans chaque sauvegarde, le dossier current correspond à la dernière sauvegarde. Sinon on a la date des sauvegardes précédentes, ici il en garde 3.
  • Dans semaine, les sauvegardes de la semaine avec trois rotations

Créez le fichier script à adapter puis le rendre exécutable :

/root/script/incremental.sh
chmod +x /root/script/incremental.sh

On peut ensuite mettre un script en place comme ceci :

0 5 * * * /root/script/incremental.sh