Assurer un backup avec Duplicati et pousser les logs sur IRC (ncat)

duplicati 31 oct. 2021

Il y a autant de solutions de sauvegarde et de notification qu’il existe de geeks. Moi-même j’en utilise plusieurs…

En voici une, pour serveur, basée sur Duplicati (déployé en Docker) auquel j’adjoins un petit script (basé sur ncat) pour assurer un reporting sur un serveur IRC (ouais, je sais, c’est là qu’on voit que je suis né au siècle dernier…).
Les 2 outils que j’utilise sont disponibles pour Linux, Windows, MacOS. Je suppose que maintenant on peut aussi lancer un script BASH (.sh) sous Windows.

Duplicati est un outil gratuit de sauvegarde incrémentale (gain de place et de temps) qui permet de bosser soit en CLI soit en WUI. Et on peut l’installer dur comme en Docker, ce que je privilégie. Notez que les sauvegardes peuvent être en clair ou chiffrées et locales ou distantes. Et à ce niveau c’est plutôt complet : FTP, SSH, WebDAV, rClone, S3, MEGA, Azure, B2, Dropbox, Google, Microsoft…

docker run -d \
--name=duplicati \
--restart always \
-e PUID=0 \
-e PGID=0 \
-e TZ=Europe/Paris \
-p 2:8200 \
-v /home/docker/duplicati:/config \
-v /home/duplicatibackup:/backups \
-v /home/docker/:/source \
ghcr.io/linuxserver/duplicati

Quand on suit la documentation de Linuxserver/Duplicati on voit que la configuration de l’outil est dans /config, que le dossier de sauvegarde locale est dans /backups et que les données à sauvegarder doivent être dans /source. Je monte donc les dossiers du serveur en adéquation avec ça :

Le /config du Docker sera /home/docker/duplicati, /backups sera /home/duplicatibackups et enfin /source sera ce que je veux sauvegarder, à savoir le dossier Docker de mon serveur soit /home/docker


Je vois déjà les remarques… “sauvegarder localement c’est stupide, si le disque casse tu perds tout !”. Beh oui. J’en parlerai pas plus ici mais ce dossier local de sauvegarde peut tout à fait être synchronisé avec des serveurs/PC/clouds distants (FTP, scp, rsync, rClone, Syncthing…). Enfin il peut mais surtout il doit l’être :)

Et l’interface Web sera disponible sur le port 2 => ip_du_serveur:2, protégée par un mot de passe et en HTTP ou HTTPS.
Avec un proxy Nginx devant on aura une belle URL du genre https://duplicati.domaine.com

Comme vous le voyez, ce Duplicati me sert à sauvegarder de la base de données SQL (Nextcloud etc).

J’ai pour habitude (comme tout le monde je suppose) d’exécuter mes sauvegardes en pleine nuit. Déjà pour éviter que ça ne se voit si ça fait ramer la machine ou les outils sauvegardés mais aussi pour avoir un œil sur le résultat le lendemain matin et pouvoir intervenir rapidement en cas de pépin.

La configuration via la WUI est ultra simple, il suffit de lire et cliquer. L’étape la plus compliquée est de taper un mot de passe pour le chiffrement :P

On commence par créer une nouvelle Sauvegarde, la nommer et lui mettre un mot de passe de chiffrement (ou pas).

On lui indique ensuite où sauvegarder les données (pour rappel, dans mon exemple c’est du local)

Comme je suis quelqu’un de ‘achement organisé, que cette tâche de sauvegarde est journalière, je place ça dans /backups/journee. Donc sur le serveur ce sera dans /home/duplicatibackups/journee

Je lui indique ensuite le dossier source, donc le ou les dossiers/fichiers à sauvegarder

Comme je le disais plus haut, ce Duplicati ne me sert qu’à sauvegarder des bases de données SQL. Et c’est le contenu du montage /source de Docker, configuré lors de l’installation.

On précise ensuite la fréquence de sauvegarde. Pas le type, avec Duplicati c’est toujours de l’incrémentale.

Et ça se termine avec le nombre de sauvegardes à conserver. Je veux un backup de 7 jours roulants.
La 1ère sauvegarde seront donc complète (perso ça fait dans les 7 Go) et ensuite, chaque jour à 5h, ça vient ajouter/retirer ce qui aura changé depuis la veille entre la précédente sauvegarde et la /source. C’est de la sauvegarde incrémentale.
Donc certains jours la sauvegarde peut faire 30Mo comme 2Go, selon ce qui aura changé. Enfin vu que c’est de la base de données dans cet exemple ça ne bouge pas énormément. Ce serait plus flagrant avec des documents professionnels type tableurs, PDF, images, emails.

La taille du volume distant est assez mal traduit en français… C’est pas du tout la taille maximale de l’espace de stockage ni de la sauvegarde, c’est plutôt pour indiquer à Duplicati quelle taille de fichier maximale il peut envoyer (dans le cas d’une sauvegarde distante, donc par Internet).
Avec la fibre osef mais avec l’ADSL ça peut avoir son importance de lui faire répartir la sauvegarde en petits fichiers de 200Mo par exemple.

Duplicati est pouvu d’options de reporting par Email et XMPP. Mais je le voulais avec d’autres reports personnels sur mon IRC.

Pour ça j’utilise ncat (sudo apt install ncat en général sinon voir ici). Il permet de communiquer en TCP notamment. Et donc, par extension, de se connecter à un serveur IRC.

J’utilise aussi duplicati_client, un outil Python qui permet de récupérer les logs Duplicati. Pour l’installer suivre les recommandations. Il faudra ensuite créer un fichier de paramètres avec votre mot de passe Duplicati (celui d’accès à la WUI) :

nano ~/.config/duplicati-client/parameters.yml
et y mettre votre mot de passe comme ceci :

password: jesuisunmotdepasse

Le 1er script permet de récupérer les logs d’erreur : nano duplicatiquotidienerreur.sh (ne pas oublier chmod a+x sur le script pour le rendre exécutable)

#!/bin/bash

USER=moi/perso
PASSWORD='mot de passe'
IRC_SERVER=123.456.789.10
IRC_PORT=6697
CHANNEL=#reportings

# Mot de passe Duplicati
python3 /home/scripts/duplicati-client/duplicati_client.py params ~/.config/duplicati-client/parameters.yml;

# Recuperation du log
python3 /home/scripts/duplicati-client/duplicati_client.py logs --id 1 error > /home/scripts/outerror1.log;

(
echo NICK $USER
echo USER $USER 8 * : $USER
sleep 3
echo PASS $USER:$MYPASSWORD
echo "JOIN $CHANNEL"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" "ERREUR de backup incrémental QUOTIDIEN"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" `cat /home/scripts/outerror1.log`
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo QUIT
) | ncat $IRC_SERVER $IRC_PORT

Quelques explications

USER=moi/perso
Je me connecte via mon bouncer IRC (ZNC) d'où le user/serveur, si vous vous connectez en directement seul un nom d'utilisateur suffit

MYPASSWORD='mot de passe'
Mot de passe de votre user IRC ou, dans mon cas, de mon user ZNC

IRC_SERVER=123.456.789.10
IP du serveur IRC, ici celle de mon ZNC

IRC_PORT=6697
Port du servuer IRC, ici de mon relais ZNC

CHANNEL=#reportings
Le canal IRC sur lequel je veux le rapport


# Mot de passe Duplicati
python3 /home/scripts/duplicati-client/duplicati_client.py params ~/.config/duplicati-client/parameters.yml;
Ici je me sers de l'outil Python pour récupérer les logs de Duplicati. Mais avant tout il faut lui donner l'accès et donc le mot de passe grâce au fichier créé précédemment

# Recuperation du log
python3 /home/scripts/duplicati-client/duplicati_client.py logs --id 1 error > /home/scripts/outerror1.log;
Je lui demande ensuite d'exporter les logs d'erreur (error) de la sauvegarde (id 1 si c'est la seule, sinon son numéro) vers le fichier /home/scripts/outerror1.log

Et c'est ce contenu que j'envoie vers IRC en guise de rapport d'erreur :
echo "PRIVMSG $CHANNEL" `cat /home/scripts/outerror1.log`

Ce qui donne (y’a pas d’erreur là, heureusement…)

Et pour le résultat du backup quotidien c’est le même principe

#!/bin/bash

USER=moi/perso
PASSWORD='mot de passe'
IRC_SERVER=123.456.789.10
IRC_PORT=6697
CHANNEL=#reportings

# Mot de passe Duplicati
python3 /home/scripts/duplicati-client/duplicati_client.py params ~/.config/duplicati-client/parameters.yml;

# Recuperation du log
python3 /home/scripts/duplicati-client/duplicati_client.py logs --id 1 information > /home/scripts/out1.log;

# grep le contenu utile
grep 'Get -\|Message:\|Error' /home/scripts/out1.log | tail -n 10 > /home/scripts/out2.log;

(
echo NICK $USER
echo USER $USER 8 * : $USER
sleep 3
echo PASS $USER:$MYPASSWORD
echo "JOIN $CHANNEL"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" "RAPPORT de backup incrémental QUOTIDIEN"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" `cat /home/scripts/out2.log`
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo "PRIVMSG $CHANNEL" "---------------------------------------------------------------------"
echo QUIT
) | ncat $IRC_SERVER $IRC_PORT

Quelques explications

# Recuperation du log
python3 /home/scripts/duplicati-client/duplicati_client.py logs --id 1 information > /home/scripts/out1.log;
Je lui demande d'exporter les logs (information) de la sauvegarde (id 1 si c'est la seule, sinon son numéro) vers le fichier /home/scripts/out1.log

# grep le contenu utile
grep 'Get -\|Message:\|Error' /home/scripts/out1.log | tail -n 10 > /home/scripts/out2.log;
Là je sélectionne et exporte uniquement la partie des logs qui m'intéresse, à savoir celle concernant les Messages

Et c'est ce contenu que j'envoie vers IRC en guise de rapport :
echo "PRIVMSG $CHANNEL" `cat /home/scripts/out2.log`

Il suffit enfin de les placer en cron pour qu’ils s’exécutent et passent les rapports sur IRC le matin, chez moi à 8h et 8h05.

# Rapports Duplicati
0 8 * * * /bin/bash /home/scripts/rapportsduplicati/duplicatiquotidien.sh
05 8 * * * /bin/bash /home/scripts/rapportsduplicati/duplicatiquotidienerreur.sh

Mots clés