Linux : Script bash pour une sauvegarde historisée

Le principe est simple : réaliser une sauvegarde historisée sur un certain nombre de jours d’un serveur Linux.
J’ai personnellement sélectionné :

  • Le répertoire etc pour avoir la conf du serveur et des services utilisés
  • Les bases de données, sous forme de dump MySQL
  • Les répertoires des différents sites web

Le script va créer une archive tar.gz par jour et par élément (etc, bases, répertoires web), enregistrés sous un dossier local qui sera ici /home/sauvegardes/
Il faudra en général prévoir un rsync distant de la dernière version de chaque élément au moins, pour avoir une sauvegarde distante. Ceci pourrait faire l’objet d’un autre article.

Ce script étant à appeler en tache « cron » bien entendu.

En attendant, voilà le script en question.

#!/bin/bash

# DECLARATIONS VARIABLES
mysqldbs=(db1 db2 db3)
wwwdirs=(dir1 dir2 dir3)
nbjours=30
jourtodelete=$((nbjours+1))

# ROTATION ANCIENNES VERSIONS
for ((  jour = ${nbjours[*]};  jour > 1;  jour--  ))
do
    jourprec=$((jour-1))
    # SYSTEME
    mv /home/sauvegardes/etc.$jourprec.tar.gz /home/sauvegardes/etc.$jour.tar.gz

    # MYSQL
    for db in ${mysqldbs[*]}
    do
        mv /home/sauvegardes/mysql_dump/$db.$jourprec.sql.tar.gz /home/sauvegardes/mysql_dump/$db.$jour.sql.tar.gz
    done
    # WWW
    for dir in ${wwwdirs[*]}
    do
        mv /home/sauvegardes/www/$dir.$jourprec.tar.gz /home/sauvegardes/www/$dir.$jour.tar.gz
    done
done

# SUPPRESSION VERSION LA PLUS VIEILLE
# SYSTEME
rm /home/sauvegardes/etc.$jourtodelete.sql.tar.gz
# MYSQL
for db in ${mysqldbs[*]}
do
    rm /home/sauvegardes/mysql_dump/$db.$jourtodelete.sql.tar.gz
done
# WWW
for dir in ${wwwdirs[*]}
do
    rm /home/sauvegardes/www/$dir.$jourtodelete.tar.gz
done

# GENERATION VERSION DU JOUR
# SYSTEME
tar czf /home/sauvegardes/etc.1.tar.gz /etc
# MYSQL
for db in ${mysqldbs[*]}
do
    mysqldump -u root --password=MYSQLROOTPASSWORD $db > /home/sauvegardes/mysql_dump/$db.sql
    tar czf /home/sauvegardes/mysql_dump/$db.1.sql.tar.gz /home/sauvegardes/mysql_dump/$db.sql
    rm /home/sauvegardes/mysql_dump/$db.sql
done
# WWW
for dir in ${wwwdirs[*]}
do
    tar czf /home/sauvegardes/www/$dir.1.tar.gz /var/www/$dir/
done

Pour l’adapter à votre environnement :

  • Remplacer « (db1 db2 db3) » par la liste des bases à sauvegarder
  • Remplacer « (dir1 dir2 dir3) » par la liste des répertoires web à sauvegarder
  • Variable « nbjours » : renseigner le nombre de jours d’historisation souhaités
  • Remplacer « MYSQLROOTPASSWORD » par le mot de passe root MySQL de votre serveur.
  • Remplacer « /home/sauvegardes/ » ainsi que « /home/sauvegardes/mysql_dump/ » et « /home/sauvegardes/www » par les chemins respectifs souhaités : racine des sauvegardes, répertoire des sauvegardes des bases, et répertoire des sauvegardes des répertoires web.

Et roulez jeunesse !

Cela reste artisanal, mais très pratique pour avoir une procédure de sauvegardes historisées suffisante pour pouvoir restaurer des versions antérieures de chaque site, ainsi que le paramétrage du serveur (en cas d’urgence, ce que je ne vous souhaite pas).

La grosse faille du script étant la présence du mot de passe root MySQL en dur, il mériterait de gérer les mots de passe de chaque base sous forme de liste pour éviter d’avoir le mot de passe root. Et dans l’idéal de trouver une solution pour ne pas faire apparaitre les mots de passe dans le script.
La première solution est relativement simple à implémenter, la deuxième beaucoup moins mais est sans doute possible également.
Je n’ai pas appronfondi ces aspects, le serveur concerné dans mon cas personnel étant un serveur de développement et de « gros bordel », les enjeux stratégiques sécuritaires n’en valaient pas la peine.

Si vous utilisez ce script comme base et le faites évoluer dans ce sens, n’hésitez pas à poster des modifications améliorant ces aspects de sécurité (et éventuellement d’autres que je n’aurais pas identifié) 🙂