Le chiffrement ZFS est l’une de ces rares fonctionnalités qui améliorent réellement la vie d’un ingénieur stockage : les données sont chiffrées sur disque, les clés sont gérées au niveau du dataset, et la réplication peut s’effectuer sans transformer votre site DR en service d’entiercement des clés. L’astuce derrière cette dernière partie est le raw send : une manière de répliquer les octets chiffrés tels quels, afin que la destination puisse stocker et servir le dataset sans jamais apprendre les clés de chiffrement.
Ce n’est pas une histoire théorique de « livre blanc » sur la sécurité. Le raw send est la façon dont vous construisez des sauvegardes multisite sensées lorsque des contraintes légales, de conformité ou le simple bon sens exigent « le fournisseur de sauvegarde ne doit pas avoir les clés ». C’est aussi la manière d’éviter l’erreur classique qui consiste à déchiffrer à la source juste pour envoyer du texte clair vers un endroit « sûr ». Spoiler : un endroit « sûr » finit par devenir « un endroit avec un laptop admin compromis ».
Ce qu’est réellement le raw send (et ce que ce n’est pas)
Soyons précis, parce que les discussions sur la réplication ZFS tendent à se résumer en déclarations vagues du type « c’est chiffré, donc c’est sûr ». Le raw send n’est pas « utilisez ssh et appelez ça chiffré ». Le raw send n’est pas « envoyez un dataset qui est chiffré par hasard ». Le raw send est un mode d’envoi ZFS spécifique où le flux de send contient les blocs et métadonnées chiffrés tels qu’ils sont sur disque, plutôt que ZFS les déchiffre pour le flux.
En termes pratiques :
- Envoi normal d’un dataset chiffré produit généralement un flux de données déchiffrées (sauf si vous dites à ZFS le contraire). Le récepteur reconstruit le contenu du dataset, mais le flux lui‑même n’est pas le texte chiffré qui vivait sur disque.
- Raw send produit un flux qui conserve le dataset chiffré de bout en bout tel que ZFS le stocke. Le récepteur stocke le dataset chiffré et peut le répliquer davantage, prendre des snapshots, etc. — sans pouvoir le monter/le lire à moins qu’une clé ne soit ensuite fournie.
Résumé en une phrase : le raw send réplique le texte chiffré et le contexte de chiffrement, pas le texte en clair.
Deux conséquences opérationnelles qui comptent :
- Avec le raw send, votre site DR peut être un « coffre-dumb » pour les datasets chiffrés. Vous pouvez confier le stockage et la réplication sans remettre les clés.
- Avec le raw send, le côté récepteur peut toujours effectuer des opérations ZFS (snapshots, holds, réplication supplémentaire), mais il ne peut pas « réparer » vos données en les rendant lisibles si vous perdez les clés. Le chiffrement est un excellent professeur : il note sévèrement.
Blague #1 (courte et pertinente) : Le chiffrement, c’est comme la ceinture de sécurité : ça semble contraignant jusqu’à ce que vous voyiez quelqu’un essayer de « simplement tenir bon » pendant un accident.
Faits & contexte historique
L’ingénierie du stockage est pleine d’énergie « on l’a inventé en 2005 et on l’explique encore en 2025 ». Voici quelques faits concrets et éléments de contexte qui font sens du raw send :
- Le send/receive ZFS a précédé le chiffrement natif de ZFS. La réplication existait bien avant que le chiffrement ne fasse partie du design principal, il a donc fallu étendre le modèle de réplication avec soin sans casser les hypothèses existantes.
- Le chiffrement ZFS est natif au dataset et au niveau bloc. Ce n’est pas une histoire de filesystem sur LUKS. ZFS chiffre des blocs et stocke des métadonnées de chiffrement avec le dataset, ce qui permet des clés par dataset et la rotation des clés.
- Le raw send existe parce que « dataset chiffré » n’implique pas automatiquement « flux de réplication chiffré ». Sans le mode raw, ZFS peut envoyer une représentation logique du dataset qui est effectivement du texte clair dans le flux.
- Les snapshots sont l’unité de réplication. ZFS send n’est pas « synchroniser le dossier ». C’est « envoyer la différence entre deux points dans le temps ». Voilà pourquoi votre politique de snapshots est votre politique de réplication.
- Les tokens de reprise ont changé la donne opérationnelle. Sur des liaisons instables, « recommencer » était souvent le comportement par défaut. Les tokens de reprise permettent de continuer un receive sans renvoyer tout le stream.
- Le raw send préserve la racine de chiffrement et les propriétés. La frontière de chiffrement compte : les datasets peuvent hériter du chiffrement, mais le raw send a besoin du contexte complet de chiffrement pour rester cohérent entre sites.
- La déduplication et la compression ne sont pas des cadeaux gratuits. Surtout avec le chiffrement, les attentes sur l’efficacité de la déduplication entrent souvent en collision avec la réalité (et les besoins en RAM).
- Les flux ZFS peuvent inclure des données embarquées, de grands blocs, et le comportement de recordsize. Si vous êtes habitué aux outils de niveau fichier, le moment « pourquoi c’est 3× plus volumineux » arrive vite quand recordsize, compression, et churn de snapshots interagissent.
Modèle de menace : ce que protège (et ne protège pas) le raw send
Le raw send est un outil de sécurité, pas une couverture totale. Utilisez-le pour résoudre le bon problème.
Ce que protège le raw send
- Les administrateurs de stockage à la destination ne peuvent pas lire les données sans les clés. Ils peuvent les répliquer, snapshotter, détruire ou les perdre — mais pas les parcourir.
- Les systèmes intermédiaires ne peuvent pas lire le contenu du flux si le flux raw est transporté sur une infrastructure non fiable. (Ils peuvent toujours le falsifier, ce qui est une discussion différente.)
- Séparation des clés entre environnements. Vous pouvez garder les clés de production en production et tout de même maintenir des copies externes des datasets chiffrés.
Ce que ne protège pas le raw send
- L’intégrité à lui seul. Le raw send protège la confidentialité, pas l’authenticité. Les checksums ZFS aident à détecter la corruption, mais vous devez quand même penser à l’intégrité du transport, aux erreurs disque et aux modifications malveillantes.
- La disponibilité. Si vous perdez les clés, votre site DR devient une vitrine intitulée « Blocs chiffrés, circa mardi dernier ».
- Les fuites de métadonnées au-delà de ce que le chiffrement couvre. Selon l’implémentation et les propriétés, certaines métadonnées (noms de dataset, noms de snapshot, tailles, horodatages) peuvent être observables via les propriétés ZFS et les logs opérationnels.
- Mauvaise hygiène des snapshots. Si vous snapshottez et répliquez des secrets que vous n’auriez pas dû conserver, le raw send enverra fidèlement votre erreur hors site.
Modèle mental : chiffrement et flux de send
Le modèle mental le plus utile est le suivant : ZFS a deux grandes façons de représenter un dataset pour la réplication.
- Représentation logique : « Voici les fichiers/blocs tels qu’ils doivent apparaître. » ZFS peut reconstruire cela et écrire les blocs sur le récepteur. C’est là que du texte clair peut apparaître dans le flux même si les données sur disque sont chiffrées — parce que ZFS décrit le contenu logique.
- Représentation raw : « Voici les blocs et métadonnées exacts sur disque. » Si le dataset est chiffré, ces blocs sont du texte chiffré. Le récepteur les stocke en tant que ciphertext. Aucune clé requise pour les stocker ; une clé requise pour les interpréter.
Le raw send interagit aussi avec le concept de racine de chiffrement. Dans ZFS, un dataset peut hériter du chiffrement d’un parent. La racine de chiffrement est l’endroit où les paramètres de chiffrement sont établis. Lorsque vous répliquez, vous devez préserver la frontière de chiffrement, sinon vous finirez avec une destination incapable de représenter correctement l’héritage des clés et des propriétés.
C’est là que les gens trébuchent : ils supposent que « dataset chiffré » implique « le récepteur pourra charger la clé et le monter ». Ça peut être vrai, mais c’est optionnel. Le raw send est explicitement conçu pour que le récepteur n’ait pas besoin des clés pour recevoir. S’il pourra plus tard monter dépendra de si vous chargez ensuite la clé côté destination et si les paramètres de chiffrement correspondent à ce que vous attendez.
Blague #2 (courte et pertinente) : En stockage, « ça a marché en staging » est juste une façon polie de dire « la production a plus d’entropie ».
Tâches pratiques : commandes à exécuter en production
Ci‑dessous se trouvent les vraies tâches que vous exécuterez en construisant et en exploitant une réplication raw send. Chaque tâche inclut les commandes et ce qu’il faut vérifier. Je pars du principe d’outils de type OpenZFS sur Linux, mais les concepts se traduisent vers d’autres plateformes avec de légères différences de flags.
Task 1: Confirm the dataset is encrypted and identify the encryption root
cr0x@source:~$ zfs get -H -o name,property,value encryption,keylocation,keystatus,encryptionroot tank/prod
tank/prod encryption aes-256-gcm
tank/prod keylocation prompt
tank/prod keystatus available
tank/prod encryptionroot tank/prod
Interprétation : Si encryption=off, le raw send n’encryptera rien magiquement. Si encryptionroot est un dataset parent, soyez conscient que vous pourriez répliquer un arbre où les enfants héritent des clés.
Task 2: Create a replication snapshot with a naming convention that won’t hurt later
cr0x@source:~$ zfs snapshot -r tank/prod@rep-2025-12-25T0200Z
cr0x@source:~$ zfs list -t snapshot -o name,used,creation -r tank/prod | tail -5
tank/prod@rep-2025-12-25T0200Z 0B Thu Dec 25 02:00 2025
tank/prod/db@rep-2025-12-25T0200Z 0B Thu Dec 25 02:00 2025
tank/prod/app@rep-2025-12-25T0200Z 0B Thu Dec 25 02:00 2025
Interprétation : Les noms de snapshot deviennent des poignées opérationnelles. Si votre convention de nommage est incohérente, vos scripts de réplication incrémentale deviendront hantés.
Task 3: Do a full raw send into a new destination dataset (unmounted)
cr0x@source:~$ zfs send -w -R tank/prod@rep-2025-12-25T0200Z | ssh cr0x@dest "zfs receive -uF backup/prod"
cr0x@dest:~$ zfs list -o name,used,avail,keystatus,mounted backup/prod
NAME USED AVAIL KEYSTATUS MOUNTED
backup/prod 112G 38.2T unavailable no
Interprétation : -w est le switch raw send. -R réplique le dataset et ses descendants ainsi que les propriétés. Sur le récepteur, -u le laisse démonté (bonne pratique quand les clés sont absentes). Voir keystatus=unavailable à la destination est le but : le dataset chiffré a été reçu sans clés.
Task 4: Verify you actually received an encrypted dataset (not plaintext)
cr0x@dest:~$ zfs get -H -o name,property,value encryption,keystatus,encryptionroot backup/prod
backup/prod encryption aes-256-gcm
backup/prod keystatus unavailable
backup/prod encryptionroot backup/prod
Interprétation : Si encryption est off ici, vous n’avez pas fait ce que vous croyiez avoir fait. Arrêtez et enquêtez avant de répliquer davantage.
Task 5: Perform an incremental raw send (the workhorse)
cr0x@source:~$ zfs snapshot -r tank/prod@rep-2025-12-25T0300Z
cr0x@source:~$ zfs send -w -R -I tank/prod@rep-2025-12-25T0200Z tank/prod@rep-2025-12-25T0300Z | ssh cr0x@dest "zfs receive -uF backup/prod"
cr0x@dest:~$ zfs list -t snapshot -o name,creation -r backup/prod | tail -3
backup/prod@rep-2025-12-25T0200Z Thu Dec 25 02:00 2025
backup/prod@rep-2025-12-25T0300Z Thu Dec 25 03:00 2025
Interprétation : -I envoie tous les snapshots intermédiaires entre deux points (utile si vous avez pu en sauter certains). Si votre graphe de snapshots est propre, -i est plus serré. Pour la simplicité opérationnelle, -I gagne souvent.
Task 6: Estimate send size before you saturate a link (or a change window)
cr0x@source:~$ zfs send -nP -w -R -I tank/prod@rep-2025-12-25T0200Z tank/prod@rep-2025-12-25T0300Z
size 21474836480
incremental size 21474836480
Interprétation : -nP est un dry run avec sortie parsable. Ce « size » est votre numéro de planification. Si c’est beaucoup plus grand que prévu, vous avez probablement du churn de snapshots, un mismatch de recordsize, ou une appli qui « réécrit tout le fichier chaque minute ».
Task 7: Receive into a safe holding area using -u and verify nothing auto-mounts
cr0x@dest:~$ zfs receive -uF backup/prod < /dev/null
cannot receive: failed to read from stream
Interprétation : La commande échoue car il n’y a pas de flux, mais le point est culturel : incluez toujours -u dans l’automatisation pour des copies DR chiffrées sauf si vous exécutez explicitement un warm standby avec les clés chargées.
Task 8: Use resume tokens to survive flaky links
cr0x@dest:~$ zfs get -H -o value receive_resume_token backup/prod
1-8f9c2f1d7c-100000-7890abcdef-200000-10
Interprétation : Si un receive a été interrompu, cette propriété peut contenir un token. Ce n’est pas un trophée ; c’est votre bouée de sauvetage.
cr0x@source:~$ ssh cr0x@dest "zfs get -H -o value receive_resume_token backup/prod"
1-8f9c2f1d7c-100000-7890abcdef-200000-10
cr0x@source:~$ zfs send -w -t 1-8f9c2f1d7c-100000-7890abcdef-200000-10 | ssh cr0x@dest "zfs receive -uF backup/prod"
Interprétation : zfs send -t reprend depuis le token. Ça peut vous sauver des heures (et votre relation avec l’équipe réseau).
Task 9: Confirm the destination can’t mount without keys (expected behavior)
cr0x@dest:~$ zfs mount backup/prod
cannot mount 'backup/prod': encryption key not loaded
Interprétation : C’est une condition de succès pour le « mode coffre ». Si vous vous attendiez à monter, vous avez besoin d’un plan de gestion des clés, pas d’un flag ZFS différent.
Task 10: Load a key on the destination (only when appropriate)
cr0x@dest:~$ zfs load-key backup/prod
Enter passphrase for 'backup/prod':
cr0x@dest:~$ zfs get -H -o value keystatus backup/prod
available
cr0x@dest:~$ zfs mount backup/prod
cr0x@dest:~$ zfs get -H -o value mounted backup/prod
yes
Interprétation : Vous avez maintenant franchi la ligne entre « DR stockage seulement » et « DR lisible ». C’est là que l’équipe audit commence à demander qui peut taper cette passphrase et où elle est stockée.
Task 11: Validate replication state by comparing snapshot lists
cr0x@source:~$ zfs list -t snapshot -o name -r tank/prod | grep '@rep-' | tail -5
tank/prod@rep-2025-12-25T0200Z
tank/prod@rep-2025-12-25T0300Z
tank/prod@rep-2025-12-25T0400Z
tank/prod@rep-2025-12-25T0500Z
tank/prod@rep-2025-12-25T0600Z
cr0x@dest:~$ zfs list -t snapshot -o name -r backup/prod | grep '@rep-' | tail -5
backup/prod@rep-2025-12-25T0200Z
backup/prod@rep-2025-12-25T0300Z
backup/prod@rep-2025-12-25T0400Z
backup/prod@rep-2025-12-25T0500Z
backup/prod@rep-2025-12-25T0600Z
Interprétation : La correction de la réplication commence par « avons‑nous les mêmes endpoints de snapshots ? » Ne compliquez pas trop.
Task 12: Use holds to prevent snapshot deletion mid-replication
cr0x@source:~$ zfs hold -r keepforrep tank/prod@rep-2025-12-25T0600Z
cr0x@source:~$ zfs holds -r tank/prod@rep-2025-12-25T0600Z | head
NAME TAG TIMESTAMP
tank/prod@rep-2025-12-25T0600Z keepforrep Thu Dec 25 06:01 2025
Interprétation : Les holds sont sous-estimés. Ils empêchent les jobs de nettoyage bien intentionnés de supprimer le snapshot dont dépend votre chaîne incrémentale.
Task 13: Check send/receive throughput and identify where time goes
cr0x@source:~$ zpool iostat -v 2
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 9.21T 5.32T 210 980 185M 612M
raidz2-0 9.21T 5.32T 210 980 185M 612M
sda - - 26 120 23.1M 76.4M
sdb - - 25 122 22.9M 77.1M
...
Interprétation : Si la bande passante écriture disque est élevée mais que votre réseau est bas, vous pouvez être limité par le CPU (chiffrement/compression), le choix du cipher ssh, ou les écritures sync côté récepteur. Si la lecture disque est faible, l’envoi pourrait ne pas tirer autant que prévu (ou être bloqué ailleurs).
Task 14: Receive safely when destination already has data (force rollback with care)
cr0x@dest:~$ zfs receive -uF backup/prod
cannot receive: failed to read from stream
Interprétation : La partie importante est le flag : -F force un rollback du dataset destination vers le snapshot le plus récent qui correspond au flux. C’est puissant, et ça peut détruire des snapshots locaux plus récents. Utilisez‑le seulement quand la destination est strictement une cible de réplication, pas un endroit où l’on fait du travail local.
Task 15: Verify encryption key is not accidentally copied into automation
cr0x@dest:~$ zfs get -H -o name,property,value keylocation backup/prod
backup/prod keylocation none
Interprétation : Pour le « mode coffre », keylocation=none (ou une source non-auto) réduit la chance que les clés soient chargées silencieusement au reboot. Si votre environnement attend un auto-load, documentez‑le et auditez‑le.
Trois mini-récits du monde de l’entreprise
1) Incident causé par une mauvaise hypothèse : « dataset chiffré » équivaut à « réplication chiffrée »
Dans une grande organisation (du genre à trois systèmes de tickets et zéro calendrier partagé), une équipe a déplacé un dataset sensible sur le chiffrement ZFS et a proclamé victoire. La conformité aimait les mots « AES-256 », la direction aimait qu’on n’ait pas demandé de budget, et l’équipe stockage aimait ne pas avoir à apprendre aux développeurs la gestion des secrets.
Puis est venue la réplication DR. Quelqu’un a câblé rapidement zfs send et zfs receive, parce que l’ancien système de sauvegarde arrivait en fin de vie et que le fournisseur ne parlait plus que de devis de renouvellement. La réplication a marché, des snapshots sont apparus sur le site distant, et tout le monde est retourné à ses occupations.
Des mois plus tard, lors d’un audit sécurité, un auditeur a posé une question simple : « Les admins du site distant peuvent-ils lire les données répliquées ? » La réponse devait être « non ». Le test a donné « oui », et ce fut aussi embarrassant que vous l’imaginez — silencieux, professionnel, et avec beaucoup de notes prises.
Le postmortem n’a pas pointé de malveillance. C’était une hypothèse : l’équipe pensait que le chiffrement sur disque impliquait chiffrement en transit et dans le flux. Mais leur réplication envoyait un flux non‑raw, et le récepteur stockait un dataset qui pouvait être monté localement sans la frontière de chiffrement d’origine. Ils avaient construit un DR qui semblait correct dans la supervision mais violait l’exigence de sécurité fondamentale.
La correction fut simple : reconstruire la réplication en raw send, vérifier keystatus=unavailable à la destination, et rédiger un runbook forçant une décision explicite : « Construisons‑nous un coffre ou un warm standby ? » La leçon est celle qu’on réapprend toujours : dans ZFS, une propriété de dataset n’est pas une politique tant que vous ne l’avez pas testée bout‑à‑bout.
2) Optimisation qui a mal tourné : « activons la dédup pour les backups »
Autre lieu, autre bonne intention. Ils avaient des snapshots nocturnes d’images VM et de volumes de base de données. La réplication vers le site DR bouffait la bande passante et ils voulaient la réduire. Quelqu’un a proposé la dédup : « On a plein de blocs similaires ; la dédup ZFS va tout écraser. » L’idée sonnait plausible, et l’expression « écraser la bande passante » a une certaine musicalité.
Ils ont activé la dédup sur le pool de destination, en se disant que c’était « juste des backups ». Un temps, ils ont vu une amélioration de l’usage d’espace et des deltas légèrement plus petits. Puis le système a commencé à se sentir lent. Au début on a cru à du jitter réseau. Ensuite à de la latence disque. Finalement c’était tout : receives lents, snapshots lents, et des blocages occasionnels qui faisaient soupçonner la couche hyperviseur.
Le retour de bâton était prévisible rétrospectivement : la dédup nécessite de la mémoire pour la DDT (dedup table), et les blocs chiffrés raw ne dédupliquent pas comme les gens l’imaginent intuitivement. Le chiffrement tend à transformer « blocs plaintext similaires » en « blocs chiffrés à l’apparence aléatoire », donc le gain de dédup peut être minime tandis que le coût en DDT est réel. Ils avaient échangé de la bande passante contre de la complexité persistante et un nouveau mode de défaillance.
Ils ont annulé la dédup, accepté que la compression et une fréquence de snapshots raisonnable étaient de meilleurs outils, et ajouté une métrique : « coût de réplication par GB changé ». Morale : si une optimisation change le profil mémoire et métadonnées de votre stockage, vous n’avez pas optimisé — vous avez changé le système. Parfois c’est acceptable, mais ce n’est jamais gratuit.
3) Une pratique ennuyeuse mais correcte qui a sauvé la mise : holds sur snapshots et discipline de chaîne
Les incidents les plus héroïques sont souvent les moins glamour. Une équipe faisait des snapshots horaires et une réplication incrémentale raw vers un site distant. Ils avaient aussi une règle douloureusement ennuyeuse : les snapshots de réplication recevaient un tag hold, et les jobs de nettoyage étaient interdits de supprimer les snapshots retenus. Ce n’était pas intelligent. Ça n’impressionnait personne en réunion d’architecture. C’était juste… une politique.
Puis un changement est arrivé : une équipe applicative a déployé une nouvelle build qui a généré un churn massif — réécrivant de gros fichiers au lieu d’append. Les deltas de réplication ont explosé, la liaison a saturé, et la job de réplication a pris du retard. Pendant ce temps, le job de nettoyage sur la source supprimait d’anciens snapshots parce que « on ne conserve que 48 heures ».
Sauf qu’il ne pouvait pas supprimer les snapshots d’ancrage de réplication, car ils étaient retenus. Cela signifiait que la chaîne incrémentale est restée intacte pendant que l’équipe opérations ralentissait les charges, ajustait la fréquence des snapshots, et laissait le temps à la réplication de se rattraper. Sans les holds, ils auraient perdu le snapshot de base en plein processus et auraient dû faire un resync complet au pire moment.
Quand la fumée s’est dissipée, le postmortem n’a pointé aucun coupable. Le système de réplication a survécu grâce à une pratique dont personne ne voulait parler : conventions de nommage, holds, et refus d’être malin. En production, l’ennuyeux est une fonctionnalité.
Guide de diagnostic rapide
Quand la réplication raw send est lente, échoue, ou se comporte étrangement, vous n’avez pas besoin d’une checklist de 40 étapes. Vous avez besoin d’un entonnoir rapide qui identifie la catégorie de goulot : CPU, disque, réseau, ou sémantique ZFS (snapshots/streams/propriétés). Voici le playbook que j’utilise avant de laisser quelqu’un « tuner » quoi que ce soit.
First: confirm what you’re actually doing (raw vs non-raw, full vs incremental)
cr0x@source:~$ zfs send -nP -w -R -I tank/prod@rep-2025-12-25T0200Z tank/prod@rep-2025-12-25T0300Z
size 21474836480
incremental size 21474836480
Regardez : si la taille est bien plus grande que prévu, le « goulot » est souvent « vous envoyez plus que vous ne pensez » à cause du churn ou du choix de snapshots.
Second: check receiver-side constraints (space, readonly, incompatible dataset state)
cr0x@dest:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
backup 40T 28.1T 11.9T - - 21% 70% 1.00x ONLINE -
cr0x@dest:~$ zfs get -H -o name,property,value readonly,available,receive_resume_token backup/prod
backup/prod readonly off
backup/prod available 11.2T
backup/prod receive_resume_token -
Regardez : peu d’espace libre, readonly=on, ou un token de reprise qui indique des interruptions répétées.
Third: decide whether the bottleneck is disk, CPU, or network
Disque :
cr0x@source:~$ zpool iostat -v 2
cr0x@dest:~$ zpool iostat -v 2
Regardez : latence élevée (await) sur les plateformes qui l’affichent, saturation d’un vdev, ou écritures réceptrices à fond alors que le CPU est inactif.
CPU / crypto :
cr0x@source:~$ top -b -n 1 | head -20
cr0x@dest:~$ top -b -n 1 | head -20
Regardez : un cœur saturé par ssh ou par le crypto noyau, indiquant le choix du cipher ou l’absence d’accélération matérielle.
Réseau :
cr0x@source:~$ ip -s link show dev eth0
cr0x@dest:~$ ip -s link show dev eth0
Regardez : erreurs/paquets perdus. Si le lien est propre mais le débit faible, suspectez une étape mono‑thread (cipher ssh, buffer userland, ou comportement sync du récepteur).
Fourth: inspect ZFS receive behavior and stream compatibility
cr0x@dest:~$ zfs events -v | tail -30
Regardez : événements sur failed receives, erreurs de checksum, ou défauts au niveau du pool qui rendent la réplication « lente » parce qu’elle réessaie constamment.
Erreurs courantes, symptômes, corrections
Mistake 1: Forgetting raw mode and assuming encryption carries over
Symptôme : le dataset destination est montable/lisible sans chargement de la clé attendue ; ou encryption=off à la destination.
Correction : reconstruisez la réplication en raw send et vérifiez à la destination :
cr0x@source:~$ zfs send -w -R tank/prod@rep-2025-12-25T0200Z | ssh cr0x@dest "zfs receive -uF backup/prod"
cr0x@dest:~$ zfs get -H -o name,property,value encryption,keystatus backup/prod
backup/prod encryption aes-256-gcm
backup/prod keystatus unavailable
Mistake 2: Breaking incremental chains by deleting snapshots
Symptôme : cannot send '...': incremental source ... does not exist ou le récepteur refuse le flux à cause d’une base manquante.
Correction : ajoutez des holds aux snapshots d’ancrage et ne supprimez les snapshots qu’une fois leur réplication confirmée.
cr0x@source:~$ zfs hold -r keepforrep tank/prod@rep-2025-12-25T0600Z
cr0x@source:~$ zfs release -r keepforrep tank/prod@rep-2025-12-25T0200Z
Mistake 3: Using -F blindly on a target that isn’t “replication-only”
Symptôme : perte « mystérieuse » de snapshots locaux ou de changements locaux sur la destination après une réplication.
Correction : séparez les datasets : un strict pour la réplication, un pour l’usage local. Ou retirez -F et gérez explicitement les divergences.
Mistake 4: Letting the destination auto-mount encrypted datasets
Symptôme : montages inattendus au boot, clés chargées « d’une manière ou d’une autre », augmentation du rayon d’impact d’un compte admin DR compromis.
Correction : recevoir avec -u, définir un keylocation contrôlé, et auditer les procédures de chargement des clés.
cr0x@dest:~$ zfs set canmount=off backup/prod
cr0x@dest:~$ zfs get -H -o name,property,value canmount,mounted backup/prod
backup/prod canmount off
backup/prod mounted no
Mistake 5: Confusing “encrypted transport” with “raw send confidentiality”
Symptôme : la revue sécurité signale que les backups sont déchiffrables à la destination, ou que des systèmes intermédiaires pourraient voir du texte clair.
Correction : traitez ssh/TLS comme protection du transport ; traitez le raw send comme protection du format de données. Utilisez les deux pour une défense en profondeur.
Mistake 6: Performance “tuning” by adding layers (and latency)
Symptôme : réplication plus lente après l’introduction d’une compression supplémentaire, d’un chiffrement supplémentaire, ou de buffers lourds.
Correction : mesurez chaque étape ; simplifiez le pipeline ; confirmez l’équilibre CPU/disque. Si vous ajoutez un outil, justifiez‑le par des métriques.
Checklists / plan pas à pas
Plan A: Build a vault-style DR replica (destination cannot read data)
- Sur la source, confirmez que le chiffrement est activé et notez la racine de chiffrement.
- Créez un snapshot récursif de réplication avec une convention de nommage stable.
- Faites un dry-run pour estimer la taille de l’envoi initial.
- Effectuez un full raw send avec
-w -R. - Recevez avec
-uet envisagezcanmount=offsur la destination. - Vérifiez
keystatus=unavailableà la destination et que le dataset reste démonté. - Automatisez des envois incrémentaux raw horaires/quotidiens avec des holds sur les snapshots.
- Définissez des règles de purge qui respectent les holds et vérifiez que les snapshots répliqués existent avant suppression.
Plan B: Build a warm standby (destination can mount with controlled keys)
- Faites tout ce qui figure dans le Plan A initialement.
- Définissez la gestion des clés : qui charge les clés, où vivent les passphrases, comment s’opèrent les audits.
- Testez le chargement manuel de clés et le montage lors d’une fenêtre de maintenance contrôlée.
- Décidez si les clés doivent se charger automatiquement au démarrage (la plupart des environnements devraient répondre « non » sauf raison opérationnelle forte).
- Faites un exercice de basculement : promouvez les services, vérifiez la cohérence applicative, mesurez le RTO.
Step-by-step: A minimal, reproducible replication loop
Voici la version « si vous êtes fatigué et qu’il est 02:00 ». Elle suppose une connectivité SSH et que la destination est une réplique stricte.
cr0x@source:~$ export SRC=tank/prod
cr0x@source:~$ export DST=backup/prod
cr0x@source:~$ export SNAP=rep-$(date -u +%Y-%m-%dT%H%MZ)
cr0x@source:~$ zfs snapshot -r ${SRC}@${SNAP}
cr0x@source:~$ zfs hold -r keepforrep ${SRC}@${SNAP}
cr0x@source:~$ LAST=$(zfs list -t snapshot -o name -s creation -r ${SRC} | grep '@rep-' | tail -2 | head -1)
cr0x@source:~$ CURR=${SRC}@${SNAP}
cr0x@source:~$ zfs send -nP -w -R -I ${LAST} ${CURR}
cr0x@source:~$ zfs send -w -R -I ${LAST} ${CURR} | ssh cr0x@dest "zfs receive -uF ${DST}"
Interprétation : Ceci crée un nouveau snapshot, le retient, trouve le précédent snapshot de réplication, estime la taille, puis envoie incrémentalement en mode raw. En automatisation réelle, vous gérerez le cas du « premier run » et la libération des holds quand c’est sûr.
FAQ
1) Does raw send mean I don’t need SSH encryption?
Non. Le raw send protège la confidentialité de la payload même si elle est interceptée, mais SSH reste important pour l’authentification, la protection contre la falsification en transit, et pour réduire le risque opérationnel. Utilisez le raw send pour « pas de clés sur la destination », et SSH pour « personne n’injecte des données dans mon receive ».
2) Can the destination replicate the encrypted dataset onward without keys?
Oui, c’est l’un des meilleurs aspects. La destination peut effectuer des raw sends du dataset chiffré vers une autre cible, agissant comme relais ou coffre secondaire, sans jamais charger les clés.
3) What does keystatus=unavailable actually mean?
Cela signifie que ZFS sait que le dataset est chiffré mais n’a pas la clé chargée. Le dataset peut exister, se répliquer et être géré, mais il ne peut pas être monté ou lu.
4) If I lose keys, can I restore from the raw replica?
Vous pouvez restaurer la structure du dataset et les snapshots, mais vous ne pouvez pas déchiffrer le contenu. La réplique raw n’est pas une solution de secours pour la perte des clés. Traitez les clés comme les bijoux de la couronne : sauvegardées, contrôlées en accès, et testées.
5) Why is my incremental send huge when only a little data changed?
Causes courantes : une application réécrit de gros fichiers au lieu d’appendre, une image VM subit beaucoup de churn de blocs, un mismatch de recordsize amplifie les changements, ou vous envoyez une plage de snapshots plus large que prévu (ex. -I incluant des snapshots intermédiaires avec plus de churn).
6) Can I change properties on the destination replica?
Oui, mais attention : la réplication avec -R tend à préserver les propriétés depuis la source, et des receives répétés peuvent rétablir les changements fait côté destination. Si vous avez besoin de propriétés différentes à la destination (mountpoints, quotas), planifiez‑le explicitement et testez l’interaction avec vos flags de receive.
7) What’s the difference between receiving with -u and setting canmount=off?
-u empêche le montage pendant l’opération de receive. canmount=off est une propriété persistante qui empêche le montage sauf changement. Pour des réplicas coffre, je fais souvent les deux : receive non monté et maintien par politique.
8) Should I use -i or -I for incrementals?
-i envoie d’un snapshot à un autre directement (plus serré, suppose des chaînes propres). -I inclut les snapshots intermédiaires entre les points (plus résilient aux envois manqués, parfois plus volumineux). En entreprise, avec des jobs manqués et de la planification humaine, -I est fréquemment le choix le plus sûr.
9) How do I know the destination is not accidentally getting keys?
Vérifiez keystatus et keylocation, et auditez qui peut exécuter zfs load-key. Inspectez aussi les unités/scripts de démarrage pour le chargement des clés. La promesse « les clés ne sont pas là » échoue le plus souvent à cause d’automatisations de commodité ajoutées plus tard.
10) Is raw send slower than normal send?
Ça dépend. Le raw send peut être efficace car il transfère des blocs stockés, mais le débit global dépend de tout le pipeline : lecture source, traitement zfs send, transport, écritures récepteur, et topologie du pool. Le prédicteur de performance le plus important est généralement le churn et les caractéristiques I/O, pas le flag raw lui‑même.
Conclusion
Le ZFS raw send est une de ces fonctionnalités qui permet discrètement une infrastructure mature : vous pouvez répliquer des datasets chiffrés vers des endroits qui ne doivent jamais voir les clés, construire des chaînes de backup multi‑sauts, et le faire avec une sémantique ZFS de premier ordre — snapshots, incrémentiels, et flux résumables.
La discipline opérationnelle est le vrai coût : hygiène des snapshots, intégrité des chaînes, frontières de gestion des clés, et vérification de ce que vous croyez répliquer. Faites ces choses correctement et le raw send est un cadeau. Faites‑les à la légère et vous ferez soit fuiter des données, soit vous découvrirez, au pire moment, que vos « sauvegardes » sont des poids‑papier cryptographiques.