Aller au contenu

Backup Systemd Authority

Objet

Cette page décrit l'autorité canonique CURRENT pour les sauvegardes CMonChoix pilotées par systemd. La fondation a été introduite en P0.6 puis étendue et certifiée live jusqu'à P1.4B2B.

L'objectif est de rendre l'installation des helpers de sauvegarde et des unités systemd versionnée, atomique, idempotente et fail-closed, sans modifier les secrets ni déclencher un job de sauvegarde pendant l'installation.

Historique : P0.6 était une étape Git/off-live et la première bascule live contrôlée appartenait à P0.9. Ces jalons restent utiles comme provenance, mais ils ne décrivent plus le CURRENT.

État CURRENT certifié au 5 septembre 2026 :

P1.4B2B_TARGET_SHA=c1b2f6a356f23c1ace064a2a7e4f71c33ffb584e
P1.4B2B_SYSTEMD_ARTIFACTS=13_OF_13_B2B
P1.4B2B_LIVE=CLOSED_PASS
P1_4=CLOSED_PASS

Les 13 artefacts live ont été observés byte-identiques à l'autorité Git P1.4B2B. Les deux timers sont enabled + active et systemd-analyze verify a réussi.

Autorité des 13 artefacts

Le manifeste canonique est :

ops/systemd/backup-systemd-artifacts.manifest

Il doit contenir exactement 13 entrées :

Helpers

  1. scripts/backup-create.sh
  2. scripts/backup-critical-state-restic.sh
  3. scripts/backup-offsite-daily.sh
  4. scripts/backup-offsite-maintenance.sh
  5. scripts/backup-offsite-restic.sh
  6. scripts/backup-restore-check.sh
  7. scripts/backup-verify.sh
  8. scripts/backup-alert-notify.sh

Les helpers sont installés dans :

/usr/local/libexec/cmonchoix-backup/

Mode attendu : 0755.

Unités systemd

  1. ops/systemd/ccx-backup-alert-notify@.service
  2. ops/systemd/ccx-offsite-backup.service
  3. ops/systemd/ccx-offsite-backup.timer
  4. ops/systemd/ccx-offsite-maintenance.service
  5. ops/systemd/ccx-offsite-maintenance.timer

Les unités sont installées dans :

/etc/systemd/system/

Mode attendu : 0644.

Aucun artefact supplémentaire ne peut être ajouté silencieusement au manifeste : l'installateur et les tests exigent exactement 8 helpers et 5 unités.

Secrets et configuration

Le fichier de configuration live est :

/etc/cmonchoix/offsite-backup.env

Il n'est pas l'un des 13 artefacts installés et ne doit jamais être copié depuis Git.

L'installateur exige notamment :

  • un fichier régulier ;
  • aucun lien symbolique ;
  • mode 0600 ;
  • propriétaire attendu ;
  • conservation exacte de son contenu, de son mode et de son propriétaire pendant l'installation.

Le dépôt ne contient qu'un exemple non secret :

ops/systemd/offsite-backup.env.example

Autorité de release

L'installation est autorisée uniquement depuis une release Git explicitement identifiée.

scripts/backup-systemd-install.sh exige :

  • CCX_TARGET_SHA au format SHA Git complet ;
  • un HEAD exactement égal à CCX_TARGET_SHA ;
  • une worktree propre ;
  • un manifeste suivi par Git ;
  • les 13 sources suivies par Git ;
  • aucune source ou racine critique sous forme de lien symbolique.

L'installateur utilise une exception safe.directory limitée à la worktree fournie. Il ne modifie pas la configuration Git globale ou système.

Transaction d'installation

Avant toute substitution, l'installateur :

  1. valide l'autorité Git et le manifeste ;
  2. valide le contrat du fichier d'environnement ;
  3. vérifie la syntaxe des helpers ;
  4. capture l'état is-enabled et is-active des deux timers ;
  5. sauvegarde les octets et métadonnées des cibles existantes dans son répertoire d'état.

Chaque fichier est préparé dans un staging situé dans le répertoire de destination, puis substitué par renommage local. Cette stratégie évite une copie partiellement visible sur la cible.

Les unités sources sont vérifiées avec systemd-analyze verify avant installation. Les unités installées sont vérifiées une seconde fois avant daemon-reload.

systemctl daemon-reload n'est exécuté que si une unité a réellement changé.

Aucun déclenchement de service

L'installateur ne doit jamais appeler :

  • systemctl start ;
  • systemctl stop ;
  • systemctl restart ;
  • systemctl enable ;
  • systemctl disable ;
  • systemctl mask ;
  • systemctl unmask.

Les états enabled/active des deux timers doivent être identiques avant et après l'installation.

L'installation de l'autorité ne doit donc pas provoquer un backup, une maintenance ou un changement de planification.

Rollback fail-closed

Après armement de la transaction, tout échec provoque un rollback des cibles déjà traitées.

Le rollback restaure les fichiers précédents en ordre inverse et exécute un daemon-reload de récupération.

Une exécution ayant rollbacké doit rester en erreur et ne peut jamais produire le marqueur :

CCX_BACKUP_SYSTEMD_INSTALL_STATUS=PASS

Le marqueur de certification P0.6 :

CCX_BACKUP_SYSTEMD_INSTALLER_CERTIFIED=PASS

n'est jamais émis par l'installateur lui-même. Il appartient uniquement à la procédure de certification globale après validation indépendante.

Idempotence

Si les 13 destinations contiennent déjà exactement les bons octets, modes et propriétaires :

  • aucune cible n'est remplacée ;
  • aucun daemon-reload inutile n'est requis ;
  • l'exécution retourne CCX_BACKUP_SYSTEMD_INSTALL_CHANGED=0.

Un premier changement valide retourne CCX_BACKUP_SYSTEMD_INSTALL_CHANGED=1.

Contrats de sauvegarde préservés

L'autorité P0.6 conserve les comportements déjà certifiés :

  • lock partagé entre backup quotidien et maintenance ;
  • backup applicatif avant push offsite ;
  • snapshot Restic du critical state ;
  • dépôt Restic distant obligatoire ;
  • mot de passe Restic fourni par fichier et non par variable contenant le secret ;
  • maintenance dans l'ordre RESTIC PRE-CHECK -> RETENTION -> RESTIC POST-CHECK ;
  • aucun restic init automatique ;
  • safe.directory limité à la worktree de la plateforme.

Notification des échecs backup / maintenance

Les unités ccx-offsite-backup.service et ccx-offsite-maintenance.service utilisent :

OnFailure=ccx-backup-alert-notify@%n.service

L'unité template appelle scripts/backup-alert-notify.sh, qui publie uniquement vers l'API Alertmanager locale :

http://127.0.0.1:9093/api/v2/alerts

Le helper n'utilise ni webhook Discord, ni secret, ni URL externe. Le secret Discord reste exclusivement dans l'autorité Alertmanager hors Git.

Après une exécution réussie, ExecStartPost=-... résout l'alerte correspondant à l'unité. Le préfixe - est obligatoire : une indisponibilité du chemin de notification ne doit jamais convertir une sauvegarde réussie en échec.

Alertmanager ne doit être publié sur l'hôte qu'en loopback 127.0.0.1:9093; aucune écoute publique sur 0.0.0.0:9093 n'est autorisée.

Planification canonique

Backup quotidien :

01:30 UTC, Persistent=true.

Maintenance :

dimanche 00:30 UTC, Persistent=true.

Tests off-live

La CI dédiée est :

.github/workflows/backup-systemd-authority.yml

Elle contrôle :

  • le manifeste exact 13/8/5 ;
  • la syntaxe shell ;
  • le smoke historique des scripts de backup ;
  • le smoke de l'orchestration offsite ;
  • le smoke Restic ;
  • le smoke de l'installateur atomique.

Le smoke de l'installateur couvre notamment :

  • première installation ;
  • seconde exécution idempotente ;
  • rollback après helpers ;
  • rollback après unités ;
  • échec de systemd-analyze verify ;
  • échec de daemon-reload ;
  • absence de fuite du secret de test ;
  • absence de mutation de l'état des timers ;
  • impossibilité d'émettre le marqueur officiel de certification depuis l'installateur.

Règle live CURRENT

L'installateur est désormais une autorité live certifiée, mais son existence ne vaut jamais autorisation permanente de mutation.

Toute nouvelle installation ou réinstallation live doit :

  1. partir d'une release authority Git propre matérialisée sous umask 022 ;
  2. revalider le SHA cible et le manifeste des 13 artefacts ;
  3. préserver le checkout historique protégé ;
  4. armer le rollback avant la première mutation ;
  5. conserver l'état des timers ;
  6. ne jamais exposer Alertmanager publiquement ;
  7. nécessiter une autorisation opérateur explicite et fraîche avant la mutation VPS.

Une certification P1.4 passée ne certifie pas automatiquement une révision future.