faites des backups

Bon, ça a été dit et redit. Mais faut mieux insister. Je vais donc vous présenter la méthode de backup que j’ai mise en place sur mon serveur.

Note: ce n’est pas LA solution, mais UNE solution. Je suis preneur de toutes remarques.

Alors, sur ma machine, je distingue deux types de backups :

  • les backups quotidiens
  • les backups hebdomadaires

Dans les backups quotidiens, je fais une sauvegarde incrémentale de différents dossiers qui me semblent importants (/etc, /home, /var/{log,www,lib}, …). Je fais aussi un dump de toutes mes tables sql. Ces backups sont locaux à la machine. C’est pour revenir en arrière si jamais des bêtises sont faites par exemple.

Concernant les backups hebdomadaires, je fais une sauvegarde complète des backups de la semaine sur une machine distante. Ces backups sont envoyés chiffrés sur l’autre machine. Ces backups là, c’est en cas de panne du disque dur, d’incendie ou raz de marée à Gravelines ([0]).

backups quotidiens

backup des fichiers

Voici le script que j’utilise pour faire des backups quotidiens:

#!/bin/bash

# abort if any commands fail
set -e

# remove backup older than $MAXTIME
MAXTIME="1M"

# the directory where the backups are done.
BACKUP="/var/backups/data"
INCLUDELIST="/root/includelist.txt"

echo "`date` === starting backup ==="
echo "the directories to backup are :"
cat $INCLUDELIST
nice -n 19 rdiff-backup --include-globbing-filelist $INCLUDELIST \
            --exclude '**' / $BACKUP

echo "remove old files"

nice -n 19 rdiff-backup --remove-older-than $MAXTIME --force $BACKUP

echo "`date` === backup done ==="

Voyons ça ensemble. Je pense que les premières variables (MAXTIME et BACKUP) sont assez claires. Juste au cas où, MAXTIME correspond au temps que souhaitez garder vos backups (dans mon cas, je garde un mois de backup). Vous pouvez mettre ce que vous voulez (deux ans 2Y, trois semaines 3W, etc). Et BACKUP correspond au dossier où seront sauvegarder vos backups.

Le variable INCLUDELIST pointe sur un fichier texte. Dans ce fichier texte, vous listez les dossiers que vous souhaitez sauvergarder, un par ligne. Dans mon cas, j’ai:

/etc
/var/log
/var/www
/var/lib
/home
/root

ensuite, on dit simplement à rdiff-backup de faire le boulot : backuper les dossiers (incrémentalement) puis supprimer les fichiers trop vieux.

C’est quoi ce nice -n 19 devant là ??

— un lecteur attentif

Bonne question ! C’est tout simplement pour dire au système que ce processus n’est pas du tout prioritaire par rapport aux autres. Comme ça, vos backups se font sans que des ralentissements se fassent sentir. Pratique hein ? ;) (plus d’info : man nice)

backup sql

Je vous montre aussi un petit script très simple qui fait un dump de toutes les bases mysql du serveur. L’idée est là même, on fait le dump, puis on supprime ceux qui sont trop vieux…

#!/bin/bash
BPATH="/var/backups/sql/"

echo -n "--- backup up every databases --- "; date

mysqldump -A 2> /var/log/backups/sql.log | gzip -c \
    | cat > $BPATH/backup_`date +'%d_%m_%Y'`.sql.gz

#Delete old backups
find $BPATH* -mtime +30 -exec rm {} \;
echo -n "--- backup finnished --- "; date

La suppression des dumps trop vieux se fait avec la commande find. On cherche dans le dossier de backup sql les fichiers de plus de 30 jours et on les supprime.

backups hebdomadaires

Bon, passons au plus intéressant : les backups hebdomadaires. Alors, je répète l’idée du truc :

  • on compresse l’ensemble des backups (donc du mois en cours) dans une grosse archive.
  • on chiffre cette archive avec gpg.
  • on envoie cette archive sur une machine distance via ssh.

Donc, ça, c’est ce qu’on veut faire. Le problème, c’est que… on peut pas se permettre de faire simplement comme ça. Je vous explique pourquoi. Imaginez que vous ayez un disque de 100Go, occupé à disons 70Go (backups locaux compris). Si les backups locaux font, admettons 20Go. Si vous les compresser sur votre machine, vous allez occupés encore de la place (un peu moins de 20Go). Puis, pour les chiffrer, encore 20Go. Bref, il vous faudrait 40Go d’espace libre, que vous n’avez pas, juste pour faire une archive que vous allez envoyer puis supprimer. Du coup, si on faisait comme ça, tout le serveur plante au milieu de la nuit le dimanche soir et vous êtes tous comme des jambons. On va donc faire autrement ;).

Je propose qu’on fasse comme ça :

  • on compresse l’ensemble des backups dans une grosse archive.
  • on chiffre cette archive avec gpg.
  • on envoie cette archive sur une machine distance via ssh.

mais, cette fois, on fait tout en même temps ! Tout est fait à la volée, la compression, le chiffrement et l’envoi. Tout est fait à la volée grâce aux pipes.

Allez, sans plus tarder, voici le script :

#!/bin/bash

# abort if any commands fail
set -e

BACKUPDIR="/var/backups/"
DESTHOST="wilson"
DESTDIR="/home/chabotsi/backups"
KEY="simon.chabot@etu.utc.fr"

DATE=$(date +%Y-%m-%d-%H-%M)

BACKUPARCH="backup-$DATE.tar.bz2"

echo "=== `date +%Y-%m-%d-%H-%M` start copying backups to wilson ==="

cd $BACKUPDIR

nice -n 19 tar -jcvf - . |\
    gpg -r $KEY --trust-model always --encrypt |\
    ssh $DESTHOST "cat > $DESTDIR/$BACKUPARCH.gpg"

echo "=== `date +%Y-%m-%d-%H-%M` done with wilson ==="

Donc, ici BACKUPDIR est le dossier local à backuper. DESTHOST est la machine distante ([1]) et DESTDIR est le dossier de destination sur la machine distante ! Enfin, KEY est la clé publique avec laquelle vous souhaitez faire le chiffrement.

Pour faire tout ça à la volée, il a fallu un peu feinter… tar et gpg permettent de créer des archives et chiffrer à la volée, donc pas trop de difficultés de ce côté là. En revanche, côté ssh il faut ruser. On ne peut pas utiliser scp car il ne supporte pas la copie depuis l’entrée standard (stdin). Du coup, on ouvre une connexion ssh normale, et on lance la commande cat en disant « tout ce qui entre, tu le copies dans le fichier `$BACKUPARCH.gpg` ». Et ça fonctionne exactement comme on voulait. Tout est fait à la volée. Aucune place n’est prise sur le disque local. Cool, non ?!

Cronifions tout ça

Il faut maintenant faire en sorte que tout cela soit automatique, pour ça, j’utilise des tâches cron. Il faut donc que vous sauvegardiez les scripts qu’on vient de voir quelque part et les appeliez avec crontab. Pour modifier vos tâches cron, tapez crontab -e dans un terminal (en root… vu qu’on veut backuper des fichiers/dossiers root…) et écrivez ceci, par exemple :

18 4  * * * nice -n19 /root/backups/data.sh >> /var/log/backups/data.log
28 5  * * * nice -n19 /root/backups/sql.sh >> /var/log/backups/sql.log
0  1  * * 1 nice -n19 /root/backups/wilson.sh >> /var/log/backups/wilson.log

Comme ça,

  • chaque nuit à 4h18, sont faits les backups des données
  • chaque nuit à 5h28, sont faits les dumps mysql
  • chaque lundi à 1h00, sont copiés les backups sur la machine distante.

Tout ce qui est normalement affiché à l’écran est loggué. S’il y a une erreur, elle sort sur stderr et est donc envoyé par email au propriétaire de la tâche (ici au root).

Il faut aussi penser à mettre une tâche cron sur la machine distante pour supprimer les backups trop vieux (ici toutes les sauvegardes de plus de 40 jours… soit environ 5 semaines) :

@weekly find /home/chabotsi/backups/* -mtime +40 -exec rm {} \;

@weekly est un alias pour dire 0 0 * * 1.

Mot de la fin

Une autre chose à voir, c’est comment restaurer les backups. Faire des backups, c’est bien. Être capable de s’en servir, c’est mieux ! Mais ça, je vous laisse regarder les exemples de la doc ;)

Je vous ai donné ces scripts juste comme ça pour l’exemple, pour que vous voyez un peu comme ça fonctionne. Faîtes vos backups comme vous voulez, mais faîtes en. Sinon, un jour vous vous direz que « oups… », ce sera trop tard et vous vous retrouverez comme deux ronds de flan devant votre machine à vous morfondre, à vous maudire… (Vous aurez été prévenu ! ^^)

[0]c’est là bas qu’est hébergé mon serveur dédié.
[1]oui, je fais les backups de cameron chez wilson (cf ici)
Published In informatique
Tags: hébergement

blogroll

social