- 011. La règle 3-2-1-1-0 expliquée
- 022. Restic vs Borg : choisir ou combiner
- 033. Architecture cible
- 044. Scripts bash : init, backup, prune, check, restore-test
- 055. Object Lock S3 : compliance vs governance
- 066. Test de restauration mensuel automatisé
- 077. Métriques opérationnelles
- 088. Pièges récurrents et parades
- 099. Conformité ISO 27001 et NIS2
- 10En résumé
Une sauvegarde non testée n'est pas une sauvegarde. Une sauvegarde accessible en écriture par le serveur de production n'est pas une sauvegarde non plus : c'est une cible. Depuis 2020, la majorité des ransomwares modernes ciblent explicitement les répertoires de backup avant de chiffrer la production. La réponse de l'industrie tient en cinq chiffres : 3-2-1-1-0. Ce guide montre comment l'implémenter concrètement avec deux outils éprouvés, Restic et Borg, complétés par du stockage S3 verrouillé en mode compliance.
#1. La règle 3-2-1-1-0 expliquée
La règle 3-2-1 historique stipulait : 3 copies des données, sur 2 supports différents, avec 1 copie hors site. Elle reste valable mais devient insuffisante face aux menaces actuelles. La version étendue ajoute deux contraintes critiques :
- 3 copies des données (la production + 2 sauvegardes minimum) ;
- 2 supports distincts (disque local + objet S3, par exemple) ;
- 1 copie hors site (datacenter distant ou cloud public) ;
- 1 copie immuable (write-once-read-many, ou retention lock activé) ;
- 0 erreur lors des tests de vérification et de restauration.
Le « 1 immuable » casse la chaîne d'attaque : même avec les credentials du serveur de production, un attaquant ne peut pas supprimer ni chiffrer les snapshots verrouillés. Le « 0 erreur » impose un test de restauration périodique avec contrôle d'intégrité bit à bit. Sans ces deux derniers points, vous avez juste une copie de plus à perdre.
#2. Restic vs Borg : choisir ou combiner
Les deux outils partagent une philosophie commune (déduplication par blocs variables, chiffrement authentifié, snapshots) mais divergent sur les détails opérationnels.
#Déduplication
- Restic utilise CDC (Content Defined Chunking) basé sur Rabin fingerprinting, blocs entre 512 Kio et 8 Mio. Déduplication globale au repository.
- Borg utilise le buzhash, blocs entre 19 et 23 bits par défaut. Déduplication également globale, légèrement plus efficace sur des données très répétitives (VMs, bases de données dump).
En pratique, sur un parc mixte (fichiers utilisateurs, conteneurs, dumps PostgreSQL), Borg gagne 5 à 15 % d'espace par rapport à Restic. L'écart se réduit sur du média déjà compressé.
#Compression
- Restic : compression zstd activée par défaut depuis la 0.14, niveau
auto. - Borg : compression configurable au moment du backup (
lz4,zstd,zlib,lzma).zstd,3est un excellent compromis CPU/ratio.
#Chiffrement
Les deux outils chiffrent côté client en AES-256 avec authentification (Poly1305 pour Restic, HMAC-SHA256 pour Borg). Les clés ne quittent jamais le client : le serveur de stockage ne voit que des blobs opaques. C'est un prérequis non négociable pour stocker chez un fournisseur tiers.
#Backends et concurrence
- Restic parle nativement S3, Backblaze B2, Azure Blob, GCS, Swift OVH, SFTP, REST server. Plusieurs clients peuvent écrire simultanément dans le même repo.
- Borg est plus restrictif : SSH ou local, et un seul writer à la fois. Cela en fait l'outil idéal pour des snapshots locaux append-only, mais limite l'usage multi-sites sur un repo partagé.
#Notre choix : combiner les deux
Pour appliquer 3-2-1-1-0 sans gymnastique, nous déployons :
- Restic pour les sauvegardes vers S3 (off-site, immuable) — multi-clients, multi-clouds ;
- Borg pour les snapshots locaux append-only sur disque dédié — ultra-rapide, second support physique.
Cette double pile protège contre les deux scénarios majeurs : compromission de la production (Borg local en append-only n'est pas vidable depuis le client) et destruction physique du site (S3 off-site avec Object Lock).
#3. Architecture cible
Voici l'architecture que nous déroulons systématiquement sur les infrastructures que nous gérons :
┌──────────────────────┐ ┌──────────────────────┐
│ Serveur production │ │ NAS / disque dédié │
│ (agents Restic + │─────▶│ Repo Borg │
│ Borg client) │ SSH │ append-only │
└──────────┬───────────┘ └──────────────────────┘
│
│ HTTPS + AWS SigV4
▼
┌──────────────────────────────────────────────────┐
│ Bucket S3 immuable (OVH / Scaleway / MinIO) │
│ Object Lock = COMPLIANCE, retention = 30j │
│ Versioning ON, MFA Delete ON │
└──────────────────────────────────────────────────┘
Trois copies : production, Borg local, S3 distant. Deux supports : disque local et stockage objet. Une copie off-site : le bucket S3. Une copie immuable : Object Lock compliance. Reste à valider le « 0 erreur » par les tests automatisés.
#Choix du fournisseur S3
- OVH Object Storage (S3 compatible) : Object Lock disponible depuis 2024, hébergement souverain (Roubaix, Strasbourg, Gravelines). Tarif autour de 7 €/To/mois en Standard, 4 €/To/mois en classe Cold.
- Scaleway Glacier / Object Storage : Object Lock supporté, datacenters Paris/Amsterdam. ~5 €/To/mois en Standard, ~2 €/To/mois en Glacier.
- MinIO self-hosted : si vous avez deux racks distants, c'est imbattable en coût marginal et vous gardez la souveraineté complète. Plus de complexité opérationnelle.
Pour les charges critiques, doubler : Restic vers OVH et vers Scaleway. Le coût supplémentaire est marginal, l'isolation des fournisseurs est totale.
#4. Scripts bash : init, backup, prune, check, restore-test
Les scripts qui suivent sont volontairement minimalistes pour rester lisibles. Tous les secrets sont chargés depuis un fichier .env hors git, lui-même géré par un coffre (HashiCorp Vault, sops + age, ou pass).
#Initialisation du repo Restic S3
#!/usr/bin/env bash
set -euo pipefail
source /etc/backup/restic.env
export RESTIC_REPOSITORY="s3:s3.gra.io.cloud.ovh.net/backup-prod-immuable"
export RESTIC_PASSWORD_FILE=/etc/backup/restic.passwd
restic init \
--repository-version 2 \
--compression auto
echo "Repo Restic initialisé. Hash de la clé maître :"
restic key list
#Initialisation du repo Borg local en append-only
#!/usr/bin/env bash
set -euo pipefail
export BORG_REPO=/srv/borg/prod
export BORG_PASSPHRASE_FILE=/etc/backup/borg.passwd
borg init --encryption=repokey-blake2 "$BORG_REPO"
# Verrou append-only côté serveur SSH (dans authorized_keys du client)
# command="borg serve --append-only --restrict-to-path /srv/borg/prod"
L'option --append-only dans la directive SSH garantit qu'un client compromis ne peut que ajouter des archives. La suppression et la compaction nécessitent une connexion administrative séparée, depuis un autre poste.
#Backup quotidien Restic avec vérification partielle
#!/usr/bin/env bash
set -euo pipefail
source /etc/backup/restic.env
HC_URL="https://hc-ping.com/UUID-PROJET"
curl -fsS -m 10 --retry 3 "${HC_URL}/start" >/dev/null
restic backup \
--tag daily \
--exclude-caches \
--exclude-file=/etc/backup/exclude.txt \
/etc /home /srv /var/lib/postgresql/backup
# Vérification de 2 % des données réelles à chaque run
restic check --read-data-subset=2%
curl -fsS -m 10 --retry 3 "${HC_URL}" >/dev/null
Le --read-data-subset=2% est l'astuce critique : sur un repo de 500 Go, vous lisez et vérifiez réellement 10 Go de blobs chiffrés par jour. En 50 jours, l'intégralité du repo est vérifiée bit à bit, sans ralentir la fenêtre de backup.
#Backup quotidien Borg
#!/usr/bin/env bash
set -euo pipefail
export BORG_REPO=ssh://[email protected]/srv/borg/prod
export BORG_PASSPHRASE_FILE=/etc/backup/borg.passwd
ARCHIVE="prod-$(hostname -s)-$(date +%Y%m%dT%H%M%S)"
borg create \
--stats --compression zstd,3 \
--exclude-caches \
--exclude-from /etc/backup/exclude.txt \
"::${ARCHIVE}" \
/etc /home /srv /var/lib/postgresql/backup
#Prune et compact
À exécuter depuis un poste dédié, pas depuis la production. C'est ce qui rend l'append-only utile : la production ne peut pas appeler forget.
#!/usr/bin/env bash
# /usr/local/bin/backup-prune.sh — exécuté depuis le bastion d'admin
set -euo pipefail
source /etc/backup/restic.env
restic forget \
--keep-daily 14 \
--keep-weekly 8 \
--keep-monthly 12 \
--keep-yearly 5 \
--prune
# Borg équivalent
borg prune --list \
--keep-daily 14 --keep-weekly 8 \
--keep-monthly 12 --keep-yearly 5 \
ssh://[email protected]/srv/borg/prod
borg compact ssh://[email protected]/srv/borg/prod
#Check complet hebdomadaire
#!/usr/bin/env bash
set -euo pipefail
source /etc/backup/restic.env
# Vérifie structure + intégrité de tous les blobs (long mais exhaustif)
restic check --read-data
# Borg
borg check --verify-data ssh://[email protected]/srv/borg/prod
Ce check complet tourne le dimanche à 3 h, fenêtre de faible activité. Sur 500 Go, comptez 20 à 60 minutes selon le débit du backend.
#5. Object Lock S3 : compliance vs governance
Le verrouillage S3 connaît deux modes, et le choix engage votre tolérance au risque.
#Mode COMPLIANCE
Aucun utilisateur, pas même le compte root du fournisseur cloud, ne peut supprimer ou raccourcir la rétention avant son échéance. C'est le mode à choisir pour la « copie immuable » de la règle 3-2-1-1-0. Activation au niveau du bucket, puis sur chaque objet :
aws --endpoint-url https://s3.gra.io.cloud.ovh.net s3api \
put-object-lock-configuration \
--bucket backup-prod-immuable \
--object-lock-configuration '{
"ObjectLockEnabled":"Enabled",
"Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":30}}
}'
Restic écrit ensuite normalement, le bucket appose la rétention sur chaque PUT. Pendant 30 jours, ces blobs sont intouchables.
#Mode GOVERNANCE — la fausse bonne idée
Le mode GOVERNANCE permet à un utilisateur disposant de la permission s3:BypassGovernanceRetention de supprimer un objet verrouillé avant échéance. C'est commode pour corriger des erreurs, mais c'est précisément ce qu'un attaquant ayant compromis vos credentials IAM cherchera à faire. Concrètement :
# Cette commande EFFACE un objet verrouillé en mode GOVERNANCE
aws s3api delete-object \
--bucket backup-prod \
--key data/abc123 \
--version-id xyz \
--bypass-governance-retention
N'utilisez jamais GOVERNANCE pour la copie immuable. Si vous avez besoin de flexibilité administrative, gardez deux buckets : un en GOVERNANCE pour les opérations courantes, un en COMPLIANCE strict pour la copie de dernier recours. La rétention en COMPLIANCE doit être au moins égale à votre fenêtre de détection d'incident — 30 jours est un plancher, 90 jours un standard sain pour les ransomwares à activation différée.
#Versioning et MFA Delete
Activez le versioning du bucket et MFA Delete sur le compte root. Cumulé à Object Lock COMPLIANCE, vous obtenez trois couches : suppression d'un objet ne le supprime pas (versioning), suppression d'une version est refusée (Object Lock), suppression du bucket exige un token MFA physique (MFA Delete).
#6. Test de restauration mensuel automatisé
Le « 0 » de 3-2-1-1-0 ne se déclare pas, il se prouve. Voici un test mensuel qui restaure un fichier témoin et vérifie son hash.
#!/usr/bin/env bash
# /usr/local/bin/restore-test.sh
set -euo pipefail
source /etc/backup/restic.env
WORKDIR=$(mktemp -d /tmp/restore-test.XXXXXX)
trap "rm -rf $WORKDIR" EXIT
WITNESS=/etc/backup/witness.txt
EXPECTED_HASH=$(sha256sum "$WITNESS" | awk '{print $1}')
# On restaure le dernier snapshot, fichier témoin uniquement
restic restore latest \
--target "$WORKDIR" \
--include "$WITNESS"
ACTUAL_HASH=$(sha256sum "$WORKDIR$WITNESS" | awk '{print $1}')
if [[ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]]; then
echo "ALERTE: hash divergent. Backup corrompu."
curl -fsS "https://hc-ping.com/UUID-RESTORE/fail" >/dev/null
exit 1
fi
echo "Restore test OK — hash $ACTUAL_HASH"
curl -fsS "https://hc-ping.com/UUID-RESTORE" >/dev/null
Le fichier witness.txt est généré une fois pour toutes (openssl rand -base64 1024 > /etc/backup/witness.txt), inclus dans chaque backup, et son hash est connu. Toute divergence signale une corruption silencieuse — bit rot disque, manipulation, ou bug du backend S3.
Pour aller plus loin : restaurer un volume entier dans un conteneur isolé une fois par trimestre, monter, lancer un tree et un échantillonnage de hashes. Cela coûte 30 minutes et évite la mauvaise surprise du jour où tout brûle.
#7. Métriques opérationnelles
Voici les chiffres que nous observons sur un parc type PME (25 serveurs, 4 To de données utiles) :
| Métrique | Cible | Observé |
|---|---|---|
| RPO (perte de données max) | 24 h | 4 à 12 h selon la criticité |
| RTO (temps de retour) | 4 h | 1 à 3 h (restore S3 vers nouvel hôte) |
| Rétention quotidienne | 14 jours | 14 |
| Rétention long terme | 5 ans | 5 ans (1 par an) |
| Taille repo Restic après dédup | n/a | 1,8 To pour 4 To bruts |
| Taille repo Borg après dédup | n/a | 1,5 To pour 4 To bruts |
| Coût mensuel S3 (OVH Standard) | n/a | ~13 €/mois |
| Coût mensuel S3 (Scaleway Glacier) | n/a | ~4 €/mois |
| Vérification quotidienne | 2 % | 2 % (~36 Go lus/jour) |
| Test restore témoin | mensuel | mensuel automatisé |
À 4 €/To/mois en Glacier, une PME peut s'offrir la copie immuable conforme NIS2 pour le prix de deux cafés par mois. L'argument financier ne tient plus pour ne pas le faire.
#8. Pièges récurrents et parades
#Secrets en git
Le passphrase Restic, la clé Borg, les credentials S3 ne doivent jamais être committés. Vu trop souvent : un restic.env exporté dans le dépôt Ansible « privé » qui finit sur GitHub lors d'une migration. Parades :
- secrets dans HashiCorp Vault, sops + age, ou pass ;
pre-commitavecgitleaksoutrufflehogqui bloque le commit ;- rotation tous les 6 mois minimum, immédiate si suspicion.
#Rotation des accès
Les credentials S3 doivent être en write-only depuis la production (politique IAM s3:PutObject uniquement, pas de Delete, pas de List). La lecture et le delete sont réservés à un compte d'admin séparé, manipulé depuis un bastion. Cela rend impossible l'exfiltration des sauvegardes par un client compromis.
#Monitoring Wazuh + Healthchecks.io
Trois sondes minimum :
- Healthchecks.io : ping de fin de chaque job. Pas de ping = alerte sous 1 h. Gratuit jusqu'à 20 checks.
- Wazuh : règle custom qui scanne le journal
/var/log/backup/restic.loget remonte toute occurrence deerror,fatal,Load(<data/. Corrélé aux autres événements de sécurité du SIEM, cela transforme une corruption silencieuse en alerte qualifiée. - Métriques Prometheus : exporter custom qui publie la durée du dernier backup, la taille du repo, le nombre de snapshots. Alerte si la durée double ou si le nombre de snapshots stagne.
#L'erreur du repo unique
Sauvegarder vingt serveurs dans un seul repo Restic est tentant pour la déduplication globale. C'est aussi un point de défaillance unique : un passphrase compromis ouvre tout. Notre règle : un repo par périmètre de sécurité (production, dev, postes admin), passphrases distincts.
#9. Conformité ISO 27001 et NIS2
La règle 3-2-1-1-0 implémentée comme décrit ci-dessus couvre directement les contrôles suivants :
- A.8.13 Sauvegarde des informations : trois copies, deux supports, un site distant, vérification automatique.
- A.8.14 Redondance des moyens de traitement : doublement Restic + Borg, doublement OVH + Scaleway possible.
- A.5.30 Disponibilité TIC pour la continuité d'activité : RTO de 1 à 3 h documenté et testé mensuellement.
- A.8.16 Surveillance des activités : logs centralisés Wazuh, alertes Healthchecks, métriques Prometheus.
Côté NIS2, l'article 21 de la directive impose des « politiques et procédures relatives à la sauvegarde, à la reprise après sinistre et à la gestion des crises ». L'application stricte de 3-2-1-1-0 avec test de restauration documenté constitue la preuve attendue lors d'un contrôle ANSSI ou d'un audit assureur cyber.
Pour les entités importantes ou essentielles au sens NIS2, ajoutez :
- une procédure formelle de restauration (runbook signé, version courante affichée) ;
- un exercice annuel de simulation incident (chiffrement supposé de la production, restauration complète depuis S3 immuable, chronométrage) ;
- une revue trimestrielle des journaux de backup et des écarts de rétention.
Ces éléments constituent l'ossature d'un PCA / PRA technique défendable. Ils s'intègrent dans une démarche ISO 27001 plus large, mais peuvent être déployés isolément si l'urgence est uniquement la résilience anti-ransomware.
#En résumé
La règle 3-2-1-1-0 n'est pas une coquetterie d'architecte : c'est le minimum vital face aux menaces de 2026. Elle se déploie en quelques heures avec des outils libres et matures, pour un coût marginal de quelques euros par To et par mois. Les deux clés de voûte sont l'immuabilité réelle (Object Lock COMPLIANCE, jamais GOVERNANCE pour la copie de dernier recours) et le test de restauration automatisé (hash témoin mensuel, exercice complet trimestriel).
Tout le reste — choix du fournisseur, niveau de compression, fréquence du --read-data-subset — relève de l'optimisation. Ne commencez pas par là. Commencez par garantir que demain matin, si le serveur de production est chiffré, vous avez une copie qu'aucun attaquant ne peut atteindre, et que vous savez la restaurer.
On déploie ces stratégies de backup chez nos clients infogérance ISO-compliant. Voir l'infogérance ISO-compliant →
Équipe M-KIS
Cet article vous parle ?
On accompagne PME, ESN et éditeurs SaaS dans leur conformité ISO 27001 / NIS2 — Lead Auditor certifié, tarifs publics, 100 % open source.