Sauvegarde avec BURP

Un des problèmes récurrent sur toute infrastructure informatique est la gestion des sauvegardes. Ce qui commence par la simple copie manuelle d’un fichier peut aller jusqu’à des grosses infrastructures et des logiciels complexes et utilisant du matériel de stockage dédié.

Il n’y a pas d’outil qui réponde à tous les besoins, il est donc essentiel de bien les définir. Dans mon cas:

  • Il doit sauvegarder sur disque
  • Il doit pouvoir sauvegarder des postes mobiles et pas toujours allumés (un
  • portable par exemple).
  • Il doit permettre la sauvegarde incrémentale et optimiser l’espace de stockage.
  • Il doit sauvegarder tous les jours, et gérer des règles de rétention (par exemple 7 sauvegardes journalières, 4 hebdomadaires et 6 bi-mensuelles).
  • Il doit permettre la restauration totale ou partielle de la sauvegarde.
  • On doit pouvoir simplement et rapidement visualiser un fichier d’une sauvegarde donnée.
  • Et enfin il doit être simple à utiliser, à prendre en main et a configurer. Ça c’est juste pour exclure bacula :)

J’ai donc trouvé burp “Backup and restore program”, développé par un utilisateur frustré de bacula, il en tire quelques morceaux de code mais ce n’est pas un fork à proprement parler.

Installation

Burp fonctionne en client/serveur, l’installation est plutôt simple et c’est le même programme qui fait serveur et client, seule la configuration change. La version que j’ai utilisé c’est celle disponible dans les backports debian wheezy.

La communication entre le client et le serveur est protégée par des certificats SSL qui permettent à la fois de chiffrer le contenu de d’authentifier le client. Le serveur fait office de CA, le client envoie une demande de signature CSR et le serveur signe le certificat en se basant sur le CNAME du client et un mot de passe partagé. Toute la procédure de génération des certificats et de la signature est simplifiée.

# /etc/burp/burp.conf du client
mode = client
server = 1.2.3.4
port = 4971
cname = client1
password = secret
ssl_peer_cn = burpserver
# /etc/burp/burp.conf du serveur
mode = server
port = 4971
ca_server_name = burpserver
# /etc/burp/clientconfigdir/client1 sur le serveur
password = secret

Au premier lancement du serveur la CA et les certificats sont générés et il ne nous reste plus qu’à lancer une commande coté client pour finaliser l’échange et la signature du certificat.

Fonctionnement

Le principe des sauvegardes est le suivant:

  • Le serveur est un démon tcp sur le port 4971
  • Le client est lancé régulièrement (toutes les 20 minutes par exemple) via une crontab avec la commande burp -at (timed backup)
  • Le serveur décide alors si c’est le bon moment pour faire une sauvegarde du client (cf le paramètre timer_arg)

On voit bien ici la possibilité de sauvegarder un portable.

La liste des fichiers et des options de sauvegarde peuvent être paramétrées coté serveur ou coté client Beaucoup de possibilités ici: expression régulières, compression etc, voyez la partie “INCLUDE / EXCLUDE” du manuel.

Shuffling

La sauvegarde se fait avec librsync, c’est à dire que burp ne va transférer sur le réseau que ce qui a changé par rapport à la dernière sauvegarde.

À la fin du transfert il y a une phase post sauvegarde appelée ‘shuffling’, là on a deux stratégies possibles contrôlés avec l’option hardlinked_archive et qui prend 0 ou 1 comme valeur.

Avec 0 (valeur par défaut), burp va appliquer le delta qui permet d’obtenir la dernière version du fichier et ensuite générer le ‘reverse-delta’ (patch inverse) qui permet de revenir à l’ancienne version et enfin il va supprimer l’ancienne version du fichier.

  • Avantages: L’espace occupé est optimal et la sauvegarde la plus récente se restaure très rapidement.
  • Inconvénient: La phase de shuffling est intensive en CPU et l’opération de restauration des anciennes sauvegardes est aussi intensive en CPU (puisqu’il faut appliquer les reverse-delta).

Avec 1, si le fichier n’a pas changé il va créer un hard-link

  • Avantages: La phase de shuffling et la restauration des sauvegardes est très rapide.
  • Inconvénient: Si un seul octet a changé dans un fichier de 1MB, burp va stocker à nouveau un fichier de 1MB. Et même si le fichier n’a pas changé il va quand même allouer un inode. La taille de la sauvegarde est plus importante qu’avec hardlinked_archive à 0.

Pour résumer, c’est tout simplement CPU versus de l’espace disque.

Burp a aussi des options de déduplication qui permettent de gagner l’espace disque utilisé par des fichiers identiques sur les backups d’un ou de plusieurs clients (ici aussi, CPU VS espace disque).

Snapshot LVM, pg_dump ?

Si vous utilisez LVM, vous pouvez prendre un instantané (snapshot) du système de fichier et le sauvegarder. Vous aurez ainsi une sauvegarde atomique et c’est obligatoire pour sauvegarder par exemple des bases de donnée et s’assurer l’intégrité de la sauvegarde.

De la même manière vous pourriez vouloir sauvegarder la sortie d’une commande de type pg_dump, mysqldump.

Burp peut exécuter des scripts pre/post sauvegarde coté serveur et coté client.

Dans le cas de LVM, il suffit de faire un script qui crée les snapshots, éventuellement qui mappe les partitions avec kpartx puis qui les montent dans /mnt/burp/XXX et ensuite configurer burp pour les sauvegarder.

Pour la sortie des commandes, la technique consiste à utiliser un fifo, car oui burp sait sauvegarder le contenu d’un fifo et même d’un bloc device:

read_fifo=/path/to/fifo
read_blockdev=/path/to/device

Restauration

Que serait la sauvegarde sans la restauration ? Avez vous déjà restauré une sauvegarde et vérifié qu’elle fonctionnait ? La restauration est centrale dans un système de sauvegarde et là encore burp nous facilite la tâche.

  • On peut restaurer depuis le client ou depuis le serveur voire même depuis un autre client (avec l’option restore_client).
  • Restauration vers le chemin d’origine ou dans répertoire donné.
  • La restauration peut être partielle en utilisant des expressions régulières

Voilà un exemple de restauration:

# on liste les sauvegardes
% burp -al
[...]
Backup: 0000069 2015-04-22 03:07:01
Backup: 0000070 2015-04-23 03:07:01
Backup: 0000072 2015-04-25 03:07:01 (deletable)
2015-04-25 20:59:08: burp[24071] List finished ok
[...]
% burp -ar -b 69 -d out -r '^/etc'
[...]
2015-04-25 21:01:35: burp[24511] doing restore
-----------------------------------------------------
Start time: 2015-04-25 21:01:35
End time: 2015-04-25 21:01:42
Time taken: 00:07
Attempted | Expected
------------------------------
Files:                1424 |     1424
Directories:                 310 |      310
Soft links:                1326 |     1326
Grand total:                3060 |     3060
------------------------------
Warnings:             0
Bytes estimated:       6749807 (6.44 MB)
Bytes attempted:             0
Bytes sent:             0
----------------------------------------------------
2015-04-25 21:01:42: burp[24511] got restore end
2015-04-25 21:01:42: burp[24511] restore finished
# dans ./out on a /etc de la sauvegarde du 2015-04-22
% find out
out
out/etc
out/etc/python3
out/etc/python3/debian_config
out/etc/modules
out/etc/sane.d
out/etc/sane.d/dmc.conf
out/etc/sane.d/sm3840.conf
out/etc/sane.d/net.conf
out/etc/sane.d/teco1.conf
[...]