2 Configuration de Borg
neil edited this page 1 month ago

Borg Backup est un utilitaire de sauvegarde de données que nous utilisons pour tous les services de La Contre-Voie.

Un script utilisant Borg est exécuté sur notre serveur de stockage (Antigone) pour envoyer toutes les trois heures une archive de nos données vers un VPS qui nous est offert gracieusement par Picasoft.

Borg supporte la création d’archives chiffrées, dédupliquées et compressées. Nous utilisons également le mode append-only qui permet d’éviter la suppression de nos backups depuis nos serveurs de production si une entité malveillante réussit à prendre le contrôle de notre infrastructure.

L’utilisation de ce mode append-only va être présenté en détail sur cette page.

Stratégie de sécurité

Quelques éléments de contexte pour comprendre l’environnement dans lequel nous effectuons nos sauvegardes.

  • Nous ne sauvegardons que les données présentes sur notre serveur de stockage, Antigone.
    • Les quelques données présentes sur notre serveur principal (Balearica) qui nécessitent d’être conservées sont régulièrement synchronisées sur notre serveur de stockage.
  • Notre dépôt Borg, chiffré, est situé sur notre VPS chez Picasoft.
  • Notre dépôt Borg est de type repokey : cela signifie que la clé permettant de déchiffrer les sauvegardes est présente sur le dépôt, mais elle est elle-même chiffrée par une phrase de passe (BORG_PASSPHRASE).
  • Notre phrase de passe est conservée par Antigone.
  • Notre VPS de sauvegarde ne peut en aucun cas conserver la phrase de passe : s’il est compromis, il n’est pas possible de déchiffrer nos sauvegardes à partir des informations présentes sur le disque.
  • La création d’une nouvelle sauvegarde est déclenchée par une cron (toutes les trois heures environ) depuis Antigone. Les archives sont poussées sur notre serveur de stockage.
  • Pour limiter autant que possible la surface d’exposition de ce dispositif de sauvegarde, nous ne souhaitons pas impliquer de serveurs tiers dans ce processus. Nous n’utilisons donc que deux serveurs dans ce cas d’usage : Antigone et notre serveur de sauvegarde.

À l’heure où j’écris ces lignes, nous utilisons Borg en version 1 (Borg 2 n’est pas encore stable).

Contraintes

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 Antigone.

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 cette commande se déclenche ne peut donc pas être Antigone, 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.

Configuration du mode append-only

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 depuis Antigone dédiée à la création des archives.

Sur Antigone, voici notre script de sauvegarde − 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://{utilisateur·ice distant·e}@{IP du serveur de sauvegarde}:{port}/{dossier des sauvegardes}

export TARGET="antigone"
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://{utilisateur·ice distant·e}@{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 :

from="{IP d’Antigone}",command="borg serve --append-only --restrict-to-path {dossier des sauvegardes}",restrict ssh-ed25519 {clé publique pour les sauvegardes}

Configuration de la suppression automatique des sauvegardes

Ensuite, nous allons mettre en place des scripts pour permettre une suppression automatique et régulière de nos sauvegardes.

À l’aide de ssh-keygen, générez une nouvelle paire de clés SSH depuis Antigone dédiée au nettoyage des archives.

Sur Antigone :

export BORG_PASSPHRASE='{Votre phrase de passe}'

ssh -T -i ~/.ssh/{Clé SSH privée pour le nettoyage} {utilisateur·ice distant·e}@{IP du serveur de sauvegarde} -p{port} $BORG_PASSPHRASE

Ce script s’exécute ponctuellement sur Antigone : 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 d’Antigone}",command="env BORG_PASSPHRASE=\"$SSH_ORIGINAL_COMMAND\" borg prune --save-space --keep-daily=3 --keep-weekly=3 --keep-last=10 {dossier des sauvegardes} && 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.

  • La clé SSH utilisée pour le nettoyage n’est pas soumise au mode append-only, contrairement à celle utilisée pour la création des archives.
  • La configuration des paramètres de borg prune étant spécifiée sur notre serveur de sauvegarde, il n’est pas possible pour une personne malveillante de les modifier depuis Antigone.
  • Le serveur de sauvegarde ne conserve pas sur son disque la clé de chiffrement utilisée pour le nettoyage des sauvegardes.

Limites et pistes d’amélioration

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.