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 :
- duplicity full (force une sauvegarde complète)
- duplicity incr (force une sauvegarde incrémentale, échoue si aucune complète n’est trouvée)
- duplicity (effectue une sauvegarde incrémentale si possible, complète sinon)
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 :
- soit un chiffrement asymétrique (une paire de clés publique/privée, la clé privée pouvant elle-même être chiffrée par une passphrase)
- soit un chiffrement symétrique (une simple passphrase).
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 :
- un utilisateur doit exister ou être créer pour accueillir les données (commande adduser), il est recommandé de créer un utilisateur spécifique pour la gestion des sauvegardes et de ne pas utiliser root,
- cet utilisateur doit pouvoir se connecter avec ssh, pour ce faire la directive
AllowUsers
du fichier de configuration/etc/ssh/sshd_config
doit avoir son nom en paramètre (AllowUsers user
) ou mieux utiliserAllowGroups ssh-user
en ajoutant l'utilisateur à ce groupe. Vous utiliserez ces commandes pour créer le groupegroupadd ssh-user
et pour ajouterusermod -a -G ssh-user <username>
. - si le serveur possède un firewall, il faudra le configurer pour qu'il accepte la connexion ssh depuis notre serveur principale
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~~