La mascotte ours polaire de NordBastion, debout dans un coffre en pierre nordique sombre à côté d'une baie de serveurs, tenant une clé cyan lumineuse, tandis qu'une chaîne de cinq blocs holographiques cyan marqués de cadenas s'arque à travers une arche runique vers une seconde baie de serveurs au loin, sous une faible aurore boréale
How-to · Opsec·16 min de lecture · 45 min pratique

Sauvegarde VPS chiffrée.
Hors site, dédupliquée, et hors de portée.

Sauvegarde VPS chiffrée en six étapes : d'un serveur nu à un dépôt chiffré et vérifié sur une seconde machine, dans une seconde juridiction — restic et Borg comparés, des dumps de base de données qui restaurent proprement, un timer systemd, et un dépôt append-only qu'un serveur compromis ne peut pas effacer. La seconde machine coûte $3.90 par mois. Testé sur Debian 12.

Les six étapes
  1. 01

    Inventaire

    Ce qui ne peut pas être reconstruit

  2. 02

    Installer

    restic ou Borg

  3. 03

    Destination

    Un second bastion

  4. 04

    Initialiser

    Dépôt + première exécution

  5. 05

    Automatiser

    Dumps, timer, rétention

  6. 06

    Exercice

    Restaurez, et chronométrez

Avant de commencer · À quoi ça sert

Quatre façons de perdre des données. Une seule est un disque cassé.

Presque toute discussion sur les sauvegardes dérape dès la première minute, parce que les deux interlocuteurs pensent à des défaillances différentes. L'un imagine un disque mort. L'autre imagine un mardi matin où le compte a disparu. Ils ont besoin de réponses différentes, et une configuration qui ne survit qu'à la première paraît sûre jusqu'au jour où elle est mise à l'épreuve par la seconde.

Il existe quatre modes de défaillance contre lesquels il vaut la peine de se prémunir, et ce ne sont pas des variations sur un même thème — chacun met en échec une défense différente.

Matériel. Le NVMe tombe en panne, le nœud hôte meurt, la grappe perd deux membres à la fois. C'est la panne pour laquelle tout le monde se prépare, et c'est la plus rare sur une infrastructure virtualisée moderne. Le stockage redondant s'en charge. Le stockage redondant ne gère rien d'autre, ce qui explique pourquoi le RAID n'est pas une sauvegarde et ne l'a jamais été : il copie fidèlement chaque écriture, y compris celle qui dit « tout supprimer ».

Humain. Un script de migration exécuté sur la production. Un DROP TABLE dans le mauvais terminal. Un rsync avec les arguments inversés. C'est de loin la cause la plus fréquente de perte de données réelle, et la seule défense contre elle est l'historique — une copie antérieure à l'erreur, conservée là où l'erreur n'a pas pu l'atteindre. Le temps est l'ingrédient clé : si la seule copie est un miroir en retard de trente secondes, elle contient déjà l'erreur.

Malveillant. Quelqu'un obtient les droits root, ou un rançongiciel s'introduit via une application non corrigée. La première chose que fait un rançongiciel moderne est de chercher la configuration de sauvegarde — identifiants, partages montés, clés cloud — et de détruire ce qu'il trouve, précisément parce qu'une restauration fonctionnelle transforme une catastrophe en simple après-midi. Un identifiant de sauvegarde capable de supprimer est un identifiant que l'attaquant hérite. C'est la faille pour laquelle existe le chapitre append-only de ce guide.

Dépositaire. Rien n'a cassé et rien n'a été attaqué ; vous avez simplement perdu l'accès. Un compte suspendu pour un signal de fraude automatisé, une carte refusée pendant un voyage, un litige, un contrôle de conformité, une injonction signifiée au prestataire. La machine est intacte et injoignable, et chaque snapshot de ce compte l'est avec elle. C'est la défaillance à laquelle aucune redondance chez un seul prestataire ne peut répondre, et la raison pour laquelle une sauvegarde sérieuse vit sous un autre toit.

Défense Matériel Erreur humaine Rançongiciel Compte perdu
RAID / stockage redondantOuiNonNonNon
Snapshot du fournisseur, même compteOuiPartiellementNonNon
Dépôt hors site, clé en écritureOuiOuiNonOui
Dépôt hors site, append-only, autre juridictionOuiOuiOuiOui

La dernière ligne est ce que construit le reste de ce guide. Elle ne coûte pas plus cher que la ligne au-dessus — le réglage append-only est gratuit et la seconde juridiction coûte le même $3.90 que la première.

La règle du 3-2-1, reformulée pour un VPS unique. Trois copies des données, sur deux types de stockage différents, dont une hors site. La formulation classique date d'une époque de bandes magnétiques et de serveurs de bureau, et l'esprit survit mieux à la traduction que la lettre. Pour une seule machine auto-hébergée, cela donne : les données en production sur le VPS, un dépôt sur une seconde machine ailleurs, et — pour tout ce qui est vraiment irremplaçable — une troisième copie que vous pouvez tenir en main, sur un disque à la maison ou dans un tiroir. Le chiffre qui compte vraiment n'est pas trois. C'est le nombre de choses indépendantes qui doivent mal tourner avant que les données ne disparaissent. Deux est le minimum qui vaille la peine d'être eu.

Avant de commencer · Choix de l'outil

restic, Borg, ou rsync. Deux d'entre eux sont des sauvegardes.

La catégorie que vous cherchez s'appelle un outil de snapshot dédupliquant et chiffrant. Il découpe chaque fichier en chunks définis par le contenu, chiffre chaque chunk sur la machine propriétaire des données, et ne le stocke qu'une seule fois, quel que soit le nombre de snapshots qui le référencent. Cela vous donne trois propriétés à la fois : de nombreux points de restauration pour à peine plus d'espace qu'un seul, un contenu en clair qui ne quitte jamais la source, et un transfert qui ne déplace que ce qui a changé.

Deux programmes dominent ce domaine et tous deux sont excellents. restic est un binaire Go statique unique, avec un large éventail de backends de stockage. BorgBackup est un programme Python qui parle SSH avec une copie de lui-même à l'autre bout. Tout ce qui suit est la différence honnête entre les deux.

Propriété restic BorgBackup rsync / rclone
Chiffrement côté clientToujours actif, non facultatifToujours actif, non facultatifUniquement via un remote rclone crypt
DéduplicationChunks définis par le contenuChunks définis par le contenuAucune, ou des arborescences de hardlinks
Historique des snapshotsOui, avec des politiques de rétentionOui, avec des politiques de rétentionUn miroir de l'instant présent
Exigences de la destinationRien — SFTP, S3, REST, rcloneBorg installé aux deux extrémitésUn compte SSH ou une API
Application de l'append-onlyVia rest-server ou un verrou d'objetIntégré, via SSH simpleAucun
Idéal pourPresque tout le monde, la plupart des backendsUne machine SSH que vous possédez, en append-onlyMiroir, pas sauvegarde

rsync figure dans le tableau parce que c'est le premier outil vers lequel la plupart des gens se tournent, et parce que c'est réellement le mauvais outil : un miroir reproduit fidèlement une suppression, et le miroir d'un disque chiffré au repos n'est lui-même chiffré nulle part. Il mérite sa place à l'intérieur d'une sauvegarde comme ce qui déplace une archive terminée, pas comme l'archive elle-même.

Ce guide montre à la fois restic et Borg pour chaque commande qui diffère, afin que vous puissiez le suivre avec l'un ou l'autre. Là où un choix unique s'impose — l'exemple traité, le timer, le script — c'est restic qui est utilisé, car la destination n'a alors besoin de rien d'autre qu'un compte SSH, ce qui garde la seconde machine parfaitement ennuyeuse.

Étape 01 · Inventaire

Ce qui ne peut pas être reconstruit. Notez-le avant de l'automatiser.

Sauvegarder tout le système de fichiers est un choix défendable et gaspilleur à la fois. La majeure partie d'un serveur n'est qu'à un gestionnaire de paquets de la recréation, et chaque gigaoctet transporté en plus ralentit l'élagage du dépôt, coûte plus cher à conserver et ralentit la recherche quand vous êtes pressé. L'exercice utile est l'inverse : lister ce qu'une installation neuve ne vous rendrait pas.

Pour un VPS auto-hébergé classique, cette liste est courte, et elle contient toujours ces cinq éléments :

  • 01Contenu de la base de données. Pas le répertoire de données — le dump. L'étape 05 explique pourquoi.
  • 02Fichiers mis en ligne par les utilisateurs. Volumes Docker, un répertoire d'uploads ou de médias, un stockage mail. C'est généralement le gros des octets.
  • 03Configuration et secrets. Les fichiers Compose, les fichiers .env, les clés de chiffrement, les jetons d'API. Petit, et pourtant la différence entre une restauration de deux heures et une de deux jours.
  • 04État système que vous avez modifié. /etc dans son ensemble est assez petit pour être pris en bloc — configuration sshd, règles de pare-feu, unités systemd, entrées cron, le routage mail sur lequel vous avez passé une soirée.
  • 05Tout ce qui porte une identité. Une clé de service caché Tor, une clé de signature Matrix, une clé privée WireGuard, un portefeuille de nœud. Perdez l'une d'elles et le service ne revient pas — un service différent portant le même nom revient à la place.

Transformez la liste en deux fichiers sur le serveur source. Une liste d'inclusion garde l'intention visible ; une liste d'exclusion écarte le bruit. Les deux sont lues par la commande de sauvegarde, et les deux doivent elles-mêmes figurer dans la sauvegarde.

/etc/backup/include.txt

/etc
/opt
/root
/var/backups
/var/lib/docker/volumes
/home

/etc/backup/exclude.txt

# Caches and rebuildable artefacts
**/node_modules
**/.cache
**/*.tmp
/var/lib/docker/volumes/*/_data/cache
# Log noise — keep the config, drop the volume
/var/log/journal
# Never back up the mount point you restore into
/mnt/restore

Deux remarques sur cette ligne Docker, car elle piège pas mal de monde. Les volumes nommés vivent sous /var/lib/docker/volumes et c'est ce que vous voulez ; les bind mounts vivent où vous les placez, en général à côté du fichier Compose, et sont couverts par /opt. Les images de conteneurs ne sont pas des données — elles reviennent avec un pull, et une sauvegarde qui les transporte transporte des gigaoctets dont elle n'a pas besoin.

Enfin, mesurez le résultat avant de construire quoi que ce soit autour. Ce chiffre indique quel palier de dépôt commander et si le premier envoi prendra quatre minutes ou quarante :

du -sh --exclude=/var/lib/docker/overlay2 /etc /opt /root /home /var/lib/docker/volumes
Étape 02 · Installation

Un seul binaire sur la source. Rien d'autre ne change.

Installez l'outil sur la machine qui détient les données. Sur Debian et Ubuntu, les deux sont empaquetés, et pour restic le paquet de la distribution a souvent une ou deux versions de retard — ce qui compte, car les fonctionnalités de dépôt et les gains de performance arrivent dans les versions mineures. Installez le paquet, puis laissez restic se mettre à jour lui-même :

apt update && apt install -y restic
restic self-update
restic version

Pour Borg, le paquet de la distribution est le bon choix, car la version côté source et celle côté destination doivent se comprendre, et une paire assortie issue de la même version de distribution est le moyen le moins douloureux d'y parvenir :

apt install -y borgbackup
borg --version

Un mot sur les versions majeures avant d'engager des années d'historique dans un dépôt : le format de dépôt de Borg a changé entre ses lignes majeures, et faire passer un dépôt d'une ligne à l'autre est une conversion, pas une mise à jour. Lisez les notes de version de celle que vous installez, et gardez la destination sur la même ligne majeure que la source. restic est resté rétrocompatible entre ses versions et ajoute ses fonctionnalités derrière une version de dépôt explicite, donc l'inquiétude équivalente y est moindre.

Aucun des deux outils n'a besoin d'un démon, d'un agent ou d'un port ouvert sur la source. Cela mérite d'être dit clairement : le système de sauvegarde que vous installez n'ajoute aucun service à l'écoute ni aucune nouvelle surface d'attaque à la machine qu'il protège. Tout ce qu'il fait est sortant, sur un planning, via SSH.

Étape 03 · Destination

Un second bastion, et une clé qui ne peut pas supprimer. C'est l'étape qui compte.

L'hôte du dépôt n'a qu'un seul rôle et presque aucune exigence. Il n'a pas besoin de cœurs, car il ne lit jamais vos données — il ne fait qu'héberger des blobs chiffrés qu'il ne peut pas ouvrir. Il n'a pas besoin de mémoire, car le travail de déduplication se fait sur la source. Il a besoin de disque, d'une adresse stable, et d'être ailleurs, là où les ennuis de la machine source ne le suivent pas.

Dans le panel : Commander → VPS → Sentinel, image Debian 12, et — c'est tout l'enjeu — un bastion différent de celui où tourne la source. Helsinki pour le travail, Reykjavík pour la garde. Aucune adresse e-mail n'est requise pour ouvrir le compte, et la facture se règle en Monero, Bitcoin, Lightning ou tout autre actif pris en charge, ce qui signifie que la seconde machine ne réintroduit pas l'identité que la première avait pris soin d'éviter.

Dépôt cible Mensuel Stockage Working set hébergé Coût de restauration
Sentinel$3.90120 GB NVMe~30 GBRien — non facturée au volume
Garrison$7.90240 GB NVMe~70 GBRien — non facturée au volume
Ravelin$16.90480 GB NVMe~150 GBRien — non facturée au volume
Bulwark$32.90960 GB NVMe~300 GBRien — non facturée au volume
Stockage objet de classe S3~$0.023/GBÉlastiqueN'importe lequelSortie facturée au volume

La colonne working set suppose des snapshots quotidiens conservés un an avec un taux de renouvellement normal ; un dépôt qui contient surtout des fichiers évoluant lentement va beaucoup plus loin, un dépôt plein de gros binaires réécrits va moins loin. La dernière ligne est là pour l'échelle, et pour le détail que tout le monde oublie jusqu'au jour où ça tourne mal : le stockage objet facture aussi le téléchargement, et c'est précisément ce que vous faites en cas d'urgence.

Sur la destination — un utilisateur sans privilège et un répertoire.

adduser --disabled-password --gecos "" backup
install -d -m 0700 -o backup -g backup /srv/restic/web01

L'utilisateur de sauvegarde n'a ni mot de passe, ni sudo, ni rien où se connecter. Il existe pour posséder un répertoire. Donnez-lui son propre répertoire par machine source si vous en sauvegardez plusieurs — un dépôt par source évite qu'une compromission sur une machine touche l'historique d'une autre.

Sur la source — une clé qui ne sert à rien d'autre.

ssh-keygen -t ed25519 -f /root/.ssh/id_backup -N "" -C "backup:web01"
cat /root/.ssh/id_backup.pub

Ne réutilisez pas votre clé de connexion habituelle. Celle-ci vit en clair sur le disque parce qu'un timer non surveillé doit s'en servir à trois heures du matin, ce qui est exactement le genre de clé que l'on veut cantonner à une seule destination et un seul usage.

Retour sur la destination — restreignez ce que cette clé peut faire. Collez la clé publique dans /home/backup/.ssh/authorized_keys avec un préfixe devant. Pour restic via SFTP :

restrict,from="198.51.100.7" ssh-ed25519 AAAAC3NzaC1lZDI1... backup:web01

L'option restrict désactive en un mot le port forwarding, l'agent forwarding, X11 et l'allocation de PTY, ne laissant que le transfert de fichiers et rien d'autre. La clause from= épingle la clé à l'adresse source, si bien qu'une copie volée sur le serveur est inutilisable ailleurs. Pour Borg, allez un cran plus loin et forcez la commande, c'est là que vit son mode append-only :

command="borg serve --append-only --restrict-to-path /srv/borg/web01",restrict ssh-ed25519 AAAAC3NzaC1lZDI1... borg:web01

Cette ligne concentre à elle seule toute la défense contre les rançongiciels : quoi que la source envoie, la destination ne fera jamais qu'exécuter borg serve, uniquement dans ce chemin, et uniquement dans un mode qui ajoute. Un shell root sur la source ne peut pas utiliser cette clé pour effacer le mois dernier.

Déclarez la destination une fois, sur la source. Placez-la dans /root/.ssh/config pour que toutes les commandes suivantes restent courtes et que l'adresse ne vive que dans un seul fichier :

Host rkv-repo
    HostName 198.51.100.42
    User backup
    IdentityFile /root/.ssh/id_backup
    IdentitiesOnly yes

Connectez-vous ensuite une fois à la main — ssh rkv-repo — pour accepter la clé de l'hôte. Un timer sans surveillance ne répondra pas à une invite d'empreinte, et une première sauvegarde qui se bloque silencieusement pendant une semaine est un classique. Tant que vous êtes sur la destination, faites-lui subir le même traitement qu'à toute autre machine que vous possédez : exécutez-y aussi la checklist de durcissement de la première heure. Elle héberge une copie de tout, et mérite l'heure complète.

Étape 04 · Initialiser

La phrase de passe, puis le premier snapshot. Dans cet ordre, et hors de la machine.

Générez une phrase de passe que vous ne taperez jamais. Elle est lue dans un fichier par un script, donc la longueur ne coûte rien et rien ne justifie de la rendre mémorisable :

openssl rand -base64 32 > /root/.restic-pass
chmod 600 /root/.restic-pass
cat /root/.restic-pass

Maintenant, arrêtez-vous et copiez cette chaîne quelque part qui n'est pas ce serveur. Un gestionnaire de mots de passe, une note papier dans un tiroir, une seconde machine — n'importe où qui survit à la perte de la source. C'est la même défaillance qui détruit les coffres auto-hébergés et les moteurs d'automatisation : la clé qui déchiffre tout est stockée à côté de tout, et les deux sont perdus ensemble. Un dépôt dont la phrase de passe n'existait que sur la machine qu'il protégeait n'est pas une sauvegarde ; c'est un tas de bruit très bien rangé.

Écrivez le fichier d'environnement que toutes les commandes suivantes liront :

/etc/backup/restic.env

RESTIC_REPOSITORY=sftp:rkv-repo:/srv/restic/web01
RESTIC_PASSWORD_FILE=/root/.restic-pass
chmod 600 /etc/backup/restic.env
set -a; . /etc/backup/restic.env; set +a
restic init

La paire équivalente pour Borg — le mode repokey stocke la clé de chiffrement à l'intérieur du dépôt, protégée par la phrase de passe, ce qui est pratique et c'est précisément pour cela que vous en exportez aussi une copie :

export BORG_REPO=ssh://borg@rkv-repo/srv/borg/web01
export BORG_PASSCOMMAND="cat /root/.restic-pass"
borg init --encryption=repokey-blake2
borg key export ::  /root/borg-key.txt   # copy this off the server too

Le premier snapshot. Lancez-la à la main, surveillez-la, et laissez-la se terminer avant d'automatiser quoi que ce soit. C'est la lente — chaque chunk est nouveau — et c'est cette exécution qui vous dit si la liste d'inclusion était correcte :

restic backup \
  --files-from /etc/backup/include.txt \
  --exclude-file /etc/backup/exclude.txt \
  --tag nightly --one-file-system --verbose

Si la source sert du trafic et que l'envoi sature le lien, bridez-le. Le drapeau prend des kibioctets par seconde, donc 20000 correspond environ à 20 Mo/s :

restic backup --limit-upload 20000 --files-from /etc/backup/include.txt

Une fois terminé, regardez ce que vous avez réellement obtenu. Voici les trois commandes à lancer maintenant, puis à nouveau dans six mois quand vous aurez cessé d'y penser :

restic snapshots                    # the list, with dates and tags
restic stats latest                 # what the newest snapshot contains
restic ls latest /etc/backup        # confirm a path you expected is in there

Cette troisième commande mérite un instant d'attention. La moitié des sauvegardes cassées ne le sont pas du tout — ce sont des dépôts complets et sains, mais du mauvais répertoire. Lister un chemin que vous vous attendiez à trouver, dès le tout premier snapshot, permet de repérer cela pendant que le fichier d'inclusion est encore frais dans votre mémoire.

Étape 05 · Automatiser

Dump d'abord, snapshot ensuite. Un script, un timer, une politique de rétention.

La règle des bases de données, énoncée une fois pour toutes. Un moteur de base de données actif conserve son état en mémoire et l'écrit sur disque à son propre rythme. Lire ses fichiers pendant ce processus donne un ensemble de pages provenant de plusieurs instants différents — un fichier qui peut se restaurer, se restaurer corrompu, ou se restaurer en quelque chose qui s'ouvre proprement mais qui manque discrètement la dernière heure. Rien ne permet de savoir lequel depuis l'extérieur. C'est pourquoi la sauvegarde ne touche jamais aux fichiers actifs : un dump est d'abord écrit sur disque, et c'est ce dump que la sauvegarde récupère.

Tout tient dans un seul script. Placez-le dans /usr/local/sbin/nb-backup.sh, rendez-le exécutable, et gardez-le dans la sauvegarde elle-même :

#!/bin/sh
set -eu

# ---- 1. Consistent dumps, written where the include list will find them.
install -d -m 0700 /var/backups/db

# PostgreSQL in a container:
docker exec -t app-db pg_dumpall -U postgres | gzip -9 > /var/backups/db/postgres.sql.gz

# MariaDB / MySQL, InnoDB tables:
# docker exec -t mail-db mariadb-dump --single-transaction --all-databases \
#   | gzip -9 > /var/backups/db/mariadb.sql.gz

# SQLite — never a plain file copy:
# sqlite3 /opt/app/data/app.db ".backup '/var/backups/db/app.db'"

# ---- 2. The snapshot.
restic backup \
  --files-from /etc/backup/include.txt \
  --exclude-file /etc/backup/exclude.txt \
  --tag nightly --one-file-system

# ---- 3. Retention, then reclaim the space it freed.
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

# ---- 4. Structural check every night; read 5% of the data on Sundays.
restic check
[ "$(date +%u)" = "7" ] && restic check --read-data-subset=5%

echo "backup ok: $(date -u +%FT%TZ)"

Trois détails de ce script travaillent plus qu'il n'y paraît. Le set -eu en tête signifie qu'un dump raté interrompt l'exécution au lieu de mettre silencieusement en snapshot le dump de la veille pendant les six mois suivants. Le forget et le prune ne font qu'une seule commande, car une politique de rétention qui ne libère jamais d'espace revient à un disque qui se remplit. Et le contrôle du dimanche lit une tranche des données réelles plutôt que le seul index — la corruption d'un dépôt est rare, et silencieuse, et seule la lecture permet de la détecter.

Le timer. Deux petits fichiers unit. systemd est ici le bon ordonnanceur plutôt que cron, parce qu'un timer vous donne Persistent — une exécution manquée pendant que la machine était éteinte a lieu au démarrage suivant au lieu d'être silencieusement sautée — et parce que journalctl conserve alors l'historique de chaque exécution.

/etc/systemd/system/nb-backup.service

[Unit]
Description=Nightly encrypted offsite backup
Wants=network-online.target
After=network-online.target docker.service

[Service]
Type=oneshot
EnvironmentFile=/etc/backup/restic.env
ExecStart=/usr/local/sbin/nb-backup.sh
Nice=10
IOSchedulingClass=idle

/etc/systemd/system/nb-backup.timer

[Unit]
Description=Nightly encrypted offsite backup

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=45m
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now nb-backup.timer
systemctl list-timers nb-backup.timer
systemctl start nb-backup.service && journalctl -u nb-backup.service -n 40 --no-pager

Le délai aléatoire n'est pas décoratif. Tous les serveurs auto-hébergés d'Internet lancent leur maintenance exactement à 03h00, et une sauvegarde qui démarre à la même seconde que la rotation des logs, le renouvellement du certificat et la mise à jour des conteneurs passe sa nuit à leur disputer les I/O. Étaler le démarrage sur quarante-cinq minutes ne coûte rien et élimine toute une catégorie de nuits mystérieusement lentes.

Ensuite, rendez l'échec bruyant. C'est l'étape que tout le monde saute, et c'est elle qui détermine si tout ce qui précède valait la peine d'être fait. Une sauvegarde qui cesse de fonctionner ne l'annonce jamais : le timer continue de se déclencher, le service continue d'échouer, et le dernier snapshot valide s'éloigne dans le passé pendant que le tableau de bord reste vert. Ajoutez au service une unité OnFailure= qui vous envoie quelque chose que vous verrez vraiment, et jetez un œil une fois par mois au haut de la liste des snapshots. Une ligne, une habitude.

restic snapshots --latest 3        # is the newest one from last night?
systemctl list-timers nb-backup.timer   # is the timer still armed?
Étape 06 · Exercice

Restaurez-la maintenant, pendant que rien ne brûle. Une sauvegarde non testée n'est qu'une rumeur.

Il y a deux exercices, et ils répondent à des questions différentes. Le petit demande « les données sont-elles vraiment là et lisibles ? » et prend quatre-vingt-dix secondes. Le grand demande « combien de temps faudrait-il réellement pour relancer le service ? » et prend un après-midi, une fois par an. Faites le petit tous les mois. Faites le grand au moins une fois, car la réponse n'est jamais celle qu'on imagine.

Le petit exercice. Récupérez un répertoire et un dump vers un chemin temporaire, puis comparez-les avec ce qui est en production :

install -d -m 0700 /mnt/restore
restic restore latest --target /mnt/restore --include /etc/backup
restic restore latest --target /mnt/restore --include /var/backups/db

diff -r /etc/backup /mnt/restore/etc/backup && echo "config identical"
gzip -t /mnt/restore/var/backups/db/postgres.sql.gz && echo "dump readable"

Mieux encore, quand l'outil le propose : montez le dépôt en lecture seule et parcourez-le comme un système de fichiers. Chaque snapshot apparaît comme un répertoire daté, et vous pouvez parcourir l'historique avec ls et cat sans rien restaurer du tout. Cela nécessite FUSE sur la machine qui effectue le montage :

restic mount /mnt/snapshots      # then: ls /mnt/snapshots/snapshots/latest/
borg mount ::  /mnt/snapshots     # the Borg equivalent

Le grand exercice. Commandez un VPS jetable à l'heure, et reconstruisez le service dessus à partir du seul dépôt — aucune note de mémoire, aucun fichier copié depuis la machine en production. Travaillez à partir d'un runbook écrit et corrigez-le au fur et à mesure, car les lacunes que vous trouvez sont tout l'intérêt de l'exercice. Les découvertes habituelles, par ordre de fréquence : la phrase de passe n'existait que sur la machine morte ; les enregistrements DNS n'avaient jamais été notés ; un répertoire monté en bind mount se trouvait hors de toute liste d'inclusion ; la restauration nécessitait une version de paquet qui n'est plus celle par défaut ; personne ne savait quel conteneur devait démarrer en premier.

Chronométrez-le. Notez le chiffre en haut du runbook avec la date. Ce chiffre — pas la taille du dépôt, pas le nombre de snapshots — est la seule mesure honnête du niveau de protection réel du service.

Et lisez les données de temps en temps. Le contrôle nocturne vérifie la structure : que l'index est cohérent avec lui-même et qu'aucun blob ne manque. Il ne lit pas les blobs. Une fois par mois, ou lors de l'exécution du dimanche, lisez-en une tranche — cinq pour cent en rotation couvrent tout le dépôt en quelques mois, sans jamais coûter une longue nuit :

restic check --read-data-subset=5%
borg check --verify-data              # the Borg equivalent, slower and thorough
La partie difficile · Append-only

Une clé qui peut écrire, et ne peut pas effacer. La différence entre une mauvaise semaine et une entreprise fermée.

Tout ce qui précède protège contre les accidents. Ce chapitre protège contre un adversaire, et le problème de conception devient inconfortable dès qu'on le voit : la machine source doit joindre le dépôt chaque nuit, ce qui signifie qu'elle détient un identifiant fonctionnel pour ce dépôt. Qui possède la source possède cet identifiant. Si l'identifiant peut supprimer, l'attaquant supprime — et c'est exactement ce que fait le ransomware moderne, délibérément, avant même de chiffrer quoi que ce soit, parce qu'une victime capable de se restaurer ne paie pas.

La solution n'est pas un meilleur mot de passe. C'est une permission asymétrique : la source peut ajouter des données mais ne peut en supprimer aucune. Trois façons de la construire, par ordre décroissant de facilité à bien faire.

Un — append-only forcé via SSH. C'est le terrain de prédilection de Borg, et c'est la réponse la plus propre disponible sur une machine que vous possédez. L'entrée authorized_keys de l'étape 03 force borg serve --append-only, si bien que le bout distant refuse toute suppression quoi que demande le bout proche. Le prune doit quand même avoir lieu, mais il se fait depuis la destination, selon un calendrier que la source ne peut pas influencer, exécuté par un compte que la source ne peut pas atteindre. Un attaquant qui a root sur la source peut remplir le dépôt de déchets ; il ne peut pas supprimer l'archive de la nuit précédant son arrivée.

Deux — un point de terminaison REST en append-only. Le rest-server, compagnon de restic, dispose d'un mode --append-only avec la même propriété : les nouveaux blobs sont acceptés, les existants ne peuvent pas être supprimés. Faites-le tourner sur la destination derrière TLS, pointez RESTIC_REPOSITORY vers l'URL https:// au lieu de la sftp:, et la forme de la défense est identique. Cela coûte un service de plus sur la destination et achète la même garantie.

Trois — verrou d'objet. Sur un stockage compatible S3, le versioning associé à une période de rétention avec verrouillage d'objet rend la suppression impossible avant l'expiration de cette période, appliquée par la couche de stockage plutôt que par un programme. C'est la plus solide des trois solutions et la plus coûteuse, et elle introduit un compte prestataire — ce qui réintroduit le risque de dépositaire que tout ce guide cherche à répartir. Sensé comme troisième copie, maladroit comme copie unique.

Si rien de tout cela ne convient — SFTP simple, une clé qui peut écrire et donc supprimer — ne faites pas comme si de rien n'était ; ajoutez une seconde copie indépendante que la source ne peut absolument pas toucher. Pull plutôt que push : laissez la destination se connecter à la source, lire ce dont elle a besoin, et le stocker. Les identifiants vivent alors sur la machine qui n'est pas exposée, et un attaquant sur la source ne trouve rien qui pointe vers la sauvegarde. C'est un peu plus de travail à mettre en place, et cela inverse le risque exactement dans le bon sens.

Quel que soit votre choix, vérifiez-le comme vous vérifieriez tout autre contrôle de sécurité — en essayant de le casser. Depuis la source, avec la clé de sauvegarde, tentez une suppression. Le résultat correct est un refus.

borg delete ::name-of-an-old-archive
# → Remote: Repository is in append-only mode. Refusing to delete.
Notes de terrain · Par service

Le seul fichier sans lequel chaque service ne peut pas revenir. C'est rarement le plus gros.

Chaque service possède un petit élément d'état qui n'est ni une donnée ni une configuration, et le perdre n'endommage pas le service — cela le remplace par un service différent qui porte le même nom. Les anciens liens cassent, les pairs fédérés refusent la nouvelle identité, les clients renouvellent leurs clés. Voici ces éléments, par stack, pour tout ce que ce site couvre dans ses guides.

Nextcloud

Le répertoire de données, config/config.php, et un dump de base de données. Activez le mode maintenance pour le dump, désactivez-le ensuite — sinon Nextcloud écrit dans les deux en même temps.

Vaultwarden

L'ensemble du répertoire de données : db.sqlite3 pris avec .backup plutôt que copié, plus les fichiers rsa_key, les pièces jointes et les envois.

Matrix Synapse

La clé de signature, homeserver.yaml, le stockage des médias et un dump PostgreSQL. Perdez la clé de signature et l'identité de fédération disparaît pour de bon.

Serveur mail

Le stockage de messagerie lui-même, les tables d'utilisateurs virtuels, et les clés privées DKIM — une nouvelle clé DKIM signifie que chaque message reste non signé jusqu'à ce que le DNS se mette à jour.

n8n

N8N_ENCRYPTION_KEY d'abord, puis le dump PostgreSQL. La base sans cette clé n'est qu'une liste de workflows dont chaque identifiant est illisible.

Service onion Tor

Le répertoire du service caché. Ces quelques fichiers constituent l'adresse .onion — sans eux, le service revient sous un nom différent et tous les liens qui y mènent sont morts.

WireGuard

/etc/wireguard en entier. Petit, sans intérêt, et la différence entre une reconstruction de cinq minutes et le renouvellement des clés de tous vos appareils.

Lightning node

La seed et l'état des canaux, selon les termes propres du nœud. Restaurer des données de canal obsolètes peut vous coûter des fonds — suivez la procédure de sauvegarde de l'implémentation, pas une copie de fichiers générique.

La couche sous le stockage

La distance est une réponse technique. La juridiction est l'autre moitié.

Demandez à la plupart des gens pourquoi la sauvegarde doit être ailleurs, et la réponse est l'incendie, l'inondation, ou une panne de courant en datacentre. Tout cela est vrai, tout cela devient rare, et une centaine de kilomètres de distance y répond. Les défaillances qui mettent réellement les entreprises à terre en 2026 sont administratives, et la distance seule n'y change rien.

Un seul compte est un point de défaillance unique. Une suspension pour un signal de fraude automatisé, une rétrofacturation pendant que vous étiez dans l'avion, un contrôle de conformité, une notification de retrait adressée à l'entreprise plutôt qu'à une machine — chacun de ces événements touche tous les serveurs de ce compte au même instant, y compris celui qui détient les snapshots. La redondance technique était parfaite et sans importance. Deux prestataires, ou au minimum deux comptes sous deux structures juridiques différentes, est la seule architecture qui répond à cela.

Une seule juridiction est un seul cadre juridique. Les quatre bastions nordiques ne sont pas interchangeables — la Suède, la Finlande, la Norvège et l'Islande protègent chacune une chose légèrement différente, et la Norvège comme l'Islande se situent entièrement hors de l'Union européenne. Répartir une machine de production et son dépôt entre deux d'entre eux signifie que la copie n'est pas simplement ailleurs ; elle relève d'un second jeu de règles, indépendant. La référence des juridictions nordiques passe les textes en revue un par un.

Et la destination n'apprend rien. C'est ce qui rend la répartition peu coûteuse plutôt qu'un compromis. restic comme Borg chiffrent avant que quoi que ce soit ne quitte la source, si bien que l'hôte du dépôt stocke des blobs dont il n'a pas la clé. Il ne sait ni quels fichiers il détient, ni combien, ni comment ils s'appellent. Vous n'accordez pas votre confiance à un second acteur ; vous louez un disque incapable de se lire lui-même. C'est aussi la réponse honnête à la question « dois-je utiliser un fournisseur en qui je n'ai pas totalement confiance comme cible de sauvegarde ? » — pour un dépôt chiffré, la confiance entre à peine en jeu.

La latence n'est pas un facteur. Helsinki-Reykjavík, c'est 30 ms sur le backbone, Helsinki-Stockholm 8 ms, Stockholm-Oslo 11 ms. Une sauvegarde nocturne se moque de tous ces chiffres, tout comme une restauration limitée par le débit du disque. Choisissez la paire pour la distance juridique, pas pour la distance réseau — la distance réseau à travers les pays nordiques est une erreur d'arrondi.

Une dernière chose mérite d'être dite clairement, car c'est la raison pour laquelle ce guide se trouve sur ce site plutôt que sur un blog sysadmin générique : la seconde machine rouvre chaque question à laquelle la première avait répondu. Si le VPS de travail a été commandé sans pièce d'identité et payé en Monero, puis que la machine de sauvegarde qui lui est associée est commandée avec une carte d'entreprise et un scan de passeport, la paire est exactement aussi identifiable que son maillon le plus faible. Le guide pilier sur l'hébergement VPS anonyme détaille les trois couches — inscription, paiement, réseau — qui s'appliquent à une cible de sauvegarde tout aussi littéralement qu'à un serveur web.

Notes de terrain · Six pièges

Six façons dont une sauvegarde s'avère ne pas en être une. Toutes découvertes le jour où ça tourne mal.

Piège 01 · Irréversible

La phrase de passe n'existait que sur la machine morte

Le dépôt est intact, chiffré, et définitivement illisible. Conservez la phrase de passe — et, pour Borg, la clé exportée — dans un gestionnaire de mots de passe et sur papier, avant le premier snapshot.

Piège 02 · Cohérence

La base de données se restaure, puis échoue à la première requête

Les fichiers de données actifs ont été copiés au lieu d'être dumpés. Écrivez un dump dans une étape de pré-sauvegarde et sauvegardez ce dump ; ne pointez jamais la liste d'inclusion vers le répertoire de données d'un moteur en cours d'exécution.

Piège 03 · Rayon d'impact

L'intrus a d'abord supprimé les sauvegardes

Un identifiant en écriture sur une machine compromise est un identifiant en écriture pour l'attaquant. Forcez l'append-only sur la destination, ou récupérez la seconde copie en pull plutôt qu'en push.

Piège 04 · Capacité

Le dépôt est plus volumineux que le serveur

forget sans prune ne fait que marquer les snapshots, sans rien libérer. Exécutez-les ensemble, gardez de l'espace libre sur la destination, et ne sauvegardez jamais les images de conteneurs ni node_modules.

Piège 05 · Silence

Le dernier snapshot valide date de cinq mois

Le timer a échoué après une mise à niveau et rien ne l'a signalé. Ajoutez une unité OnFailure=, et vérifiez le haut de la liste des snapshots une fois par mois — cela prend dix secondes.

Piège 06 · Périmètre

Tout a été restauré, sauf ce seul répertoire

Un montage lié en dehors de /opt, un volume déplacé lors d'une migration, un motif d'exclusion qui a couvert plus que prévu. Listez un chemin connu à chaque nouveau snapshot, et relisez le fichier d'inclusion après tout changement apporté à la stack.

FAQ · Sauvegarde VPS

Questions, réponses.

Dix questions qui se posent pendant la mise en place — et deux qui ne se posent qu'après coup, une seule fois.

Un snapshot du prestataire est-il une sauvegarde ?

Non — c'est un rollback, et un rollback utile, mais il échoue précisément aux moments pour lesquels une sauvegarde existe. Un snapshot vit dans le même compte prestataire que le serveur qu'il copie. Si le compte est suspendu, si un paiement est contesté, si un agent support supprime par erreur, ou si un attaquant obtient vos identifiants de panel, le snapshot part avec la machine. Il n'offre non plus rien de granulaire : impossible de récupérer un seul fichier supprimé d'hier, seulement de revenir en arrière sur le disque entier et de tout perdre depuis. Gardez les snapshots — c'est le moyen le plus rapide d'annuler une mauvaise mise à jour — mais ne les confondez pas avec une copie qui existe là où le problème d'origine ne peut pas l'atteindre. La règle de base : si un identifiant compromis peut détruire les deux copies, vous n'avez qu'une seule copie.

restic ou Borg : lequel choisir concrètement ?

Les deux chiffrent côté client, les deux dédupliquent au niveau du chunk, les deux sont matures, et les deux feront le travail. Choisissez restic si vous voulez un binaire statique unique, un dépôt qui peut vivre sur SFTP, un stockage objet compatible S3, un serveur REST ou tout ce que rclone peut atteindre, et rien du tout installé sur la destination. Choisissez Borg si la destination est une machine SSH que vous contrôlez, que vous voulez l'application append-only la plus stricte disponible sans stockage à verrouillage d'objet, et que vous appréciez sa compression légèrement plus serrée. Les différences pratiques qui tranchent : Borg a besoin de borg installé aux deux extrémités et ne parle que SSH ou un chemin local ; restic a besoin d'une passe de prune qui prend brièvement un verrou exclusif sur le dépôt. En cas d'indécision, utilisez restic — moins de pièces mobiles sur la destination vaut plus que n'importe quel benchmark.

De combien d'espace disque la machine de sauvegarde a-t-elle besoin ?

Partez de la taille de ce que vous sauvegardez réellement — pas de la taille du disque qui l'héberge. Une stack auto-hébergée typique représente quelques gigaoctets de base de données et de configuration, plus ce que les utilisateurs ont mis en ligne. La déduplication et la compression font alors leur travail : un snapshot quotidien d'un working set de 20 GB avec une politique de rétention de douze mois se situe généralement entre 40 et 80 GB de dépôt, car seuls les chunks modifiés sont jamais stockés deux fois. Un Sentinel ($3.90/mois, 120 GB de NVMe) couvre cela largement. Passez à un Garrison (240 GB, $7.90) quand plusieurs serveurs sauvegardent vers le même hôte de dépôt, et à un Bulwark (960 GB, $32.90) quand le working set atteint lui-même des centaines de gigaoctets. Dimensionnez pour le dépôt, puis doublez — un dépôt sans espace libre ne peut pas faire de prune, et un dépôt qui ne peut pas faire de prune ne fait que grossir.

Peut-on sauvegarder une base de données active en copiant ses fichiers ?

Vous pouvez les copier. Vous ne pourrez peut-être pas les restaurer. Une base de données qui écrit sur le disque pendant que vous la lisez vous livre un ensemble de fichiers issus de plusieurs instants différents, ce qui est la définition même d'une sauvegarde déchirée — elle se restaure en une base corrompue, ou pire, en une base qui s'ouvre normalement mais à qui il manque discrètement des lignes. La solution est un dump : pg_dump ou pg_dumpall pour PostgreSQL, mariadb-dump --single-transaction pour MariaDB et MySQL sur des tables InnoDB, et sqlite3 db .backup out.db ou VACUUM INTO pour SQLite. Écrivez le dump dans un fichier, puis sauvegardez ce fichier. Si la base est trop volumineuse pour un dump nocturne, les alternatives sont un snapshot du système de fichiers pris pendant que le moteur est brièvement figé, ou l'outil de sauvegarde physique propre au moteur — mais pour tout ce qu'un seul VPS fait tourner, un dump est la bonne solution, et c'est simple.

Que se passe-t-il si je perds la phrase de passe du dépôt de sauvegarde ?

Les sauvegardes sont perdues. restic comme Borg chiffrent côté client, et aucun des deux n'a de procédure de récupération, de clé maîtresse, ni de ticket de support capable de déverrouiller un dépôt pour vous. C'est justement le principe : l'hôte de destination — y compris un hôte qui n'est pas le vôtre — ne voit jamais votre contenu en clair. Cela signifie aussi que la phrase de passe est désormais une donnée qui vaut exactement autant que tout ce qu'elle protège, et qu'elle ne doit pas vivre uniquement sur la machine sauvegardée. Mettez-la dans votre gestionnaire de mots de passe, et gardez-en une copie sous forme physique. Pour Borg, exportez aussi la clé du dépôt avec borg key export et conservez-la à part ; en mode repokey, la clé vit à l'intérieur du dépôt, donc un dépôt devenu inaccessible emporte la clé avec lui.

Comment empêcher un serveur compromis de supprimer ses propres sauvegardes ?

Vous lui donnez un identifiant capable d'ajouter mais pas de supprimer. C'est la décision de conception la plus importante de tout l'exercice, car les rançongiciels modernes cherchent d'abord la configuration de sauvegarde et la traquent jusqu'à sa source. Trois façons d'y parvenir. Append-only sur SSH : dans l'authorized_keys de la destination, forcez la commande borg serve --append-only --restrict-to-path /srv/borg — la source peut écrire de nouvelles archives et ne peut pas supprimer les anciennes. Append-only sur REST : lancez le rest-server de restic avec --append-only et pointez le dépôt vers lui en HTTPS. Verrou d'objet : un bucket compatible S3 avec versioning et un verrou de rétention. Le SFTP simple ne vous offre rien de tout cela — une clé capable d'écrire dans un dépôt peut l'effacer — donc si le SFTP est votre transport, associez-le à une seconde copie de type pull prise côté destination, là où les identifiants qu'un attaquant a capturés sur la source ne peuvent pas l'atteindre.

À quelle fréquence faire tourner les sauvegardes, et combien de temps les conserver ?

Posez la question autrement : combien de travail êtes-vous prêt à refaire ? Ce chiffre est votre objectif de point de récupération, et c'est lui qui fixe l'intervalle. Un rythme quotidien convient à presque tous les services auto-hébergés — un serveur mail, un Nextcloud, un homeserver Matrix, un moteur de workflow. Un rythme horaire se justifie quand les données sont transactionnelles et que la ressaisie est impossible. Pour la rétention, le schéma qui résiste à l'épreuve du réel est --keep-daily 7 --keep-weekly 4 --keep-monthly 12 : une semaine d'annulation fine, un mois de points hebdomadaires, un an de points mensuels, pour environ 23 snapshots. La longue traîne compte plus qu'on ne le pense, car la défaillance qu'elle capture n'est pas un disque mort — c'est une corruption ou une suppression passée inaperçue pendant six semaines.

La seconde copie doit-elle vraiment se trouver dans un autre pays ?

Un bâtiment différent est le minimum technique ; une juridiction différente est la partie que la plupart des gens sautent, puis regrettent. Un incendie, une inondation ou une panne au niveau de la baie répondent à la seule distance. Ce que la distance ne résout pas, c'est le juridique ou le commercial : un compte suspendu par un prestataire, un litige de paiement, une notification de retrait qui atteint toutes les machines sous le même toit d'entreprise, une injonction signifiée à une seule société. Si les deux copies vivent chez le même prestataire, une seule lettre atteint les deux. Répartir la paire entre deux bastions nordiques — la machine de travail à Helsinki, le dépôt à Reykjavík, à 30 ms d'écart sur le backbone — ne coûte rien en latence et achète un second cadre juridique. Les données sont chiffrées avant de quitter la source dans tous les cas, donc la destination n'apprend rien en les hébergeant.

Combien de temps prend la première sauvegarde, et le chiffrement la ralentit-il ?

Le chiffrement n'est pas le goulot d'étranglement — les CPU modernes calculent l'AES plus vite qu'une liaison gigabit ne peut en transporter le résultat, et les deux outils utilisent l'accélération matérielle quand elle existe. Le goulot d'étranglement, c'est le premier envoi, parce que tout est nouveau : sur une liaison montante à 1 Gbps, un jeu de données de 20 Go prend quelques minutes au débit nominal, et bien plus longtemps si la destination est bridée ou si les fichiers sont nombreux et petits. Chaque exécution suivante ne transfère que les chunks modifiés, ce qui représente typiquement quelques dizaines de mégaoctets pour une stack classique et se termine en moins d'une minute. Si le premier envoi entre en concurrence avec une charge de production, limitez son débit — restic prend --limit-upload en KiB/s, Borg prend --upload-ratelimit — et lancez-le sous nice et ionice.

Faut-il vraiment tester ses restaurations ?

Oui, et la raison n'est pas la paranoïa — c'est que les pannes courantes sont silencieuses. Le timer qui a cessé de se déclencher après une mise à niveau de paquet. Le motif d'exclusion qui a discrètement avalé le répertoire des uploads. Le dump de base de données écrit vers un chemin que la sauvegarde n'a jamais couvert. Le dépôt qui échoue à son contrôle d'intégrité depuis des semaines, dans un journal que personne ne lit. Rien de tout cela ne s'annonce ; tout se découvre en quatre-vingt-dix secondes en restaurant un fichier et en le regardant. Faites une petite restauration chaque mois — récupérez un dump de base de données et un répertoire de données vers un chemin temporaire et comparez-les — et une reconstruction complète une fois par an, sur un VPS neuf, chronométrée. Le chiffre qui ressort de cette reconstruction est votre vrai temps de récupération, et ce n'est presque jamais celui que vous auriez deviné.

Obtenez la seconde machine

Un bastion de dépôt dans une seconde juridiction nordique. Sans KYC, payé en crypto.

Sentinel — 120 GB de NVMe pour $3.90 par mois, à Helsinki, Stockholm, Oslo ou Reykjavík. Bande passante illimitée, donc restaurer ne coûte rien. Aucun e-mail à l'inscription, aucune pièce d'identité, et une destination incapable de lire le moindre octet de ce qu'elle héberge.

Dernière révision · 2026-08-24 · Références · Documentation de restic et BorgBackup, manuels de sauvegarde PostgreSQL et MariaDB, sshd authorized_keys(5), systemd.timer(5) · Fréquence · annuellement