L’utilisation du mode append-only a plusieurs implications que nous estimons nécessaires de détailler ci-dessous.
Quelques éléments de contexte pour comprendre l’environnement dans lequel nous effectuons nos sauvegardes.
BORG_PASSPHRASE
).En date d’août 2024, nous utilisons Borg en version 1 (Borg 2 n’est pas encore en version stable).
La création de sauvegardes régulières nécessite de prendre en compte un revers important : le nettoyage des anciennes sauvegardes. Il n’est pas envisageable d’effectuer ce nettoyage manuellement ; ce processus doit être automatisé.
Or, en utilisant le mode append-only, il n’est naturellement pas possible de supprimer d’anciennes sauvegardes depuis les serveurs (en tout cas, pas avec la même configuration que lors de la création des archives).
Deuxième contrainte importante : supprimer des sauvegardes implique de connaître la phrase de passe pour déclencher l’opération. Notre serveur de sauvegarde ne peut donc pas nettoyer ses propres sauvegardes tout seul car il ne connaît pas la phrase de passe.
Dernière contrainte : la commande borg prune
, qui permet de supprimer les sauvegardes, peut être modifiée de façon à supprimer tout notre historique de sauvegardes (avec un --keep-last 1
, par exemple). Le serveur sur lequel ce paramètre est configuré ne peut donc pas être le serveur d’origine, car il serait possible pour une personne malveillante de modifier cette commande sans avoir accès au serveur de sauvegarde pour supprimer toutes nos sauvegardes.
Nous allons voir comment nous contournons ces contraintes.
En premier lieu, nous suivons le tutoriel de Borg pour mettre en place une sauvegarde append-only.
À l’aide de ssh-keygen
, générez une nouvelle paire de clés SSH dédiée à la création des archives.
Voici notre script de sauvegarde répliqué sur chaque serveur − qui ne peut être lu que par root. Ce script est exécuté plusieurs fois par jour et crée une nouvelle archive sur le dépôt distant.
export BORG_PASSPHRASE='{Votre phrase de passe}'
export BORG_RSH='ssh -i /root/.ssh/{Clé SSH privée pour les sauvegardes}'
# Création du dépôt (à n’exécuter qu’une fois)
# borg init -e repokey-blake2 ssh://{compte distant}@{IP du serveur de sauvegarde}:{port}/{dossier des sauvegardes}
export TARGET="{nom du serveur}"
export DATE=`date +%Y-%m-%d-%H-%M-%S`
# Création d’une nouvelle archive
# Nous excluons les caches et les journaux de connexion (HTTP ou autres protocoles) de nos sauvegardes.
borg create --stats -x ssh://{compte distant}@{IP du serveur de sauvegarde}:{port}/{dossier des sauvegardes}::$TARGET-$DATE \
/var/lib/docker/volumes \
--exclude-caches \
--exclude '/var/lib/docker/volumes/local-syslog/
Ensuite, nous configurons le mode append-only dans .ssh/authorized_keys
sur notre serveur de sauvegarde, pour le compte dédié aux sauvegardes :
from="{IP du serveur}",command="borg serve --append-only --restrict-to-path {dossier des sauvegardes}",restrict ssh-ed25519 {clé publique pour les sauvegardes}
Ensuite, nous allons mettre en place des scripts pour permettre une suppression automatique et régulière de nos sauvegardes. Chaque serveur étant reponsable de la suppression de ses données.
À l’aide de ssh-keygen
, générez une nouvelle paire de clés SSH dédiée au nettoyage des archives.
Le script suivant, accessible uniquement par root, est configuré sur chaque serveur :
export BORG_PASSPHRASE='{Votre phrase de passe}'
ssh -T -i ~/.ssh/{Clé SSH privée pour le nettoyage} {compte distant}@{IP du serveur de sauvegarde} -p{port} $BORG_PASSPHRASE
Ce script s’exécute ponctuellement sur chaque serveur : il établit une connexion SSH et envoie la phrase de passe $BORG_PASSPHRASE
sur notre serveur de sauvegarde.
Du côté de notre serveur de sauvegarde, ajoutons l’entrée suivante dans .ssh/authorized_keys
:
from="{IP du servuer}",command="env BORG_PASSPHRASE=\"$SSH_ORIGINAL_COMMAND\" borg prune --save-space --keep-daily=3 --keep-weekly=3 --keep-last=5 {dossier des sauvegardes} -a '{valeur TARGET}-*' && borg compact {dossier des sauvegardes}",restrict ssh-ed25519 {clé publique pour le nettoyage}
Modifiez les valeurs de --keep-daily
, --keep-weekly
et --keep-last
selon vos contraintes d’espace disque.
borg prune
étant spécifiée sur notre serveur de sauvegardes, il n’est pas possible pour une personne malveillante de les modifier depuis nos autres serveurs.Dans notre situation, l’opération borg prune
est exécutée sur notre serveur de sauvegarde. Bien que notre configuration ne permette pas à notre serveur de sauvegarde de stocker la phrase de passe, elle est tout de même envoyée régulièrement à notre serveur de sauvegarde (à chaque nettoyage), ce qui n’aurait pas lieu si borg prune
était exécutée depuis un autre serveur.
Il est donc possible pour une personne malveillante qui prendrait le contrôle de notre serveur de sauvegarde de modifier .ssh/authorized_keys
(si elle dispose des privilèges suffisants) et d’attendre l’exécution du script de suppression automatique des sauvegardes sur Antigone afin de récupérer la phrase de passe et déchiffrer nos sauvegardes.
Pour contourner ce problème, il serait possible d’exécuter borg prune
sur un serveur tiers, mais ce serveur serait particulièrement sensible car une personne malveillante pourrait supprimer l’intégralité des sauvegardes si elle y gagne l’accès.