Sauvegarde distante avec duplicity

Suite à la migration de la majorité de mon nuage de services vers mon réseau en passant à l’auto-hébergement, la question de la sauvegarde des données est devenue cruciale. Côté cahier des charges, les principaux critères retenus étaient les suivants :

  • Sauvegarde externe géographiquement
  • Automatique
  • Chiffrée

Après de nombreuses recherches, j’ai décidé d’utiliser duplicity pour réaliser la sauvegarde et le service hubiC d’OVH pour le stockage des données sauvegardées. Voici donc la procédure utilisée pour mettre en place une sauvegarde incrémentale quotidienne, avec sauvegarde complète à intervalle régulier.

Pour commencer, il convient d’installer les composants nécessaires:

sudo aptitude install duplicity python-pip python-dev gcc
sudo pip2 install pyrax

Ayant décidé d’envoyer les sauvegardes dans mon espace hubiC, et afin de permettre à duplicity de communiquer avec hubiC, il faut au préalable autoriser l’application dans l’interface web du service. On va donc créer une nouvelle application, renseigner un nom, duplicity par exemple, et un domaine de redirection valant http://localhost/. On note ensuite les paramètres « Client ID » et « Client secret » qui serviront pour paramétrer la connexion à hubiC sur la machine source.

Le paramétrage s’effectue dans le fichier ~/.hubic_credentials :

[hubic]
email = your_email
password = your_password
client_id = api_client_id
client_secret = api_secret_key
redirect_uri = http://localhost/

On limite ensuite les droits liés au fichier:

chown 600 ~/.hubic_credentials

A ce stade, on peut faire un premier test afin de valider la configuration, par exemple, sauvegarder le répertoire test dans le conteneur test qui sera accessible à l’adresse suivante: https://hubic.com/home/browser/#test.

duplicity test cf+hubic://test

Pour lister le contenu du répertoire distant, la commande dédiée est:

duplicity list-current-files cf+hubic://test

Pour la gestion des opérations de sauvegarde, j’utilise un petit script sh, adaptation de celui de David Mercereau:

#!/bin/bash

###################################
## Backup sur HubiC avec duplicity
# Script sous licence BEERWARE
# Version 0.5.0 11/2017
# Adapté de :
# http://david.mercereau.info/backup-chiffre-avec-duplicity-sur-hubic
###################################

set -eu

##### Paramètres

# Nom du dépôt
CONTAINER="monContaineur"
# Liste à sauvegarder (voir le man duplicity avec le filelist)
DUPLICITYFILELIST="/chemin/vers/backup.filelist"
# Passphrase pour le chiffrement
PASSPHRASE="maSuperPassphrase"
# Fréquence des sauvegardes complètes
FULLIFOLDERTHAN="1W"
# Rétention des sauvegardes
RETENTION="1M"
# Log d'erreur
LOGERROR="/chemin/vers/fichierDeLog.log"
# Bin de duplicity
DUPLICITY_BIN="/usr/bin/duplicity"
# Email pour les erreurs (0 pour désactiver)
EMAIL="monMail@domaine.extension"
# Envoyer un rapport par email sur l'état des backup
RAPPORT=0
# Log d'erreur
exec 2> ${LOGERROR}

##### Début du script

function cleanup {
 echo "exit..."
 unset PASSPHRASE
 grep -v "has been deprecated" ${LOGERROR} > ${LOGERROR}.tmp
 mv ${LOGERROR}.tmp ${LOGERROR}
 if [ "`stat --format %s ${LOGERROR}`" != "0" ] && [ "$EMAIL" != "0" ] ; then
 cat ${LOGERROR} | mail -s "$0 - Error" ${EMAIL}
 fi
}
trap cleanup EXIT

# Gentil avec le système
ionice -c3 -p$ &>/dev/null
renice -n 19 -p $ &>/dev/null

if ! [ -f ${DUPLICITYFILELIST} ] ; then
 echo "Aucun fichier filelist : ${DUPLICITYFILELIST}"
 exit 1
fi

export PASSPHRASE

# Backup
${DUPLICITY_BIN} --full-if-older-than ${FULLIFOLDERTHAN} / cf+hubic://${CONTAINER} --include-filelist ${DUPLICITYFILELIST} --exclude '**'

# Suppression des vieux backups
${DUPLICITY_BIN} remove-older-than ${RETENTION} cf+hubic://${CONTAINER} --force

# Rapport sur le backup
if [ "$RAPPORT" != "0" ] && [ "$EMAIL" != "0" ] ; then
 ${DUPLICITY_BIN} collection-status cf+hubic://${CONTAINER} | mailq -s "$0 - collection-status" ${EMAIL}
fi

unset PASSPHRASE

exit 0

On n’oublie pas d’adapter les paramètres et de rendre le script exécutable:

chmod u+x backup-to-hubic.sh

On ajoute également un fichier backup.filelist qui contient l’ensemble des chemins des dossiers à sauvegarder. Le fichier est de la forme:

/var/backups/mysql
- /var/www/mon-site/dossier-a-ignorer/cache
/var/www/mon-site

L’état de la sauvegarde peut être vérifié avec la commande:

duplicity collection-status cf+hubic://test

Afin d’exécuter le script à intervalles régulier, on ajoute une ligne au cron (crontab -e):

0 0 * * * /chemin/vers/backup-to-hubic.sh

A ce stade, les différents dossiers listés sont sauvegardés vers hubiC de manière incrémentale et chiffrée. Des sauvegardes complètes sont effectuées périodiquement et nettoyées automatiquement à l’issue de la durée de conservation configurée. Par ailleurs, on n’oubliera pas de sauvegarder la passphrase utilisée pour chiffrer les données dans un gestionnaire de mots de passe, afin d’être en mesure de reconfigurer duplicity sur une autre machine et de récupérer les fichiers en cas de crash complet de la machine source (ce que je ne souhaite à personne).

Pour finir voici la liste des articles utilisés pour implémenter cette solution de sauvegarde:

Anonyme

Auteur/autrice : Victor

Ingénieur en informatique de formation et de métier, j’administre ce serveur et son domaine et privilégie l'utilisation de logiciels libres au quotidien. Je construis progressivement mon "cloud" personnel service après service pour conserver un certain contrôle sur mes données numériques.

13 réflexions sur « Sauvegarde distante avec duplicity »

  1. Bonjour,
    J’utilisais Duplicati mais c’est un logiciel fait à la base pour Windows et donc c’est pas mal de bidouille avec Mono…
    Du coup je suis bien intéressé par ton tuto.
    J’ai quelques question avant de m’y mettre :
    -Comment se passe la récupération d’un fichier ou de l’ensemble des fichiers?
    -Peut-on mettre une interface web pour cherche les fichiers et la vérification du bon déroulement des sauvegarde?
    Merci
    Yannick

    1. Bonjour Yannick,

      Pour la restauration, j’utilise l’instruction restore de duplicity de la manière suivante :
      duplicity restore --force --file-to-restore source/dossier -t now cf+hubic://test /destination/dossier
      De cette manière, je récupère le contenu sauvegardé de source/dossier et le restaure à l’emplacement destination/dossier, en utilisant la version la plus récente (-t now) et en écrasant un éventuel contenu existant (–force).

      Pour restaurer l’ensemble des fichiers, la commande devrait être de la forme (à tester et adapter) :
      duplicity --force cf+hubic://test /dossier/de/destination

      Du côté interface, il existe DejaDup chez Gnome. Ne l’ayant jamais testé, je ne peux en revanche pas me prononcer sur les fonctionnalités disponibles.

  2. Bonjour Victor,
    J’ai suivi ton tuto et cela fonctionne super quand je lance le bash. En fait je sauvegarde 100Go donc ça fait pas mal de fichiers à 200Mo mais bon je ne sais pas si c’est gênant.
    Par contre le cron n’a pas l’air de marcher du tout.
    Le log du cron me dit :
    Dec 17 07:00:01 heolya CRON[20431]: (root) CMD (/etc/cron.weekly/backup-to-hubic.sh)
    Dec 17 07:00:01 heolya CRON[20423]: (CRON) info (No MTA installed, discarding output)
    mais ça dure 1sec et ça fait rien.
    Sais-tu ou je peux chercher pour savoir ce qui ne va pas?
    Bonne soirée
    Yannick

    1. Alors non, il ne fait pas rien… il me crée un dossier « test » dans Hubic alors que la même commande lancée en console sauvegarde dans un dossier « sauvegarde » sur hubic…. je ne comprends rien !

      1. Bonjour Yannick,
        Difficile de te donner une réponse, néanmoins, il faut peut-être creuser du côté du user qui exécute le script.
        Les logs indiquent que c’est root, donc, si éventuellement tu as un chemin relatif vers le répertoire personnel de l’utilisateur, de la forme « ~/ », le contenu sauvegardé ne sera pas le même.
        Autrement, je jetterais aussi un œil du côté des variables d’environnements, toujours en cas d’exécution avec un utilisateur différent entre la console et le cron.

  3. Bonjour Victor,
    Je crois en effet que cela vient d’un problème de droit (root et sudo ce n’est pas pareil). J’avais un peu laissé tombé. Du coup j’ai un problème dès le départ, cette fois ci :
    ubuntuadmin@heolya:~$ duplicity test cf+hubic://test
    Connection failed, please check your credentials: ParsingError File contains parsing errors: /home/ubuntuadmin/.hubic_credentials
    [line 2]: ‘ email = XXXXX@gmail.com\n’
    [line 3]: ‘ password = je=,XXXXXXXXXnlC?~\n’
    [line 4]: ‘ client_id = api_hubic_hd8viHGlBJWXXXXXXXXXXXACeUxF9\n’
    [line 5]: ‘ client_secret = oAvNUPNFLuyRfzdXXXXXJ6puF0BH7OtOfg99U6pnX1Od5RnFRCdcKYNLjFl\n’
    [line 6]: ‘ redirect_uri = http://localhost/\n’
    Je ne sais pas trop ou chercher. J’ai bien fait attention de tout copier. Re créer une application Hubic. Mais rien n’y fait…
    Peux-tu m’aider?
    Merci d’avance.
    Yannick

  4. Re-.
    J’ai essayé avec une debian toute fraiche sur un raspberry et j’ai la même erreur :
    root@jeedom:/home/jeedomadmin# duplicity test cf+hubic://test
    Connection failed, please check your credentials: ParsingError File contains parsing errors: /root/.hubic_credentials
    [line 2]: ‘ email = xxxxxxxx@gmail.com\n’
    [line 3]: ‘ password = Yxxxxxxxxxxxx/;P#0M?bTpQ\n’
    [line 4]: ‘ client_id = api_hubic_36NgaS1jyLxxxxxxxxxxxxxCpNlmqpx\n’
    [line 5]: ‘ client_secret = gaXRPyFZv3jrJJj6gM0Nf89L7zp7TTyliNxxxxxxxxxxxxxxxxiDdYB17z3rtDS\n’
    [line 6]: ‘ redirect_uri = http://localhost/\n’

    Je suis désolé je ne comprends vraiment pas….
    Merci d’avance pour ton aide.
    Bonne journée

  5. Bonjour Yannick,

    J’ai réussi à reproduire le problème sur mon serveur. Il faut enlever tous les espaces en début de ligne du fichier .hubic_credentials . J’ai mis le contenu de l’article à jour.

  6. Chouette ! Merci beaucoup, je pense que j’aurais pu m’arracher les cheveux un moment avec de trouver.
    Bonne soirée et encore merci

  7. Bonjour. En ces temps étrange je me remets à essayer de sauvegarder en ligne. J’avais abandonné parce que le test me renvoyait de nouveau : « Connection failed, please check your credentials: AuthenticationFailed Unable to get oauth access token, wrong client_id or client_secret ? »
    J’avoue de que je comprends rien. Je pensais que Hubic etait HS mais cela fonctionne avec d’autres applications.
    J’ai bien supprimer les espaces :
    [hubic]
    email = hXXX.y@gmail.com
    password = VGR0XXXXXXXXXXXk2zKnP
    client_id = api_hubic_NGiv8MvTJ0XXXXXXXXXXXXXXXaNpv
    client_secret = yrU6WcHiiTYHnxqO3HwVEG3O1XXXXXXXXXXXXXXXXXXXXOTiChtf1h4Q
    redirect_uri = http://localhost/

    Pouvez vous m’aider?
    Merci
    Yannick

    1. Bonjour Yannick.
      Je viens de comparer avec mon propre fichier de configuration et je ne vois rien de différent.
      A en croire le message d’erreur, le problème est à chercher du côté du client_id ou du client_secret.
      De ce côté là, vérifier les valeurs avec celles disponibles dans les interfaces hubic et dans un second temps, essayer en générant un nouveau client_id.
      J’ai également regardé dans le code source de la partie hubic de duplicity, l’erreur que vous mentionnez correspond à une erreur sur la requête d’authentification adressée à l’API hubic, donc vérifier en priorité les paramètres d’authentification.

      Bonne recherche.

  8. Bonjour Victor,
    J’ai fait une VM Ubuntu 18.04 toute propre et ça fonctionne. Zut alors, je suis pas assez bon pour investiguer.
    Peut-être une signe pour remettre à plat mon serveur! Tu n’utilise pas Proxmox par hasard?
    Bonne journée

Répondre à Victor Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *