Skip to main content

Documentation Index

Fetch the complete documentation index at: https://snakysec.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Runbook 04 — Restauration artifacts (audits JSON, GRC docs, exports)

1. Quand activer ce runbook

ScénarioActiver ?
Volume archive-data ou reports-data corrompuOUI
Suppression accidentelle d’un dossier artifacts/grc/<client>/OUI ciblé sur ce client
Reconstruction VPS depuis zéroOUI (étape §5.7 du runbook 03)
Migration vers une autre infraOUI mode contrôlé
Un seul client demande restauration d’un rapport effacé par erreur côté MSSPOUI restauration partielle (snapshot specifique + path inclusion)

2. Objectifs

  • RPO atteint : 24 heures (snapshots restic quotidiens 05:00 UTC)
  • RTO cible : 4 heures pour restauration totale, 30 min pour restauration partielle
  • WRT cible : 30 minutes (vérification exhaustive des fichiers critiques)

3. Prérequis

  • Accès SSH au VPS production
  • Vault opérationnel et unsealed
  • DR AppRole creds présentes
  • Restic password (KeePass + papier coffre)
  • Au moins un des deux repos S3 accessible (OVH ou Scaleway)
  • Volumes Docker reports-data et archive-data créés

4. Stratégies selon le scénario

4.1 Restauration totale

Restorer tout artifacts/ au dernier snapshot disponible.

4.2 Restauration partielle (un client / une période)

Restorer uniquement les chemins concernés. Plus rapide, moins risqué.

4.3 Restauration point-in-time (à un snapshot précis)

Choisir un snapshot ID spécifique plutôt que latest (utile si la corruption date d’avant le dernier snapshot).

5. Procédure de restauration totale

5.1 Identifier le snapshot cible

make dr-shell

# Liste des snapshots OVH (primaire)
AWS_ACCESS_KEY_ID="$(vault kv get -field=ovh_s3_access_key mssp/dr)" \
AWS_SECRET_ACCESS_KEY="$(vault kv get -field=ovh_s3_secret_key mssp/dr)" \
RESTIC_REPOSITORY="s3:s3.gra.io.cloud.ovh.net/mssp-backup-ovh/artifacts" \
RESTIC_PASSWORD="$(vault kv get -field=restic_password mssp/dr)" \
restic snapshots --tag artifacts
Identifier le snapshot ID (8 caractères hex) à restaurer. Par défaut, le script artifacts-restore.sh prend le latest.

5.2 Stop application + worker (artifacts en lecture par next-app)

cd /opt/mssp/app/platform
make app-down
docker compose -f compose/_common.yml -f compose/app.prod.yml stop \
  worker-chain worker-digest worker-retention worker-scheduler \
  worker-import worker-deadline worker-regression worker-permission-expiry

5.3 Sauvegarde de l’état actuel (si corruption partielle)

ssh mssp@vps.snakysec.com
sudo tar czf /opt/mssp/snapshots/artifacts-pre-restore-$(date +%Y%m%dT%H%M%SZ).tar.gz \
  -C /var/lib/docker/volumes/platform_archive-data/_data . \
  -C /var/lib/docker/volumes/platform_reports-data/_data .

5.4 Vider les volumes (si restauration totale)

docker run --rm \
  -v platform_archive-data:/archive \
  -v platform_reports-data:/reports \
  alpine sh -c "rm -rf /archive/* /archive/.[!.]* /reports/* /reports/.[!.]* 2>/dev/null || true"

5.5 Lancer le restore via dr-runner

make dr-shell
/dr/restore/artifacts-restore.sh
Le script artifacts-restore.sh (cf. §5.6 du script) :
  1. Lit credentials depuis Vault DR
  2. Restorer depuis OVH par défaut (fallback Scaleway via --repo=scaleway)
  3. Restore vers /artifacts (mounté sur les volumes archive-data + reports-data)
  4. Verify intégrité après restore
Durée typique : 30 min - 1h selon volume (~50 GB).

5.6 Validation post-restore

# Compter les fichiers restaurés
docker exec mssp-dr-runner find /artifacts -type f | wc -l

# Vérifier qu'on a au moins un sample par catégorie
docker exec mssp-dr-runner ls /artifacts/audit/ | head
docker exec mssp-dr-runner ls /artifacts/grc/ | head
docker exec mssp-dr-runner ls /artifacts/dns-zones/ | head

5.7 Redémarrage application

exit  # sortir du dr-runner
make app-up
docker compose -f compose/_common.yml -f compose/app.prod.yml up -d \
  worker-chain worker-digest worker-retention worker-scheduler \
  worker-import worker-deadline worker-regression worker-permission-expiry
sleep 30
curl -sI https://snakysec.com/api/health

6. Procédure de restauration partielle

6.1 Cas client X demande son rapport GRC supprimé par erreur

make dr-shell

# Inclure UNIQUEMENT le path du client concerné
/dr/restore/artifacts-restore.sh \
  --include="/artifacts/grc/<client-slug>/**" \
  --target-dir="/artifacts/restore-tmp"

# Vérifier les fichiers restaurés
ls -la /artifacts/restore-tmp/grc/<client-slug>/

# Si OK, déplacer vers la destination réelle
mv /artifacts/restore-tmp/grc/<client-slug>/ /artifacts/grc/

# Cleanup
rm -rf /artifacts/restore-tmp

6.2 Cas restauration d’un audit spécifique (mois N)

make dr-shell

# Identifier le snapshot couvrant la période
restic snapshots --tag artifacts --json | jq '.[] | select(.time > "2026-03-01")' | head -3

# Restore le run-id concerné
/dr/restore/artifacts-restore.sh \
  --snapshot=<snapshot-id> \
  --include="/artifacts/audit/<client-slug>/<run-id>/**"

7. Procédure de restauration point-in-time

make dr-shell

# Liste avec timestamp pour repérer le snapshot avant la corruption
restic snapshots --tag artifacts

# Restore depuis un ID précis
/dr/restore/artifacts-restore.sh --snapshot=a1b2c3d4

8. Communication client

Pour restauration partielle d’un seul client :
Objet : SnakySec — Restauration de votre rapport [titre]

Suite à votre signalement, nous avons restauré le rapport [titre] depuis
notre sauvegarde du [date snapshot].

Le fichier est à nouveau disponible dans votre portail :
https://snakysec.com/clients/[slug]/reports/[id]

Aucune autre donnée n'a été impactée. Si vous identifiez d'autres anomalies,
contactez-nous immédiatement.
Pour restauration totale (incident significatif), aligner sur runbook 01 §8.

9. Erreurs courantes et solutions

ErreurCauseSolution
restic: Fatal: unable to open repository at...Bucket inaccessible (OVH down ou keys invalides)Try --repo=scaleway
restic: ignoring error for /artifacts/...: read-only file systemVolume monté roVerifier compose/dr.yml — /artifacts doit être rw pour restore
Restore OK mais next-app voit fichiers absentsPermissions UID mismatch (restic restore sous root)chown -R 1000:1000 /artifacts/* (ajuster UID au runtime app)
Snapshot vide (0 fichier restauré)Mauvais tag ou path d’inclusionLister snapshot content : restic ls <snapshot-id>
restic: Fatal: snapshot is lockedBackup en cours en parallèleAttendre + retry ou restic unlock (si on est sûr qu’aucune écriture concurrente)

10. Validation du runbook

Testé annuellement (Q1, mêmes phase que Postgres PITR car couplé dans l’exercice). Restauration partielle testée mensuellement via test client random (samedi 1er du mois).
VersionDateAuteur
1.02026-04-26Nicolas Schiffgens