Comment versionner automatiquement un dossier cible sous Linux grâce à un snapshot Btrfs, systématiquement après l’avoir synchronisé avec rsync.
Introduction
Je vous propose ci-dessous une méthode sous Linux, pour synchroniser un dossier source vers un dossier cible en mode miroir, c’est à dire où les fichiers supprimés de la source sont également supprimés de la cible. Le dossier cible sera systématiquement versionné après la sauvegarde (si possible en mode blocs), et non pas à fréquence fixe par un déclenchement cron, afin de ne pas versionner pour rien.
Pour cela, j’utilise rsync en mode –delete, et le snapshot Btrfs.
Configuration coté serveur de sauvegarde
Le serveur de sauvegarde fait tourner en permanence le daemon rsync. Ce daemon utilise les fichiers de configuration suivants : /etc/rsyncd.conf et /etc/rsyncd.secrets .
Pour la configuration, je vous passe le rsyncd.secrets ainsi que les lignes de configuraton générales de rsyncd.conf pour me concentrer sur les ressources rsync, aussi appelées modules rsync.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[data] path=/data/org/ [dir-1] path=/data/org/dir-1/ [dir-2] path=/data/org/ post-xfer exec=/usr/local/bin/snapshot-dir-2 [dir-3] path=/data/org/ post-xfer exec=/usr/local/bin/snapshot-dir-3 |
Ici le module data pointe vers le dossier org de mon disque de sauvegarde formaté en Btrfs et monté dans /data. Le /data/org (données originales) fait écho au /data/snapshot (données snapshotées).
Le module dir-1 pointe vers un répertoire du même nom, classique.
Les modules dir-2 et dir-3 pointent vers le même dossier org car je souhaite mélanger le contenu de ces dossiers sur le serveur de sauvegarde. Mais ces modules lancent des scripts de snapshot qui sont différents, chaque script va snapshoter les dossiers qui vont bien.
Les modules rsync sont indispensables pour affecter un script post-transfert à un répertoire. Je crois me souvenir que le point est interdit dans le nom du script, sous peine de non-exécution.
Dans le cas d’une sauvegarde sur internet, il faudra sécuriser les échanges par le tunnel SSH, tout en conservant les modules rsync. Coté client l’authentification SSH sera demandée juste avant le mot de passe du module rsync.
Voici un exemple de script de snapshot snapshot-dir-1 . J’ai adopté un format à la syslog dans /var/log/scripts.log .
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/bin/bash TIMESTAMP=$(date +%Y%m%d-%H%M%S) DATE=$(LANG=us_US date "+%b %d %H:%M:%S") HOSTNAME=$(hostname | cut -f1 -d'.') ME=$(basename $0) LOGFILE="/var/log/scripts.log" for i in subdir1 subdir2 do echo "$DATE $HOSTNAME $ME: start snapshot $i" | tee >> $LOGFILE btrfs subvolume snapshot -r /data/org/$i /data/snapshots/$TIMESTAMP.$i echo "$DATE $HOSTNAME $ME: end snapshot $i" | tee >> $LOGFILE done |
Pour ce script, je choisis de ne pas snapshoter les répertoires dir-[1-3] en entier, mais de spécifier leurs sous-répertoires qui seront snapshotés. Cela implique que les sous-répertoires à snapshoter ne doivent pas être des dossiers comme les autres, mais des subvolumes btrfs. Par exemple, le dossier /data/org/dir-1/subdir1 a été créé ainsi :
1 2 |
root@ordinateur:~# mkdir -p /data/org/dir-1 root@ordinateur:~# btrfs subvolume create /data/org/dir-1/subdir1 |
Configuration coté client de copie
Voici un exemple de script de sauvegarde avec rsync. Il n’a rien de spécial. Je m’autorise ici le --delete car mon système de fichiers cible est versionné par snapshot, ce qui signifie que je pourrai toujours revenir en arrière en cas de suppression ou modification par erreur de mes données.
1 2 3 |
RSYNC_PASSWORD="password" /usr/bin/rsync -rtvyy --delete --partial --progress --inplace /dir-1/ htpc::dir-1/ RSYNC_PASSWORD="password" /usr/bin/rsync -rtvyy --delete --partial --progress --inplace /dir-2/* htpc::dir-2/ RSYNC_PASSWORD="password" /usr/bin/rsync -rtvyy --delete --partial --progress --inplace /dir-3/* htpc::dir-3/ |
A chaque fois qu’un module rsync est utilisé, le script de post-transfert va s’exécuter sur le serveur. En surveillant le fichier de log on devrait trouver :
1 2 3 4 |
Jan 16 19:13:33 ordinateur snapshot-dir-2: start snapshot subdir1 Jan 16 19:13:33 ordinateur snapshot-dir-2: stop snapshot subdir1 Jan 16 19:13:37 ordinateur snapshot-dir-3: start snapshot subdir2 Jan 16 19:13:37 ordinateur snapshot-dir-3: stop snapshot subdir2 |
Limitations de la méthode proposée
La méthode proposée souffre d’un inconvénient, c’est que la copie des fichiers entre le client et le serveur de copie ne peut pas être une copy-on-write (CoW). Donc le versioning par défaut est en mode fichiers et non en mode blocs. En effet, dès que rsync détecte une modification dans un fichier, il commence par créer un nouveau fichier temporaire avec un nouvel inode pour le remplir. A ce stade, nous avons reproduit le comportement de rsnapshot sans le dépasser.
Une optimisation importante apparaît, c’est l’option --inplace de rsync qui permet de conserver l’inode du fichier cible, et donc de laisser comprendre au système CoW que le fichier cible et sa copie snapshotés n’ont que quelques blocs d’écart (au lieu du fichier entier). Ce réflexe m’apparaît comme étant plutôt logique lorsqu’on connaît rsync, et cela semble être confirmé par d’autres sources.
Pour faire mieux, il faut pratiquer une copy-on-write entre la source et la cible, ce qui implique que le versioning doit être sur le même système de fichiers que les données originales. Pour cela, plus besoin d’utiliser rsync mais simplement un snapshot de subvolume Btrfs (cf. ci-dessus), ou encore un simple cp --reflink. A ce jour, seul Btrfs gère les reflinks.
Pour la sauvegarde distante avec rsync on peut donc se poser la question : soit on ne versionne pas, soit on versionne en mode fichiers au prix d’une surconsommation. Pour des dossiers constitués de petits fichiers comme /etc , /usr ou /var/www , la surconsommation engendrée sera pas tolérable. Les cas de figure les moins favorables au versioning en mode fichiers sont les très gros fichiers comme les images disques : la conservation d’une version coûtera la taille du fichier en entier.
Pourquoi est-ce utile ?
Le snapshot Btrfs ouvre de nombreuses possibilités pour conserver des états antérieurs de répertoires complets, et donc remonter le temps à la recherche du fichier tel qu’il était avant sa dernière modification ou suppression involontaire.
Imaginez un cas de figure où votre ordinateur est infecté par un ransomware qui crypte tous vos fichiers (sur le disque système et tous les partages réseau), et vous demande ensuite une somme d’argent pour les décrypter. Imaginez que vous vous en rendiez compte trop tard, de sorte que vos sauvegardes ont été écrasées par des fichiers corrompus.
Si vous avez préalablement snapshoté vos données, ce ransomware ne pourra plus vous faire du chantage car la restauration des données ne sera qu’une simple formalité. On se rend donc compte que le snapshot, qui n’est pas une sauvegarde, peut également apporter des avantages sécuritaires en permettant de remonter le temps.
Excellent article
Merci