Aller au contenu

Sauvegardes du réseau (restic)

Le module darkone.service.restic sauvegarde les hôtes du parc avec restic 🡕 : chaque hôte (client) pousse ses données vers un dépôt, local ou distant via un serveur REST de zone.

Deux rôles, un seul module :

  • Serveur REST : un hôte qui déclare le service restic dans config.yaml. Il stocke les dépôts de tous les hôtes et écoute sur le réseau interne.
  • Client : tout hôte avec enable = true qui déclare des targets (destinations de sauvegarde).
Diagram

Disposition d’un dépôt, par catégorie :

<racine>/<hôte>/system # catégorie "system" (/ moins les exclusions)
<racine>/<hôte>/srv/nfs # catégorie "nfs" (/srv/nfs/<...>)
<racine>/<hôte>/srv/medias # catégorie "medias" (/srv/medias/<...>)
  1. Dans etc/config.yaml, ajouter le service restic à l’hôte serveur :

    services:
    restic:
  2. Brancher le disque de sauvegarde et le monter sur /mnt/backup dans la configuration de l’hôte (usr/machines/<hôte>/), avec l’option nofail :

    fileSystems."/mnt/backup" = {
    device = "/dev/disk/by-uuid/<uuid>";
    fsType = "ext4";
    options = [ "nofail" ];
    };
    # Le serveur REST ne démarre qu'une fois le disque monté.
    systemd.services.restic-rest-server = {
    requires = [ "mnt-backup.mount" ];
    after = [ "mnt-backup.mount" ];
    };
  3. Le dépôt est stocké sous serverDataDir (défaut /mnt/backup/restic). Le pare-feu ouvre le port REST sur l’interface interne automatiquement.

Déclarer une ou plusieurs targets dans la configuration de l’hôte :

darkone.service.restic = {
enable = true;
targets = [
{
# Dépôt distant via le serveur REST de la zone.
root = "rest:http://restic.zone.domain.tld:8888";
zone = "ag";
categories = [ "system" "nfs" ];
}
];
};

Champs d’un target :

ChampRôle
nameIdentifiant (défaut main), suffixe des jobs/units.
rootChemin local ou URL rest://.
zoneZone qui choisit la passphrase restic-password-<zone>.
categoriesDonnées sauvegardées : system, nfs, medias.

Une recette idempotente crée les secrets manquants (jamais d’écrasement) :

Fenêtre de terminal
just passwd-restic

Elle génère, dans usr/secrets/secrets.yaml :

  • une passphrase restic-password-<zone> par zone ;
  • un credential restic/<hôte>/rest-password par hôte du parc.

Par défaut, le serveur accepte que tout hôte authentifié accède à n’importe quel dépôt. L’option enableServerPrivateRepos impose que chaque hôte n’accède qu’à son propre dépôt (préfixe = nom d’hôte). À activer en deux temps pour éviter toute coupure :

  1. Déployer tout le parc avec les credentials par hôte (clients + serveurs), enableServerPrivateRepos = false. Vérifier que les sauvegardes passent.
  2. Passer enableServerPrivateRepos = true et redéployer les serveurs.

Sur l’hôte concerné, les secrets sont déjà en place. Lister puis restaurer :

Fenêtre de terminal
# Variables d'accès REST (générées par sops) et passphrase de dépôt.
set -a; . /run/secrets/rendered/restic-rest-env; set +a
export RESTIC_PASSWORD_FILE=/run/secrets/restic-password-ag
export RESTIC_REPOSITORY=rest:http://restic.zone.domain.tld:8888/$(hostname)/system
restic snapshots
restic restore latest --target /restore
  1. Sur un serveur, un compte par hôte du parc dans le fichier htpasswd :

    Fenêtre de terminal
    sudo cut -d: -f1 /run/restic-rest/htpasswd
  2. Sur un client, lancer une sauvegarde à la demande :

    Fenêtre de terminal
    systemctl start restic-backups-system-main.service
    journalctl -u restic-backups-system-main.service -e
  3. Isolation (si enableServerPrivateRepos = true) : l’accès au dépôt d’un autre hôte doit être refusé (erreur 401/403).