L'entropie au démarrage
- Accueil
- Éditoriaux
- L'entropie au démarrage
Éditorial
Les générateurs aléatoires des noyaux modernes ont largement réglé le manque d'entropie au démarrage d'une machine isolée. Le problème revient par les chemins de déploiement : images clonées, clés d'hôte figées dans un gabarit, graines copiées, instantanés restaurés, où ce n'est plus le hasard qui manque mais l'unicité.
Ce texte examine la production d’aléa au premier démarrage des machines virtuelles, des objets connectés et des conteneurs, et la manière dont les outils de déploiement la court-circuitent. Le comportement des noyaux, des outils d’initialisation et des images de distribution change d’une version à l’autre. Les éléments factuels datent de septembre 2026 ; le raisonnement devrait leur survivre.
Deux jumeaux qui lancent la même pièce exactement de la même façon, au même instant, obtiendront le même résultat. Ce texte montre que les ordinateurs fabriqués par copie courent ce risque au démarrage, alors que leurs secrets doivent justement être uniques et impossibles à deviner.
→ Lire l’explication complète de la marmotte
Le problème qu’on croyait réglé
Section intitulée « Le problème qu’on croyait réglé »Il y a des sujets qu’on range, avec un soupir de soulagement, dans le tiroir des problèmes résolus. On y retrouve pêle-mêle le bogue de l’an 2000, les disquettes de démarrage et le manque d’entropie au boot. Le premier a bien été réglé, les secondes ont disparu d’elles-mêmes. Le troisième a été réglé, lui aussi, mais seulement dans le cas où personne ne fait rien d’intelligent après.
Rappelons le problème historique. Un système qui démarre doit produire très tôt des valeurs imprévisibles : clés d’hôte SSH générées au premier lancement, graines pour les protocoles réseau, clés éphémères des premières connexions TLS. Pour cela, le noyau alimente un générateur cryptographique à partir de sources physiques : horodatages d’interruptions, mouvements de disque, activité réseau, instructions matérielles dédiées quand elles existent. Au tout début du démarrage, ces sources n’ont presque rien dit. Pendant longtemps, certaines interfaces renvoyaient quand même des octets, calculés à partir d’un état quasiment vide, et des logiciels pressés les consommaient sans demander leur reste.
Les noyaux modernes ont largement corrigé cela, comme on le verra. Les générateurs sont mieux conçus, les interfaces bloquent tant que l’état n’est pas initialisé, et le délai d’initialisation a fondu. Si l’on démarre une machine physique neuve, seule, avec un noyau récent, le risque d’obtenir une clé prévisible est devenu très faible.
Mais le monde ne démarre plus des machines neuves, seules. Il démarre des copies. Des machines virtuelles clonées depuis un gabarit, des objets connectés produits à cent mille exemplaires avec la même image, des conteneurs instanciés depuis une image construite une fois, des fonctions restaurées depuis un instantané mémoire pour gagner quelques centaines de millisecondes. Dans tous ces cas, la question n’est plus « le générateur a-t-il assez d’entropie ? » mais « le générateur de cette machine est-il distinct de celui de sa voisine ? ». Et le noyau, si parfait soit-il, n’a aucun moyen de le savoir quand on lui a menti sur son histoire.
Cet éditorial examine ce déplacement : comment un problème réglé en théorie revient par la chaîne de déploiement, où personne ne le cherche, parce que tout le monde le croit réglé.
Ce que le noyau a vraiment réglé
Section intitulée « Ce que le noyau a vraiment réglé »Il faut d’abord rendre justice aux développeurs de noyaux, qui ont fait un travail considérable et assez peu célébré, sans doute parce qu’un générateur aléatoire qui fonctionne ne produit rien de remarquable, par définition.
Sous Linux, l’appel système getrandom(), introduit il y a plus d’une décennie, bloque tant que le générateur n’est pas initialisé, puis ne bloque plus jamais. C’est exactement la sémantique dont les programmes ont besoin, et elle a mis fin à la querelle interminable entre /dev/random, qui bloquait trop, et /dev/urandom, qui ne bloquait pas assez. Les versions successives du noyau ont ensuite supprimé le blocage perpétuel de /dev/random après initialisation, rapproché les deux interfaces, remplacé la construction interne du générateur par une conception plus moderne, et introduit au démarrage une collecte d’entropie fondée sur la gigue d’exécution du processeur, qui permet d’initialiser le générateur en un temps raisonnable même sur une machine calme. Les détails, et le rôle des générateurs matériels intégrés aux processeurs, sont décrits dans le chapitre sur la production d’aléa.
Le résultat est qu’un programme qui utilise correctement getrandom() sur un noyau récent obtient, dans l’immense majorité des cas, des octets imprévisibles, et que le message qui annonce l’initialisation du générateur apparaît tôt dans le journal de démarrage.
Ce que « initialisé » veut dire
Section intitulée « Ce que « initialisé » veut dire »Il faut toutefois être précis sur ce que le noyau garantit, parce que toute la suite de l’éditorial se loge dans l’écart entre cette garantie et ce qu’on lui prête.
Le noyau garantit que son générateur a absorbé ce qu’il estime être suffisamment d’entropie, à partir des sources qu’il observe. Il ne garantit pas que cette entropie soit propre à cette machine. Si deux machines démarrent à partir du même état et observent des événements identiques, ou si l’état d’une machine est copié en mémoire vers une autre après l’initialisation, le noyau ne peut pas le détecter. Le générateur est une fonction déterministe de son état et de ses entrées : deux copies du même état, nourries des mêmes entrées, produisent la même suite, et chacune d’elles est parfaitement convaincue d’être unique.
C’est la vieille leçon qu’on oublie à chaque génération : un générateur pseudo-aléatoire cryptographique ne crée pas d’imprévisibilité, il la conserve et la distribue. Il la conserve admirablement bien. Il conserve aussi, avec la même application, l’absence d’imprévisibilité et la duplication.
Deux machines, un seul hasard
Section intitulée « Deux machines, un seul hasard »Le cas le plus pur est celui de la machine virtuelle clonée à chaud, ou restaurée depuis un instantané.
Supposons une machine virtuelle en fonctionnement depuis des heures, dont le générateur est largement initialisé. On en prend un instantané, mémoire comprise, puis on démarre deux instances à partir de cet instantané. Au moment de la reprise, les deux instances ont exactement le même état interne du générateur, au bit près. Les premiers octets qu’elles produiront seront identiques. Si l’une et l’autre établissent immédiatement une connexion TLS, elles tireront la même clé éphémère. Si une application génère un identifiant « unique », il ne le sera pas. Si une signature ECDSA est calculée avec un nonce tiré de ce générateur, deux signatures de messages différents avec le même nonce permettent de retrouver la clé privée, ce qui est la propriété la plus désagréable de ce schéma, et que le chapitre sur les courbes elliptiques détaille.
Les instances vont diverger, bien sûr : elles recevront des interruptions à des instants différents, des paquets réseau différents, et le noyau mélangera ces événements dans leur état. Mais la divergence n’est pas instantanée, et tout ce qui est tiré avant qu’elle soit suffisante est potentiellement partagé. Or ce qui est tiré juste après une reprise, c’est précisément ce qui intéresse : reconnexions, renouvellements de sessions, jetons régénérés.
La réponse des hyperviseurs
Section intitulée « La réponse des hyperviseurs »Le problème est connu, et il a reçu une réponse technique propre : certains hyperviseurs exposent à la machine invitée un identifiant de génération qui change à chaque fois que la machine est restaurée depuis un instantané ou clonée. Les noyaux récents savent lire cet identifiant et, lorsqu’il change, réinjecter de l’aléa neuf dans leur générateur. Les hyperviseurs exposent aussi, souvent, un périphérique virtuel qui transmet à l’invité de l’aléa provenant de l’hôte.
C’est une solution élégante, et elle a deux limites. La première est qu’elle n’agit qu’au niveau du noyau : les générateurs en espace utilisateur, que certaines bibliothèques et certains langages maintiennent pour des raisons de performance, ne sont pas prévenus, et continuent de produire la même suite dans les deux instances jusqu’à ce qu’ils se réensemencent d’eux-mêmes, ce qui peut prendre longtemps. La seconde est qu’elle suppose que l’hyperviseur expose l’identifiant, que l’invité ait le pilote, et que la chaîne entre les deux ne soit pas cassée par un outil de migration ou de sauvegarde qui restaure un état sans le signaler.
Un clone qui ne sait pas qu’il est un clone est un jumeau parfait, et la cryptographie n’a pas été conçue pour les jumeaux.
La clé dans l’image
Section intitulée « La clé dans l’image »Le cas précédent est subtil. Celui-ci ne l’est pas du tout, et c’est pour cela qu’il est beaucoup plus fréquent.
Une distribution Linux courante génère les clés d’hôte SSH au moment de l’installation du serveur SSH, ou au premier démarrage du service. Si l’on construit une image de référence (une « image dorée », comme on dit avec une emphase qui devrait mettre la puce à l’oreille) en installant le serveur SSH puis en figeant le disque, les clés d’hôte générées pendant la construction sont dans l’image. Toutes les machines instanciées à partir de cette image auront la même clé privée d’hôte.
Les conséquences sont précises. D’abord, la vérification de l’hôte par le client devient décorative : un client qui a mémorisé l’empreinte d’une machine l’acceptera pour toutes ses sœurs, et un attaquant qui a compromis l’une d’elles, ou qui a simplement téléchargé l’image, dispose de la clé privée de toutes. Il peut donc se faire passer pour n’importe laquelle, sans aucun avertissement côté client. Ensuite, la rotation devient un problème de parc : changer la clé d’une machine ne change pas celle des autres, et l’on ne sait plus très bien lesquelles ont hérité de quoi. Le chapitre sur la création et la vérification des clés rappelle pourquoi une clé doit naître là où elle servira.
Ce défaut a une particularité délicieuse : il ne dépend en rien de la qualité du générateur. La clé a été générée avec un aléa irréprochable, par un noyau moderne, sur la machine de construction. Elle est parfaitement imprévisible. Elle est simplement présente en autant d’exemplaires qu’il y a de machines. On a résolu le problème de l’entropie avec une rigueur admirable, puis on a photocopié le résultat.
Les outils savent, à condition qu’on s’en serve
Section intitulée « Les outils savent, à condition qu’on s’en serve »Les outils d’initialisation des images de nuage savent ce problème et y répondent par défaut : ils suppriment les clés d’hôte présentes dans l’image au premier démarrage de l’instance et en génèrent de nouvelles. Plusieurs distributions destinées aux ordinateurs monocartes régénèrent elles aussi les clés au premier démarrage. Les outils de généralisation d’images de systèmes non Linux ont une étape équivalente pour les identifiants de sécurité de la machine.
Le problème réapparaît donc surtout hors de ces chemins balisés : images construites à la main pour un hyperviseur local, gabarits de machines virtuelles clonés depuis une console d’administration, images d’appliances distribuées par un éditeur, disques dupliqués pour déployer rapidement un lot de postes. Chaque fois qu’une image est préparée sans passer par l’outil qui la « généralise », la clé reste, et personne ne s’en aperçoit, puisque tout fonctionne.
Le cas du conteneur, en pire
Section intitulée « Le cas du conteneur, en pire »Dans le monde des conteneurs, la même erreur prend une forme encore plus directe : une instruction de construction qui génère une clé ou un certificat. Un fichier de construction qui installe un serveur SSH dans l’image, ou qui génère un certificat auto-signé pour que le service TLS démarre, fige ce secret dans une couche de l’image. Cette couche est ensuite poussée dans un registre, tirée par chaque nœud, parfois publiée. La clé privée n’est plus seulement dupliquée sur toutes les instances ; elle est distribuée à quiconque peut lire l’image, c’est-à-dire, pour une image publique, à l’humanité entière.
Le réflexe correct est de générer ces secrets au démarrage du conteneur, ou mieux de les injecter depuis un gestionnaire de secrets, comme le décrit le chapitre sur l’exploitation des clés. Le réflexe courant est de les générer pendant la construction, parce que c’est plus simple et que le conteneur démarre plus vite. La simplicité est ici la complice habituelle de la catastrophe, et elle a un excellent alibi : ça marche.
Les graines figées
Section intitulée « Les graines figées »Entre la clé photocopiée et l’état mémoire dupliqué, il existe une catégorie intermédiaire, plus discrète : les graines persistées.
Pour accélérer l’initialisation du générateur au démarrage, les systèmes enregistrent à l’arrêt un fichier de graine, qu’ils relisent au démarrage suivant pour nourrir le générateur. C’est une excellente idée sur une machine physique : l’aléa accumulé pendant la dernière session sert à amorcer la suivante. Sous systemd, c’est le rôle d’un service dédié, décrit dans le chapitre sur systemd pour ce qui est de son fonctionnement général.
Sur une image clonée, l’idée devient ambiguë. Si le fichier de graine a été écrit pendant la construction de l’image, toutes les instances démarrent avec la même graine. Tout dépend alors de ce que le système en fait. S’il se contente de mélanger la graine dans l’état du générateur, sans la compter comme de l’entropie, elle est inoffensive : elle n’ajoute rien, mais ne retire rien, et le générateur attend d’avoir récolté son entropie propre avant de se déclarer prêt. S’il la crédite, c’est-à-dire qu’il la compte comme de l’entropie réelle et accélère d’autant la déclaration d’initialisation, alors toutes les instances se déclarent prêtes avec un état largement commun, et les premiers octets produits risquent de l’être aussi.
Les implémentations récentes ont pris conscience de cette ambiguïté et prennent des précautions pour ne pas créditer une graine dont elles ne peuvent pas garantir l’unicité, par exemple en tenant compte de l’identifiant de machine. La conséquence pratique est double. D’abord, un fichier de graine dans une image est rarement catastrophique sur un système récent, mais il est inutile et mieux vaut le retirer lors de la généralisation. Ensuite, l’identifiant de machine lui-même doit être unique, et un fichier /etc/machine-id recopié dans l’image annule les précautions qui s’appuient dessus. Les outils de préparation d’images le vident pour qu’il soit régénéré au premier démarrage ; les images préparées à la main l’oublient avec une régularité de métronome.
Les générateurs de l’espace utilisateur
Section intitulée « Les générateurs de l’espace utilisateur »Le même raisonnement s’applique, avec moins de filets, aux générateurs que les programmes maintiennent eux-mêmes. Une bibliothèque qui s’ensemence une fois au lancement puis dérive tout son aléa de cet état interne est exposée à deux duplications : celle du processus qui se dédouble (un programme qui crée des processus enfants après s’être ensemencé, sans réensemencer dans chaque enfant), et celle du processus figé dans un instantané. Les bibliothèques sérieuses ont appris, parfois à leurs dépens, à détecter le dédoublement et à réensemencer. Elles ne peuvent en général pas détecter une restauration d’instantané, faute de signal.
La règle qui en découle est simple, et elle a le mérite d’éviter la plupart de ces pièges : pour tout ce qui est cryptographique, demander l’aléa au noyau au moment où on en a besoin, plutôt que de le conserver dans un état applicatif. Le coût de l’appel système est négligeable devant le coût d’une clé partagée.
Les objets connectés, ou le démarrage perpétuel
Section intitulée « Les objets connectés, ou le démarrage perpétuel »Tout ce qui précède s’applique aux objets connectés, avec quelques circonstances aggravantes.
Un objet connecté démarre souvent dans un environnement pauvre en événements : pas de disque, pas de clavier, un réseau qui n’est pas encore configuré, parfois pas d’horloge temps réel, un processeur simple dont la gigue d’exécution est faible et régulière. Il génère ses clés au premier démarrage, ce qui est la bonne pratique, mais ce premier démarrage a lieu justement au moment où il a le moins d’entropie à disposition. Si le noyau est ancien, ce qui est la norme dans ce monde où les mises à jour sont une rumeur, le générateur peut répondre avant d’être initialisé. Si le processeur dispose d’un générateur matériel, il n’est pas toujours activé dans la configuration du noyau livrée par le fabricant. Et tous les exemplaires de l’objet démarrent avec la même image, dans des conditions semblables.
Le résultat a été mesuré, publiquement et spectaculairement. Des travaux académiques publiés en 2012 ont collecté à grande échelle les clés publiques TLS et SSH accessibles sur Internet et ont constaté qu’un nombre non négligeable d’équipements, essentiellement embarqués (routeurs, équipements réseau, boîtiers d’administration), partageaient des clés identiques, ou pire, des clés RSA partageant l’un de leurs deux facteurs premiers. Deux clés RSA qui partagent un facteur se cassent toutes les deux par un simple calcul de plus grand commun diviseur, sans aucune astuce, comme le rappelle le chapitre sur RSA. Le mécanisme identifié était exactement celui décrit ici : génération au premier démarrage, entropie insuffisante, états de générateur proches entre exemplaires.
Pour mémoire, un incident plus ancien et d’une autre nature montre à quel point la réduction de l’espace des clés passe inaperçue : en 2008, une modification malheureuse du paquet OpenSSL d’une distribution répandue avait réduit la source d’aléa à peu de chose, rendant les clés générées pendant plusieurs années énumérables. Tout fonctionnait. Les clés avaient la bonne taille, le bon format, et se comportaient parfaitement bien, sauf qu’il n’en existait qu’un petit nombre possible.
Le chapitre sur les réseaux personnels et l’IoT replace ces équipements dans leur contexte. Retenons ici que l’objet connecté est une machine qui vit perpétuellement son premier démarrage : il en a toutes les faiblesses, et on lui confie pourtant des clés qui dureront toute sa vie, laquelle excède souvent celle de son support logiciel.
La personnalisation en usine
Section intitulée « La personnalisation en usine »La réponse industrielle correcte consiste à ne pas faire générer la clé par l’objet dans ses pires conditions, mais à l’injecter, ou à la faire générer par un composant sécurisé qui dispose de sa propre source d’aléa, lors d’une étape de personnalisation en fin de production. Cela coûte une étape de fabrication, un processus de gestion de clés et une infrastructure. Cela explique qu’on ne le fasse pas toujours, et pourquoi le marché récompense si bien les fabricants qui ne le font pas : leurs objets sont moins chers, et les clés partagées n’apparaissent sur aucune fiche produit.
Conteneurs et fonctions : le clone comme modèle économique
Section intitulée « Conteneurs et fonctions : le clone comme modèle économique »Les conteneurs ordinaires sont, sur la question de l’aléa du noyau, plutôt rassurants. Ils partagent le noyau de l’hôte, donc son générateur, et un conteneur qui démarre sur un hôte en fonctionnement depuis longtemps dispose immédiatement d’un générateur initialisé et propre à cet hôte. Deux conteneurs issus de la même image, sur le même hôte, obtiennent des octets différents du noyau, puisqu’ils les demandent au même générateur à des moments différents. Le chapitre sur les conteneurs et Kubernetes décrit cette architecture de noyau partagé.
Le risque des conteneurs n’est donc pas l’entropie : c’est ce qui est figé dans l’image, comme on l’a vu. Clés générées à la construction, certificats auto-signés, graines applicatives, jetons « par défaut » posés dans un fichier de configuration pour que ça démarre.
Le cas des fonctions à démarrage rapide est plus intéressant, parce qu’il réunit tous les problèmes à la fois. Pour réduire le temps de démarrage à froid, certaines plateformes exécutent l’initialisation d’une fonction une fois, prennent un instantané de la micro-machine virtuelle ou du processus à ce stade, puis restaurent cet instantané pour chaque nouvelle instance. Le clonage n’est plus un accident de déploiement, c’est le modèle d’exécution. Tout ce qui a été tiré au hasard pendant l’initialisation (graines de générateurs applicatifs, identifiants, clés éphémères préparées à l’avance) est identique dans toutes les instances restaurées.
Les plateformes concernées documentent généralement cette contrainte, et fournissent des points d’accroche pour réensemencer après restauration. C’est honnête, et c’est à peu près tout ce qu’elles peuvent faire : elles ne peuvent pas savoir ce que le code applicatif a caché dans sa mémoire. Il appartient au développeur de lire cette documentation, ce qui, de toutes les hypothèses de sécurité, est sans doute la plus audacieuse.
Vérifier sans casser
Section intitulée « Vérifier sans casser »Le bon côté de ce problème est qu’il se vérifie facilement, en lecture seule, et que la vérification est bien plus instructive que tout ce qu’on pourrait écrire à son sujet.
Sur une machine
Section intitulée « Sur une machine »# Le générateur du noyau s'est-il déclaré initialisé, et quand ?journalctl -k -b | grep -i 'crng init'# (ou, sans journald : dmesg | grep -i 'crng init')
# Identifiant de machine : doit différer d'une instance à l'autrecat /etc/machine-id
# Empreintes des clés d'hôte SSHfor k in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -lf "$k"; done
# Date de dernière modification des clés d'hôte, à comparer à la date d'instanciationls -l --time-style=long-iso /etc/ssh/ssh_host_*_key.pubLa valeur de /proc/sys/kernel/random/entropy_avail, souvent citée dans les vieux tutoriels, est devenue peu informative sur les noyaux récents, qui ne l’utilisent plus de la même manière ; mieux vaut se fier au message d’initialisation et à son horodatage. Une clé d’hôte dont la date de modification est antérieure à la naissance de l’instance a très probablement été héritée de l’image : c’est l’indice le plus simple, à confirmer par la comparaison des empreintes entre instances.
Sur un parc
Section intitulée « Sur un parc »Le défaut étant par nature collectif, il se détecte mieux en comparant. Collecter les clés publiques d’hôte d’un ensemble de machines et chercher des doublons ne demande aucun accès privilégié :
# Collecte des clés d'hôte publiques d'une liste de machines (lecture seule)ssh-keyscan -f hotes.txt 2>/dev/null \ | awk '{print $2, $3}' | sort | uniq -c | sort -rn | awk '$1 > 1'Toute ligne affichée par cette commande est une clé partagée entre plusieurs hôtes. Il existe des cas où c’est voulu (un groupe de serveurs derrière une adresse unique, qui présentent délibérément la même identité), mais alors c’est documenté, et quelqu’un sait pourquoi. Si personne ne sait, ce n’est pas un choix, c’est un héritage.
Dans une image
Section intitulée « Dans une image »Enfin, on peut inspecter une image de conteneur sans l’exécuter en service, pour savoir si elle contient des clés privées :
# Lister les fichiers de clés présents dans une image (conteneur jetable, sans réseau)docker run --rm --network none --entrypoint sh image:etiquette \ -c 'ls -l /etc/ssh/ssh_host_* 2>/dev/null; find / -xdev -name "*.key" 2>/dev/null | head'L’image n’est ni modifiée ni poussée ; le conteneur est supprimé à la sortie. Si des clés apparaissent, la question n’est pas « faut-il les changer », mais « qui d’autre a tiré cette image ».
Régénérer les clés d’hôte d’une machine en service provoque un avertissement de changement d’identité chez tous les clients qui la connaissent, et peut casser des automatisations qui vérifient l’empreinte. C’est le comportement attendu, et c’est justement ce qui rend la chose délicate : l’opération doit être annoncée, les empreintes nouvelles diffusées par un canal de confiance, et les anciennes retirées des fichiers d’hôtes connus. Ne régénérez pas un parc entier par un script un vendredi soir, sauf à vouloir apprendre à vos utilisateurs à ignorer les avertissements, ce qui serait le pire résultat possible.
Le meilleur argument contre
Section intitulée « Le meilleur argument contre »On peut soutenir, avec des arguments solides, que cet éditorial dramatise un problème largement traité.
L’argument dit ceci : les chemins standards sont désormais corrects, et le risque résiduel est marginal au regard d’autres menaces. Les images de nuage officielles régénèrent les clés au premier démarrage. Les noyaux récents lisent l’identifiant de génération des hyperviseurs et se réensemencent. Les systèmes d’initialisation ne créditent plus les graines douteuses. Les bibliothèques cryptographiques sérieuses détectent le dédoublement des processus. Les conteneurs partagent le générateur d’un hôte bien initialisé. Chacun des mécanismes décrits a sa parade, et la parade est active par défaut dans les configurations récentes.
Quant aux conséquences, elles sont plus limitées qu’il n’y paraît. Une clé d’hôte SSH partagée entre les machines d’un même parc, toutes administrées par la même équipe, ne donne à un attaquant rien qu’il n’ait déjà s’il a compromis l’une d’elles au point d’en lire la clé privée : il est déjà dans la maison. Et une collision de clés éphémères entre deux clones pendant quelques millisecondes après restauration exige un attaquant capable d’observer les deux flux au bon moment, ce qui n’est pas le profil ordinaire.
Cet argument est juste sur le premier point : le chemin standard, suivi sans détour, est aujourd’hui correct. C’est une vraie réussite, et il faut le dire.
Il est plus fragile sur le second, pour une raison qui tient à la nature du défaut. Une clé partagée ne donne pas seulement à l’attaquant ce qu’il a déjà : elle lui donne toutes les autres, y compris celles de machines qu’il n’a pas compromises, dans d’autres réseaux, parfois chez d’autres clients quand l’image vient d’un éditeur. Et elle lui permet de se faire passer pour n’importe laquelle sans déclencher le seul signal que l’utilisateur aurait vu. Le défaut transforme une compromission locale en compromission de classe.
Surtout, l’argument suppose le chemin standard, et c’est précisément là que je ne le suis pas. Le problème n’apparaît jamais sur le chemin standard. Il apparaît dans l’image construite à la main par quelqu’un de pressé, dans le gabarit cloné depuis une console, dans l’appliance d’un éditeur, dans le fichier de construction de conteneur qui génère un certificat pour que « ça démarre », dans la plateforme de fonctions dont on n’a pas lu la documentation. La sécurité par défaut protège ceux qui restent sur les rails ; l’informatique réelle est faite de raccourcis.
Ce que je ne sais pas
Section intitulée « Ce que je ne sais pas »Je ne sais pas quelle proportion des images en circulation contient des clés d’hôte figées. Les travaux publics de 2012 ont mesuré un phénomène à l’échelle d’Internet ; je ne connais pas de mesure récente équivalente sur les images de machines virtuelles, d’appliances ou de conteneurs, et je me garderai d’en inventer une. Mon intuition est qu’elle a baissé grâce aux outils d’initialisation, et qu’elle n’est pas nulle.
Je ne connais pas le comportement exact de chaque combinaison d’hyperviseur, de noyau et d’outil de sauvegarde face à une restauration. Le mécanisme d’identifiant de génération existe ; savoir s’il est exposé, transmis et lu dans une configuration donnée relève de la vérification locale, pas d’une règle générale. Les documentations des hyperviseurs et des noyaux sont la source à consulter.
Je ne sais pas si les générateurs de l’espace utilisateur des langages et bibliothèques que vous utilisez gèrent correctement la restauration d’instantané. Certains le font, d’autres non, et cela change d’une version à l’autre. La seule réponse robuste est celle déjà donnée : demander l’aléa au noyau au moment de s’en servir.
Et je ne sais pas ce que les objets connectés d’aujourd’hui font réellement au premier démarrage. Les incidents documentés datent d’une génération de matériel antérieure ; les fabricants disent avoir progressé, et certains l’ont sans doute fait. Mais un objet dont le micrologiciel n’est pas inspectable ne permet pas de le vérifier, et je n’ai pas pour habitude de croire les fiches produit sur parole, défaut d’éducation que l’âge n’a pas corrigé.
Ce qui reste
Section intitulée « Ce qui reste »Le problème de l’entropie au démarrage a changé d’adresse sans changer de nature. Il ne loge plus guère dans le noyau, qui a fait son travail. Il loge dans la chaîne de déploiement, là où l’on fabrique des machines par copie.
Trois choses me semblent acquises. Que l’imprévisibilité et l’unicité sont deux propriétés distinctes : un générateur parfait recopié produit un hasard parfait en plusieurs exemplaires, et la cryptographie a besoin des deux. Que toute étape qui fige un état (image, gabarit, instantané, couche de conteneur) doit être suivie d’une étape qui le rend unique, et que cette seconde étape est celle qu’on oublie, parce que la première fonctionne sans elle. Et que la vérification est bon marché : quelques commandes en lecture seule suffisent à savoir si un parc partage des clés, ce qui rend l’ignorance sur ce point difficile à justifier.
Reste une ironie que je livre sans supplément. Nous avons passé des décennies à fabriquer des générateurs capables de produire de l’imprévisible à partir du bruit du monde, et nous avons en parallèle bâti une industrie entière dont le métier est de rendre les machines identiques, reproductibles, clonables à l’infini. Les deux projets ont réussi. Ils sont simplement incompatibles au premier démarrage, et c’est au premier démarrage qu’on génère les clés.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Une chaîne de déploiement qui fige un état sans le rendre unique fabrique des machines qui partagent leur identité sans le savoir. Une seule image téléchargée ou une seule instance compromise livre alors la clé privée de tout le parc, y compris celle de machines d’autres réseaux construites depuis la même image, et l’usurpation ne déclenche plus le seul avertissement que l’utilisateur aurait vu. Les journaux ne distinguent pas une connexion légitime d’une connexion usurpée, puisque les deux présentent la même empreinte. Et la découverte tardive coûte cher : régénérer les clés d’un parc entier déclenche des alertes de changement d’identité en série, qui apprennent à tout le monde à cliquer sur « continuer ».
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Pour fabriquer des clés secrètes, un ordinateur a besoin de nombres imprévisibles. Le cœur du système, appelé noyau, les produit avec un générateur qu’il nourrit de petits événements physiques : l’instant précis des signaux du matériel, l’activité du réseau, les variations de vitesse du processeur. Tant qu’il n’a pas récolté assez de ces événements, un système récent refuse de répondre, puis il fournit des nombres de bonne qualité. Ce générateur reste pourtant un calcul : à partir d’un même état de départ et des mêmes événements, il produit toujours la même suite. Le danger apparaît quand on fabrique des machines par copie. Si l’on copie une machine en marche, mémoire comprise, les deux copies repartent du même état et tirent les mêmes nombres jusqu’à ce que leurs événements divergent. Si l’on prépare une image de disque après y avoir généré des clés, toutes les machines créées à partir de cette image possèdent la même clé secrète, et un attaquant qui en obtient une peut se faire passer pour toutes les autres. Dans un conteneur, la clé figée dans l’image est même distribuée à quiconque télécharge l’image. Les objets connectés, qui génèrent leurs clés au premier démarrage avec très peu d’événements disponibles, ont déjà produit des clés identiques ou cassables. Les réponses consistent à régénérer les clés et l’identifiant de chaque machine à son premier démarrage, à demander les nombres au noyau au moment où on en a besoin, et à comparer les clés d’un parc pour repérer les doublons.
À lire aussi
- Ce qu'on gardeMesurer un corpus ne dit pas quoi en faire. Tout conserver et tout effacer sont deux manières de ne pas décider. Ce qui mérite d'être gardé est aussi ce qui expose le plus, et ce n'est pas une coïncidence.
- RNG matériel ou PRNG dans un HSMSécuriser la génération de nombres aléatoires dans un HSM, entre source matérielle, générateur pseudo-aléatoire, attaques et exploitation.
- Quantifier les fuites par théorie de l'informationThéorie de l'information appliquée aux fuites de données, aux canaux cachés et à leur quantification opérationnelle.
- Les secrets dans les dépôts GitDes clés d'API, des mots de passe et des jetons continuent de se retrouver dans les dépôts Git, dans l'historique, les forks, les fichiers d'exemple et les journaux d'intégration continue. Un secret poussé est un secret compromis : le supprimer ne répare rien, seule la rotation répare, et la seule prévention durable est de ne plus avoir de secret à fuir.
Pages voisines
La citent
- Authentification défi-réponse, rejeu, relais et attaque hors ligne
- Protéger une information en environnement hostile
- RNG matériel ou PRNG dans un HSM
L'entropie au démarrage
Elle cite
- Lien dans les deux sens :Créer, vérifier et utiliser les clés dès le départ
- Lien dans les deux sens :Produire de l’aléa utilisable en cryptographie
- Lien dans les deux sens :RSA : trappe, padding et usages restreints
- Conteneurs, Kubernetes, CNI et service mesh
- Courbes elliptiques : compacité, validation et pièges
- Écrire un Dockerfile durci avec condensé, multi-étapes et non root
- Exploiter les clés : rotation, KMS et secrets
- Protocole SSH, clés d'hôte, authentification et durcissement
- Réseaux personnels, IoT et objets contraints
: les deux pages se citent l’une l’autre.
