====== Sauvegarde avec Duplicity ====== [[http://duplicity.nongnu.org/|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 [[http://duplicity.nongnu.org/|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 ===== [[http://duplicity.nongnu.org/|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 : /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 ==== [[http://duplicity.nongnu.org/|Duplicity]] utilise [[https://fr.wikipedia.org/wiki/GNU_Privacy_Guard|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 [[cryptographie:gnupg|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 = la clef expire dans n jours w = la clef expire dans n semaines m = la clef expire dans n mois 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)  » 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) 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) 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)  » 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 = la clef expire dans n jours w = la clef expire dans n semaines m = la clef expire dans n mois 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) 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 '' ==== 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) 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 [[https://fr.wikipedia.org/wiki/Cron|Cron]], voici un exemple de script à sauvegarder dans ''/usr/local/sbin/''. #!/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 utiliser ''AllowGroups ssh-user'' en ajoutant l'utilisateur à ce groupe. Vous utiliserez ces commandes pour créer le groupe ''groupadd ssh-user'' et pour ajouter ''usermod -a -G ssh-user ''. * 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 : keychain --clear id_rsa . ~/.keychain/$HOSTNAME-sh === Script de sauvegarde === #!/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é [[http://www.randomhacks.co.uk/paramiko-sshexception-incompatible-ssh-peer-no-acceptable-kex-algorithm-ubuntu-14-04/|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 [[http://sourceforge.net/projects/automysqlbackup/|AutoMySQLBackup]] puis d'intégrer son répertoire de sauvegardes, par défaut ''/var/lib/automysqlbackup/'' sous [[https://www.debian.org/|Debian]], dans la liste envoyée à la commande **duplicity** (variable $FILELIST du script de sauvegarde). [[http://sourceforge.net/projects/automysqlbackup/|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 [[https://wiki.dolibarr.org/index.php/Sauvegardes#La_base_de_donn.C3.A9es_2|sauvegarder la base de données de Dolibarr]]. Dans ce cas il faut créer une tâche [[https://fr.wikipedia.org/wiki/Cron|Cron]] pour sauvegarder régulièrement les données avec [[https://mariadb.com/kb/en/mariadb/mysqldump/|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 à [[http://sourceforge.net/projects/automysqlbackup/|AutoMySQLBackup]]. Par exemple, pour [[https://doc.owncloud.org/server/9.0/admin_manual/maintenance/backup.html|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 [[https://fr.wikipedia.org/wiki/Cron|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 : * [[http://blog.rom1v.com/2013/08/duplicity-des-backups-incrementaux-chiffres/|Duplicity : des backups incrémentaux chiffrés]] * [[https://www.debian-administration.org/article/209/Unattended_Encrypted_Incremental_Network_Backups_Part_1|Unattended, Encrypted, Incremental Network Backups]] ===== Commentaires ===== Si vous avez des commentaires ou vous désirez suggérer des corrections, je vous remercie de me joindre par [[https://twitter.com/d2air|Twitter]]. ~~socialite:icon~~