Table des matières

Sauvegarde avec Duplicity

Duplicity est un programme de sauvegarde incrémentale pour systèmes GNU/Linux tels Debian ou Ubuntu. Il permet de réaliser des sauvegardes à distance (via ssh et scp, rsync, ftp, ou Amazon S3) en chiffrant les données. Le processus utilisé par Duplicity consiste en un full backup suivi d’une série de backup incrémental sous la forme d’archives TAR chiffrées par GnuPG.

Fonctionnement

Duplicity effectue des sauvegardes complètes et incrémentales. Les sauvegardes incrémentales nécessitent toutes les sauvegardes depuis la dernière complète pour être restaurées. Personnellement, j’effectue une sauvegarde complète tous les mois, et une incrémentale tous les jours. Pour choisir le mode :

Exemple

(à exécuter en root pour avoir accès à tous les fichiers) :

duplicity / file:///srv/backups/duplicity/ --include-globbing-filelist filelist.txt --exclude '**'

Duplicity va sauvegarder à partir de la racine (“/”) tous les fichiers selon les règles d’inclusion et d’exclusion définies dans filelist.txt. Ce fichier contient simplement la liste des fichiers et répertoires à sauvegarder, ainsi que ceux à exclure. Par exemple :

filelist.txt
/usr/local/bin/
/home/user/Maildir/
/home/user/.procmailrc
- /var/www/blog/wp-content/cache/
/var/www/blog/

Attention : les fichiers et répertoires à exclure doivent apparaître avant l’inclusion d’un répertoire parent. En effet, duplicity s’arrête à la première règle qui matche un chemin donné pour déterminer s’il doit l’inclure ou l’exclure. Pour restaurer :

duplicity restore file:///var/backups/duplicity/ /any/directory/

(utiliser l’option -t pour restaurer à une date particulière) Pour supprimer les anciennes sauvegardes (ici de plus de 2 mois) :

duplicity remove-older-than 2M file:///var/backups/duplicity/ --force

Chiffrement

Duplicity utilise GnuPG pour le chiffrement, permettant :

L’utilisation d’une clé privée offre une meilleure sécurité.

Installation

apt-get update && apt-get install duplicity

Configuration

Génération d'une clef de cryptage

Sur un autre ordinateur que le serveur (votre ordinateur de travail), nous créons une paire de clef pour l'utilisateur root et nous exportons la clef publique dans un fichier. Cet ordinateur devrait être configurer comme indiqué sur la page de configuration GnuPG.

gpg2 --gen-key
gpg (GnuPG) 2.0.28; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Sélectionnez le type de clef désiré :
   (1) RSA et RSA (par défaut)
   (2) DSA et Elgamal
   (3) DSA (signature seule)
   (4) RSA (signature seule)
Quel est votre choix ? 1
les clefs RSA peuvent faire une taille comprise entre 1024 et 4096 bits.
Quelle taille de clef désirez-vous ? (2048) 4096
La taille demandée est 4096 bits
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n'expire pas
      <n>  = la clef expire dans n jours
      <n>w = la clef expire dans n semaines
      <n>m = la clef expire dans n mois
      <n>y = la clef expire dans n ans
Pendant combien de temps la clef est-elle valable ? (0) 0
La clef n'expire pas du tout
Est-ce correct ? (o/N) O

GnuPG doit construire une identité pour identifier la clef.

Nom réel : Admin
Adresse électronique : root@domaine.eu
Commentaire : Administration serveurs
Vous avez sélectionné cette identité :
    « Admin (Administration serveurs) <root@domaine.eu> »

Faut-il modifier le (N)om, le (C)ommentaire, l'(A)dresse électronique
ou (O)ui/(Q)uitter ? O
Une phrase secrète est nécessaire pour protéger votre clef secrète.

De nombreux octets aléatoires doivent être générés. Vous devriez faire
autre chose (taper au clavier, déplacer la souris, utiliser les disques)
pendant la génération de nombres premiers ; cela donne au générateur de
nombres aléatoires une meilleure chance d'obtenir suffisamment d'entropie.
De nombreux octets aléatoires doivent être générés. Vous devriez faire
autre chose (taper au clavier, déplacer la souris, utiliser les disques)
pendant la génération de nombres premiers ; cela donne au générateur de
nombres aléatoires une meilleure chance d'obtenir suffisamment d'entropie.
gpg: clef 0x555CCC000FFF7777 marquée de confiance ultime.
les clefs publique et secrète ont été créées et signées.

gpg: vérification de la base de confiance
gpg: 3 marginale(s) nécessaire(s), 1 complète(s) nécessaire(s),
     modèle de confiance PGP
gpg: profondeur : 0  valables :   1  signées :   0
     confiance : 0 i., 0 n.d., 0 j., 0 m., 0 t., 1 u.
gpg: la prochaine vérification de la base de confiance aura lieu le 2017-12-31
pub   4096R/0x555CCC000FFF7777 2016-01-01
      Empreinte de la clef = AAAA BBBB CCCC DDDD EEEE  0000 555C CC00 0FFF 7777
uid                [  ultime ] Admin (Administration serveurs) <root@domaine.eu>
sub   4096R/0xFF0FF055077CC88A 2016-01-01

Générer une seconde sous-clef

Après la génération d'une paire de clés, nous disposons d'une paire de clés maîtresse et d'une sous-clef pour le chiffrement. Nous créons une nouvelle sous-clé pour la signature des documents afin de ne pas avoir à utiliser la clé principale sur le serveur.

gpg2 --edit-key AAAABBBBCCCCDDDDEEEE0000555CCC000FFF7777  
gpg (GnuPG) 2.0.28; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

La clef secrète est disponible.

pub  4096R/0x555CCC000FFF7777  créé : 2016-01-01  expire : jamais       utilisation : SC  
                               confiance : ultime        validité : ultime
sub  4096R/0xFF0FF055077CC88A  créé : 2016-01-01  expire : jamais       utilisation : E   
[  ultime ] (1). Admin (Administration serveurs) <root@domaine.eu>

gpg> addkey
La clef est protégée.

Une phrase secrète est nécessaire pour déverrouiller la clef secrète de
l'utilisateur : « Admin (Administration serveurs) <root@domaine.eu> »
clef RSA de 4096 bits, identifiant 0x555CCC000FFF7777, créée le 2016-01-01

Sélectionnez le type de clef désiré :
   (3) DSA (signature seule)
   (4) RSA (signature seule)
   (5) Elgamal (chiffrement seul)
   (6) RSA (chiffrement seul)
Quel est votre choix ? 4
les clefs RSA peuvent faire une taille comprise entre 1024 et 4096 bits.
Quelle taille de clef désirez-vous ? (2048) 4096
La taille demandée est 4096 bits
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n'expire pas
      <n>  = la clef expire dans n jours
      <n>w = la clef expire dans n semaines
      <n>m = la clef expire dans n mois
      <n>y = la clef expire dans n ans
Pendant combien de temps la clef est-elle valable ? (0) 2y
La clef expire le lun. 01 janv. 2018 23:59:59 CET
Est-ce correct ? (o/N) o
Faut-il vraiment la créer ? (o/N) o
De nombreux octets aléatoires doivent être générés. Vous devriez faire
autre chose (taper au clavier, déplacer la souris, utiliser les disques)
pendant la génération de nombres premiers ; cela donne au générateur de
nombres aléatoires une meilleure chance d'obtenir suffisamment d'entropie.

pub  4096R/0x555CCC000FFF7777  créé : 2016-01-01  expire : jamais       utilisation : SC  
                               confiance : ultime        validité : ultime
sub  4096R/0xFF0FF055077CC88A  créé : 2016-01-01  expire : jamais       utilisation : E   
sub  4096R/0xFF0FF055077CC88B  créé : 2016-01-01  expire : 2018-01-01  utilisation : S   
[  ultime ] (1). Admin (Administration serveurs) <root@domaine.eu>
gpg> save

Certificat de révocation

La génération d'un certificat de révocation est un étape importante dans la création de clés.

gpg2 --output revoke.asc --gen-revoke '<fingerprint>'

Exportation des clefs sur le serveur

La clef publique avec les sous-clefs secrètes doivent être exportées mais pas la clef privée maîtresse que nous garderons sur notre ordinateur.

gpg2 --armor --export 0x555CCC000FFF7777 > clepublique.asc
gpg2 --armor --export-secret-subkeys 0x555CCC000FFF7777 > sousclessecretes.asc

Puis les fichiers de nos clefs exportées seront envoyés sur le serveur.

scp clepublique.asc sousclessecretes.asc user@domaine.eu:/home/user/

Ensuite sur le serveur avec l'utilisateur 'root' nous importerons les clefs dans le trousseau du serveur.

gpg2 --import clepublique.asc sousclessecretes.asc

Pour vérifier nous utiliserons la commande gpg2 –list-secret-keys qui affichera :

gpg2 --list-secret-keys
/root/.gnupg/secring.gpg
------------------------
sec#  4096R/0x555CCC000FFF7777 2016-01-01
 Empreinte de la clef = AAAA BBBB CCCC DDDD EEEE  0000 555C CC00 0FFF 7777
uid                            Admin (Administration serveurs) <root@domaine.eu>
ssb   4096R/0xFF0FF055077CC88A 2016-01-01
ssb   4096R/0xFF0FF055077CC88B 2016-01-01

Le caractère # placé sur la ligne de la clé privée après sec indique qu'elle n'est pas disponible mais les deux sous-clefs privées sont bien présentes. Cette configuration peut être utiliser pour chiffrer et signer des documents.

Sauvegarder

Sauvegarde en local

Script de sauvegarde

Pour exécuter des sauvegardes régulières que nous pourrons lancer par une tâche Cron, voici un exemple de script à sauvegarder dans /usr/local/sbin/.

backup
#!/bin/bash
#  backup.sh
#  Source originale :
#  http://blog.rom1v.com/2013/08/duplicity-des-backups-incrementaux-chiffres/
#  Source complémentaire
#  https://www.debian-administration.org/article/209/Unattended_Encrypted_Incremental_Network_Backups_Part_1
#  Script modifié par d2air
#  Version 1
#
#  Le répertoire des sauvegardes doit être sur une partition large
#  sur le formatage par défaut du Kimsufi l'espace est restreint si dans /srv/backups
#
BACKUP_HOME=/srv/backups
BACKUP_DIR="$BACKUP_HOME/duplicity"
ENCRYPT_KEY="0FFF7777"
FILELIST="/etc/
- /home/user/Downloads
/home/user/
/srv/backups/mysqldump/
/var/lib/mysql/
/var/lib/automysqlbackup/
/var/log/
/var/www/"
 
# duplicity
printf '## Backup using duplicity...\n'
unset mode
[ "$1" = full ] && mode=full && printf '(force full backup)\n'
mkdir -p "$BACKUP_DIR"
duplicity $mode --encrypt-key "$ENCRYPT_KEY" --include-globbing-filelist <(echo "$FILELIST") --exclude '**' / file://"$BACKUP_DIR"/
 
printf '## Delete old backups\n'
duplicity remove-older-than 2M file://"$BACKUP_DIR"/ --force
 
# backups are encrypted, we can make them accessible
chmod +r "$BACKUP_DIR"/*.gpg

Une fois configuré, il ne faudra pas oublier d'exécuter le script et de restaurer les données dans un répertoire de test, puis de vérifier que tout est OK. Cette vérification devra être effectuée de temps en temps, il serait dommage de s’apercevoir lorsque nous en aurons besoin que les sauvegardes sont inutilisables ou qu’un répertoire important fut oublié.

nano /usr/local/sbin/backup
chmod 700 /usr/local/sbin/backup
cd /usr/local/sbin/
./backup

Sauvegarde sur un serveur

Configuration du serveur distant

Sur le serveur distant :

Création d'une clef SSH

Sur notre serveur principale, nous créons une clef SSH :

ssh-keygen -t rsa -b 16384 -o -a 100
Generating public/private RSA key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff root@host

Il faut ensuite envoyer la clef publique au serveur distant :

scp ~/.ssh/id_rsa.pub abackupuser@backupserver.domaine.eu:/home/abackupuser
abackupuser@backupserver:~$ cat id_rsa.pub >> ~/.ssh/authorized_keys

Si le serveur distant est configuré pour n'accepter que les connexions par clefs, il faudra le faire à la main, puis nous testons notre connexion :

ssh abackupuser@backupserver.domaine.eu
Mise en cache de la clef SSH

Puis nous installons Keychain :

apt-get install keychain

Nous le configurons en ajoutant dans le fichier ~/.bash_profile les lignes suivantes :

.bash_profile
keychain --clear id_rsa
. ~/.keychain/$HOSTNAME-sh

Script de sauvegarde

rbackup
#!/bin/bash
#  rbackup
#  
#  Source originale :
#  http://blog.rom1v.com/2013/08/duplicity-des-backups-incrementaux-chiffres/
#  Source complémentaire
#  https://www.debian-administration.org/article/209/Unattended_Encrypted_Incremental_Network_Backups_Part_1
#  Script modifié par d2air
#  Version 1
#  
BACKUPSERVER="abackupuser@backupserver.domaine.eu:2222"
BACKUP_DIR="$BACKUPSERVER/home/abackupuser/duplicity"
ENCRYPT_KEY="0FFF7777"
FILELIST="/etc/
- /home/user/Downloads
/home/user/
/srv/backups/mysqldump/
/var/lib/mysql/
/var/lib/automysqlbackup/
/var/log/
/var/www/"
# duplicity
unset mode
[ "$1" = full ] && mode=full && printf '(force full backup)\n'
duplicity $mode --encrypt-key "$ENCRYPT_KEY" --include-globbing-filelist <(echo "$FILELIST") --exclude '**' / scp://"$BACKUP_DIR"/
duplicity remove-older-than 2M scp://"$BACKUP_DIR"/ --force

Résolution d'erreurs

Si les scripts de sauvegarde retournent une erreur de ce type :

GPGError: GPG Failed, see log below:
===== Begin GnuPG log =====
gpg: 0xFF0FF055077CC88A: There is no assurance this key belongs to the named user
gpg: [stdin]: encryption failed: unusable public key
===== End GnuPG log =====

Il faudra éditer la clef et lui accorder une confiance ultime avec la commande trust, signer avec sign et sortir de l'invite de commande avec save.

gpg2 --edit-key 0x555CCC000FFF7777
gpg> trust
gpg> sign
gpg> save

Si le script de sauvegarde à distance avec scp retourne une erreur de ce type :

ssh: Exception: Incompatible ssh peer (no acceptable kex algorithm)
ssh: Traceback (most recent call last):
ssh:   File "/usr/lib/python2.7/dist-packages/paramiko/transport.py", line 1612, in run
ssh:     self._handler_table[ptype](self, m)
ssh:   File "/usr/lib/python2.7/dist-packages/paramiko/transport.py", line 1692, in _negotiate_keys
ssh:     self._parse_kex_init(m)
ssh:   File "/usr/lib/python2.7/dist-packages/paramiko/transport.py", line 1807, in _parse_kex_init
ssh:     raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)')
ssh: SSHException: Incompatible ssh peer (no acceptable kex algorithm)

Il faudra mettre à jour paramiko comme indiqué sur cette page.

apt-get install python-pip
pip install paramiko --upgrade

Sauvegarder les bases de données

AutoMySQLBackup

Pour sauvegarder les bases de données, une solution est d'installer AutoMySQLBackup puis d'intégrer son répertoire de sauvegardes, par défaut /var/lib/automysqlbackup/ sous Debian, dans la liste envoyée à la commande duplicity (variable $FILELIST du script de sauvegarde). AutoMySQLBackup est un script shell qui crée une sauvegarde différente tous les jours, toutes les semaines et tous les mois. La configuration par défaut est relativement complète et fonctionne sans aucune modification, cependant vous pourrez la modifier via le fichier /etc/default/automysqlbackup.

MySQLDump

Certains logiciels peuvent nécessiter d'activer une option particulière à l'exportation de la base de données pour permettre de restaurer la sauvegarde, c'est par exemple le cas pour sauvegarder la base de données de Dolibarr. Dans ce cas il faut créer une tâche Cron pour sauvegarder régulièrement les données avec MySQLDump

30 2 * * * mysqldump nombase -h nomserveur -u utilisateur -pvotremotdepasse -l --single-transaction -K --add-drop-table=TRUE --tables -c -e --hex-blob --default-character-set=utf8 | bzip2 > /srv/backups/mysqldump/dolibarr-daily.bz2

Cette technique peut être aussi utiliser pour d'autres logiciels ou comme alternative à AutoMySQLBackup. Par exemple, pour sauvegarder ownCloud, la commande recommandée est :

30 5 * * * mysqldump --lock-tables -h [server] -u [username] -p[password] [db_name]  bzip2 > /srv/backups/mysqldump/ owncloud-sqlbkp-daily.bz2

Automatiser les sauvegardes

Pour démarrer automatiquement une sauvegarde complète le premier jour du mois et une incrémentale tous les autres jours Cron est notre ami, éditons les tâches (crontab) :

crontab -e

Et ajoutons ces lignes :

0 1 1    * * /usr/local/bin/backup full
0 1 2-31 * * /usr/local/bin/backup

La première colonne correspond aux minutes, la deuxième aux heures : le script sera donc exécuté à 1h du matin. La troisième correspond au numéro du jour dans le mois. Les deux suivantes sont le numéro du mois dans l’année et le jour de la semaine. Il peut être préférable d’exécuter le script en priorité basse :

0 1 1    * * nice -15 ionice -c2 /usr/local/bin/backup full
0 1 2-31 * * nice -15 ionice -c2 /usr/local/bin/backup

Copies des sauvegardes

Il ne reste plus qu’à effectuer des copies des fichiers de backups ailleurs.

À partir d’un autre ordinateur

Le plus simple est d’utiliser rsync (sans l’option –delete !) :

rsync -rvP -e "ssh -p 22" --partial-dir=/my/local/tmpbackup --ignore-existing --stats -h server:/srv/backups/duplicity/ /my/local/backup/

–ignore-existing évite de récupérer des modifications malicieuses des sauvegardes sur le serveur (ils ne sont pas censés être modifiés). Du coup, il faut aussi faire attention à sauvegarder les transferts partiels ailleurs (–partial-dir) sans quoi ils ne se termineront jamais. Pour supprimer les anciennes sauvegardes sur cette machine, c’est la même commande que sur le serveur :

duplicity remove-older-than 2M file:///my/local/backup/ --force

Du serveur vers un autre via Cron

Dans la liste des tâches de Cron, avec la commande crontab -e, ajoutons cette ligne :

0 7 * * * rsync -aP -e 'ssh -p 2222' --partial-dir=/tmp/ --ignore-existing /srv/backups/duplicity/ abackupuser@backupserver.domaine.eu:/home/abackupuser/duplicity/serveur1/

Réferences

Les tutoriaux et les pages d'aide qui furent utilisés pour construire cette page :

Commentaires

Si vous avez des commentaires ou vous désirez suggérer des corrections, je vous remercie de me joindre par Twitter.

~~socialite:icon~~