Le contenu de plusieurs répertoires de bulbe est sauvegardé (après chiffrement) sur une machine distante, via SFTP.

Le programme utilisé pour générer et comparer des snapshots d'arborescences de fichiers, et optionnellement pour réaliser leur chiffrement GPG et leur transfert par SFTP est Obnam. C'est donc aussi ce programme qu'on utilisera pour restaurer un ou plusieurs fichiers à partir d'une génération de sauvegarde (backup generation).

Les répertoires dont le contenu est sauvegardé sont listés dans /etc/backup.d/90.obnam.sh, lui-même exécuté quotidiennement par backupninja.

Accéder aux sauvegardes

Telles que configurées, l'accès aux sauvegardes de bulbe nécessite des clefs privées (GPG et SSH) présentes dans le répertoire personnel de root, ce qui implique l'utilisation systématique de l'option -H de la commande sudo. Cependant, la présence des paramètres repository et encrypt-with dans /etc/obnam.conf permet de ne pas avoir à spécifier les options correspondantes en ligne de commande.

Pour accéder aux sauvegardes, il n'y a aucun intérêt à ouvrir une connexion sftp au serveur dans une console. Les fichiers de sauvegardes ne sont pas exploitables en l'état et toute manipulation risque d'avoir un effet désastreux. C'est donc toujours la commande obnam qu'on utilisera, soit pour lire dans la base distante ou locale, soit pour y écrire.

Il y a deux façons d'accéder localement à la base de sauvegardes, ces deux modes d'accès étant liés à des cas d'usage très différents.

obnam mount

Obnam utilse FUSE pour monter localement la base de sauvegardes en tant que système de fichiers virtuel. L'ensemble des générations de sauvegardes apparaît comme autant de répertoires (ayant pour noms les identifiants de generations) contenant chacun tous les fichiers sauvegardés. Même si les sauvegardes sont chiffrées, là tout apparaît en clair, donc directement exploitable. Évidemment, seules les opérations de lecture sont autorisées.

sudo -H obnam mount ne fonctionne pas, il est nécessaire d'ouvrir d'abord un shell root :

sudo -Hs
mkdir /tmp/backups
obnam mount --to /tmp/backups
ls -l /tmp/backups
[...]
fusermount -u /tmp/backups
exit

sshfs

Sur des opérations un peu lourdes, ou si la base de sauvegardes est dans un mauvais état, il peut être intéressant de déléguer à sshfs la connexion au serveur, et dans ce cas de dire à obnam d'opérer sur la base locale. Mais d'abord, installer le paquet :

sudo apt-get install sshfs

sshfs utilise aussi FUSE, et là aussi il faudra ouvrir un shell root pour que le montage fonctionne :

sudo -Hs
mkdir /tmp/sshfs
sshfs user@server:/path/to/backups /tmp/sshfs
obnam --repository /tmp/sshfs [OPTIONS] COMMAND
[...]
fusermount -u /tmp/sshfs
exit

Manipuler les sauvegardes

Déverrouiller les sauvegardes

Pour éviter des accès concurrents en écriture sur les mêmes fichiers, obnam utilise un système de verrou (des fichiers lock dans tous les répertoires concernés). En cas de perte de la connexion, les verrous ne sont pas nettoyés, ce qui interdit toutes les opérations ultérieures nécessitant un accès en écriture. Il existe donc une commande spécifique pour reprendre la main :

sudo -H obnam force-lock

Lister les générations de sauvegardes

Dans le langage d'Obnam, le résultat d'une opération de sauvegarde s'appelle une generation. Par défaut, chaque commande d'obnam a une portée qui lui est propre en termes de generations et peut donc s'appliquer soit à l'ensemble des sauvegardes effectuées, soit à la dernière, soit une en particulier, etc. Il est donc important de savoir lister ces generations pour pouvoir ensuite les manipuler :

sudo -H obnam generations
[…]
47      2013-12-21 01:00:53 .. 2013-12-21 01:01:39 (13438 files, 2041663192 bytes)
[…]

Le premier champ est l'identifiant de generation et peut être utilisé comme argument de la commande forget ou de l'option --generation (qui par défaut vaut latest).

Vérifier une sauvegarde

Pour vérifier l'état de la dernière sauvegarde, ou pour vérifier si des fichiers ont été modifiés depuis :

sudo -H obnam verify --root /usr/local/bin

L'option --root DIR est obligatoire; elle permet de spécifier quelle partie de l'arborescence sauvegardée on veut vérifier. Pour une vérification complète, on indique --root / :

sudo -H obnam verify --root /

Mais compte tenu du grand nombre de fichiers à manipuler, du chiffrement GPG et du stockage distant, la commande peut être assez longue (compter plus d'une heure sur bulbe), assez en tout cas pour que de nombreux fichiers aient été modifiés depuis son lancement. L'option --verify-randomly N permet un autre type de vérification partielle en s'appliquant sur un nombre N de fichiers choisis aléatoirement dans l'arborescence spécifiée par --root DIR :

sudo -H obnam verify --root / --verify-randomly 2000

Tester l'intégrité d'une sauvegarde

Pour un test plus poussé – et beaucoup plus long – relatif à l'intégrité et à la cohérence des sauvegardes – et ceci indépendamment de ce qui se trouve effectivement sur le système de fichiers local – on peut utiliser la commande fsck. Lancée sans autre option, elle s'applique à l'ensemble des generations et peut prendre plusieurs jours, voire plusieurs semaines en mobilisant une part non négligeable des ressources du système local. On l'utilisera donc plutôt avec un filtre, par exemple (compter trois bonnes heures) :

sudo -H obnam fsck --fsck-last-generation-only

Restaurer des fichiers

Lors d'une opération de restauration, les répertoires parents du fichier à restaurer, s'ils n'existent pas, sont créés (mais attention, avec umask 077, soit des droits à 700) : soit dans le répertoire courant, soit dans celui donné en argument de l'option --to. Pour restaurer à leurs emplacements d'origine sur le système local des fichiers ou des répertoires particuliers, il est donc nécessaire soit de se déplacer dans /, soit de spécifier --to / :

sudo -H obnam restore /home/quidame/etc/cron.d/test --to /

Cette commande restaurera la version la plus récente du fichier spécifié présente dans la base de sauvegarde. Cependant, on peut aussi vouloir restaurer un fichier à partir d'une sauvegarde plus ancienne. Dans ce cas, il faut d'abord lister les différentes générations de sauvegardes, et utiliser la valeur du premier champ de la ligne qui nous intéresse comme argument de l'option --generation :

sudo -H obnam --generation 2337 restore /usr/local/bin/foo --to /tmp/bar

Dans ce cas on retrouvera notre fichier à /tmp/bar/usr/local/bin/foo. Mais attention : seul le dernier élément du chemin de ce qu'on veut restaurer l'est avec ses permissions et propriétaires d'origine. Les répertoires intermédiaires créés par obnam ont les permissions 700 (umask 077). Les permissions et propriétaires des répertoires déjà existants ne sont pas modifiées. Le répertoire de destination (ici, /tmp/bar) n'a pas besoin d'exister. Même s'il existe, ses permissions passent à 700.

Éclaicir l'historique

Pour éviter que la taille et le nombre de sauvegardes impacte trop les performances d'obnam, il peut être intéressant d'oublier certaines générations de sauvegardes avec la commande forget et son option --keep RULES, les RULES en question définissant ce qu'on va conserver. Par exemple :

sudo -H obnam forget --keep 100d,105w,60m

permet de ne conserver que les générations de sauvegardes suivantes :

100d
Les dernières sauvegardes du jour, sur les 100 derniers jours
105w
Les dernières sauvegardes de la semaine, sur les 105 dernières semaines (2 ans)
60m
Les dernières sauvegardes du mois, sur les 5 dernières années

Changer de clef GnuPG

Il peut arriver d'avoir à changer de clef de chiffrement, parce que celle utilisée jusque là n'est plus considérée comme sûre. Pour cela, on va d'abord générer une nouvelle clef, puis utiliser les commandes list-keys, list-toplevels, add-key et remove-key.

todo: à documenter. Un script d'exemple existe dans la documentation d'obnam.

Restaurer une base de données

PostgreSQL

Sur bulbe, plusieurs services utilisent PostgreSQL. backupninja se charge de faire un dump de chaque base de données et de les poser dans /var/backups/postgres. Pour restaurer une telle base de données, on commence par récupérer le dump (archive tar compressée) avec obnam restore, puis on utilise pg_restore et psql pour effectuer la restauration proprement dite :

sudo -H obnam generations
sudo -H obnam --generation 28570 restore /var/backups/postgres --to /tmp/pg
sudo mv /tmp/pg/var/backups/postgres/* /tmp/pg
sudo gunzip /tmp/pg/*.gz
sudo chown -R postgres:postgres /tmp/pg

On se retrouve avec un fichier globals.sql et autant de fichiers *.pg_dump qu'on a de bases de données (au minimum, postgres.pg_dump). À partir de là, on a deux possibilités :

  • La base de données existe
  • La base de données n'existe pas

Si la base de données n'existe pas ou plus ou n'est plus accessible parce que la version de PostgreSQL a changé, il faut ajouter l'option --create à la commande pg_restore :

sudo su -l postgres
pg_restore -f /tmp/pg/bley.sql /tmp/pg/bley.pg_dump
psql < /tmp/pg/bley.sql

Si on a tout perdu, ou lors d'une migration de PostgreSQL, l'ordre de traitement des fichiers est le suivant :

  1. postgres.pg_dump
  2. globals.sql
  3. les autres .pg_dump

Debconf

backupninja se charge aussi, via son plugin sys, de créer deux fichiers debconfsel.txt et dpkg-selections.txt dans /var/backups. Le premier permet de restaurer la base de données des réponses aux questions posées par debconf et de reconfigurer les paquets en conséquence :

sudo -s
debconf-set-selections < /var/backups/debconfsel.txt
dpkg-reconfigure --unseen-only --default-piority PAQUETS
exit

Le second contient la liste des paquets installés ou supprimés dans un format exploitable par dpkg :

sudo -s
dpkg --clear-selections
dpkg --set-selections < /var/backups/dpkg-selections.txt
apt-get dselect-upgrade
exit

Si on doit restaurer l'état d'installation des paquets et leur configuration, il faut opérer dans l'ordre indiqué ci-dessus mais sans passer par l'étape dpkg-reconfigure.