Sauvegarder les données de son serveur avec rsync

Ah mais cette fois j’en ai marre … marre de lire à gauche et à droite que rsync n’est pas un outil de backup digne de ce nom. Je m’en vais vous montrer le contraire, et pas plus tard que tout de suite !

Introduction

Soit la situation suivante : j’ai un serveur dédié, par exemple en release 2 OVH (mais cela marchera tout aussi bien avec d’autres distributions Linux). Mes données se trouvent dans /home et je souhaite en faire une sauvegarde quotidienne et incrémentale sur un autre serveur (Linux lui aussi, voire pourquoi pas en release 2).

Incrémentale ? Bah oui, tant qu’à faire, je souhaite ne sauvegarder que les fichiers créés ou modifiés depuis la veille, tout en gardant évidemment un backup complet de mes données aussi récent que possible. Cela n’offre que des avantages :

  1. Économie de temps de transfert et de bande passante (puisqu’on ne transfère tous les jours que les fichiers qui ont été ajoutés / modifiés)
  2. On dispose toujours d’un backup complet qui date du matin même (les backups se faisant la plupart du temps la nuit ou au petit matin)
  3. On garde un historique des fichiers qui ont été modifiés au jour le jour. Idéal en cas de hack du serveur, au premier coup d’oeil : on voit ce qui a été ajouté / modifié et à quelle date.

Création d’un utilisateur sur le serveur de backup

On commence par créer un user dont le répertoire sera dédié au backup. Cela peut se faire en SSH via la commande adduser ou bien par Webmin :  Système > Utilisateurs et groupes > Créer un nouvel utilisateur

Dans mon exemple, mon utilisateur se nommera backupserveur1.

Mise en place des clés SSH

Il faut faire en sorte que les deux serveurs puissent dialoguer de manière cryptée et sans devoir s’échanger de mot de passe. Donc, si ce n’est pas encore fait, il convient de générer une paire de clés SSH.

Donc, sur le serveur source (le serveur à sauvegarder) :
ssh-keygen -b 1024 -t dsa

(valider par la touche “enter” les questions qui vous sont posées)

Personnellement, je dédie ces clés à la procédure de backup entre les 2 serveurs, je les stocke donc dans un répertoire différent. Par exemple :

mkdir /usr/share/keys/
mv /root/.ssh/id_dsa.pub /usr/share/keys/key-rsync.pub
mv /root/.ssh/id_dsa /usr/share/keys/key-rsync

Il convient à présent de copier la clé publique (pas de gaffe, attention) dans le fichier authorized_keys de l’utilisateur backupserveur1 sur le serveur de backup. Il s’agit donc de copier le contenu de key-rsync.pub dans /home/backupserveur1/.ssh/authorized_keys (voire authorized_keys2 selon votre configuration SSH).

Le script

C’est là que ça devient rigolo car le script lui-même tient en une seule et unique ligne que vous pouvez, par exemple créer dans un fichier /root/toto/backup.sh:

#!/bin/bash

rsync -a -e "ssh -i /usr/share/keys/key-rsync" -b --backup-dir=../home-`date -I` --delete /home/ --exclude-from=/root/toto/backup-exclude backupserveur1@11.22.33.44:home/

A mettre en cron, une fois par jour vers 5 heure du matin par exemple.

Explications

Quel sera l’effet de cette ligne de code ?

Elle va tout simplement synchroniser votre répertoire /home avec le répertoire éponyme, lui même situé dans le répertoire de backupserveur1 sur le serveur à distance (donc dans /home/backupserveur1/home). Vous aurez donc ainsi un miroir de votre /home sur le serveur de backup, mis à jour quotidiennement. Jusque là, c’est déjà pas mal … mais en plus cela aura pour effet de créer un répertoire /home/backupserveur1/home-AAAA-MM-JJ qui contiendra tous les fichiers qui ont été modifiés depuis la veille, et seulement eux !

Alors, plutôt sympa rsync, non ? 😉

Dans l’instruction ci-dessus, notez que :

  1. /usr/share/keys/key-rsync doit correspondre à l’emplacement de votre clé SSH
  2. backupserveur1 est bien sûr le nom de l’utilisateur que vous avez préalablement créé sur le serveur de backup
  3. 11.22.33.44 correspond à l’adresse IP du serveur de backup
Attention au fichier /root/toto/backup-exclude

Comme je le disais ci-dessus, ce mini-script sauvegarde l’intégralité de votre /home … ce qui n’est pas forcément souhaitable. Il est donc prévu un fichier “backup-exclude” où vous pouvez lister tous les fichiers et/ou répertoires qui se trouvent dans /home et que vous ne souhaitez pas sauvegarder.

Cette fonction est absolument essentielle sur les serveurs en release 2 OVH car les bases de données MySQL se trouvent précisément dans /home/mysql (c’est une originalité de cette distribution) et le fait de copier les fichiers qui s’y trouvent ne constitue pas un bon backup des bases. A vrai dire, il est même fortement recommandé de ne pas toucher à ces fichiers (donc de ne pas les copier) quand MySQL tourne. Et comme MySQL tourne en permanence … pas touche ! Pour savoir comment backuper proprement vos base, voyez ce billet : Bases de données MySQL : backup quotidien (que vous pouvez d’ailleurs astucieusement combiner avec le système de backup décrit ici)

A titre personnel, sur les serveurs en release OVH, je ne sauvegarde pas les logs ni les stats des sites hébergés (en plus du fameux /home/mysql). Voici donc à quoi ressemble mon “backup-exclude” :

/log
/mysql
www/stats

Je crois que c’est à peu près tout, ouf 🙂

Ah non, j’oubliais, il convient de lancer une première fois le scirpt “à la main” pour que les deux serveurs puisse se reconnaitre. Il s’agit donc simplement de taper…

sh /root/toto/backup.sh

… et de répondre par “yes” à la question qui est posée. Cette question ne sera plus posée à l’avenir et le script peut alors être mis en tâche cron, il s’exécutera sans problème. Notez aussi que ce premier backup risque d’être assez long (cela dépend évidemment quantité de données à transférer) puisque toutes vos données vont devoir être copiées une première fois. Par la suite, les backup seront nettement plus rapide dans la mesure ou seuls les nouveaux dossiers/fichiers (ainsi que ceux qui auront été modifiés) seront transférés quotidiennement.