Sous Linux, on parle d’entropie comme étant la quantité d’information permettant d’alimenter un générateur de nombres pseudo-aléatoires (PRNG).

L’entropie, c’est-ce que c’est ?

Description de l’entropie

L’entropie thermodynamique désigne la quantité de désordre d’un système physique : cette quantité augmente lorsque le système est soumis à une transformation irréversible. Qui dit transformation irréversible dit impossibilité de diminuer l’entropie d’un système.

Le terme entropie de Shannon est également employé en cryptographie, comme étant l’incertitude d’une source de données. Plus la variabilité des données est grande, moins on est capable d’en prédire la suite, et plus l’entropie de Shannon est grande. Ce terme possède quelques analogies avec la thermodynamique. Le noyau Linux utilise également le terme.

Pour différentes opérations, le noyau du système d’exploitation a besoin d’être capable de générer des nombres (ou des données) aléatoires. C’est un pilier fondamental de nombreux algorithmes de cryptographie comme GPG ou SSL par exemple.

Malheureusement, ces nombres aléatoires ne tombent pas du ciel, et le noyau est obligé de recourir à des astuces logicielles pour les produire. Le noyau utilise un amalgame de données variables (état des disques durs, IO, date, saisies clavier, périphériques, …) comme source d’instabilité, ou source d’entropie, de son générateur de nombres aléatoires. Le résultat final est une bonne approche logicielle de l’aléatoire, on parle de PRNG (pseudorandom number generator).

Cette entropie n’est pas illimitée, le noyau ne peut pas générer de grands volumes de données aléatoires sans être à court à un moment ou à un autre : le pool d’entropie se vide au fur et à mesure de son utilisation.

Comment afficher l’entropie ?

Pour interroger le noyau sur la quantité d’entropie qu’il a pu récolter depuis différentes éléments variants, il faut afficher le contenu de /proc/sys/kernel/random/entropy_avail.

Le nom de ce fichier signifie « entropie disponible », ce qui montre bien que la source d’entropie du noyau est stockée dans un pool (un réservoir) qui peut se vider si on puise trop fort dedans.

Voici la preuve en exemple en utilisant le périphérique de générateur aléatoire /dev/random .

On a fait diminuer l’entropie du noyau de 3183 à 98. Pour se donner une idée, si votre système tombe sous les 1000, il risque d’avoir des difficultés à générer des nombres aléatoires lorsque cela lui sera demandé. Il va donc attendre paisiblement jusqu’à ce qu’il collecte suffisamment d’entropie.

Qui consomme mon entropie ?

Si le chiffre affiché dans /proc/sys/kernel/random/entropy_avail diminue et tend vers zéro, vous êtes à court d’entropie.

Le périphérique /dev/random , le principal pourvoyeur d’aléatoire du système, va donc faire attendre tous les logiciels qui font appel à lui, le temps que le stock d’entropie se reconstitue. C’est le principal moyen utilisé par les logiciels pour faire débiter le générateur d’octets aléatoires. La plupart du temps, cela n’a aucune incidence sur la stabilité du système ni même sur ses performances, car le périphérique /dev/random  devrait normalement être utilisé dans très peu de cas où la sécurité cryptographique est vitale.

L’utilisation du périphérique /dev/urandom  restera possible quoi qu’il arrive de par sa nature non-bloquante. L’utilisation de ce périphérique consomme un peu d’entropie.

Le noyau lui-même consomme de l’entropie, car certaines opérations internes sont volontairement aléatoires dans la gestion des processus et du réseau.

Lors de la génération de clés GPG, SSL ou SSH, de l’entropie est consommée. On voit sur la sortie écran ci-dessous que la génération de clés GPG a été ralentie par le manque d’entropie, avec un message dans ce sens.

Le serveur SSH consomme également un peu d’entropie, et il peut souffrir de lenteurs lors de l’établissement de connexions si celle-ci vient à manquer.

Les machines virtuelles et l’entropie

Les machines virtuelles sont particulièrement susceptibles d’arriver à court d’entropie car elles tournent dans un environnements logiciel (l’hyperviseur) beaucoup trop pur par rapport à un environnement matériel « bare metal ». Sans avoir accès directement à un disque dur mécanique, une carte son, une saisie clavier, des mouvements de souris, la source d’entropie de la machine virtuelle se trouve très diminuée.

Par exemple, les blocages lors de la génération de clés GPG seront fréquents sur les machines virtuelles.

L’environnement de virtualisation KVM permet d’y relier avec le pilote virtio-rng qui permet de piper un périphérique de l’hôte vers la machine invitée. L’équivalent Xen de virtio-rng sous KVM est xentropyd (merci pTTy en commentaire).

Comment améliorer l’entropie du système ?

Les générateurs matériels de nombre aléatoires

La meilleure méthode pour aider un système d’exploitation à renouveler son entropie disponible, c’est de recourir à un générateur de nombres aléatoires de type matériel.

Il existe un excellent article Wikipédia sur les différents matériels disponibles sur le marché. Je vous propose le contenu de archive.org car Wikipédia a malheureusement supprimé l’article en Août 2018 sous prétexte que les catalogues de produits ne sont pas acceptés sur une encyclopédie en ligne. Pourtant certains matériels listés sont ouverts et potentiellement utiles.

Curieusement, ce type de produit reste très peu répandu. Sun Microsystems en produisait, sinon la plupart des produits plutôt amateurs et réalisés par des petites entreprises d’électronique. A se demander si l’offre du marché n’est pas régulée d’une manière ou d’une autre.

Clés USB les plus populaires

Selon moi, le dispositif BitBabbler est un des meilleurs disponibles, avec une construction électronique qui semble réputée, un matériel entièrement open-source et une capacité de produire entre 650 Kbit/s et 2,5 Mbit/s. Leur site était actif à la date de rédaction de cet article (2017) mais il est malheureusement hors-ligne en 2022.

On parle souvent sur les forums de Simtec et leur Entropy Key compatible Debian, mais leur produit n’est plus disponible à la vente depuis un petit moment.

Pour en citer d’autres : OneRNG, ChaosKey, TrueRNG, …

Toutes ces clés sont accessibles via le périphérique /dev/hwrng. Les noyaux Linux les plus récents (comme le 4.9 utilisé par Debian 9) utiliseront cette source d’entropie naturellement via le processus noyau [hwrng] . Pour les noyaux les moins récents (au moins jusqu’à la version 3.16 utilisée par Debian 8.6) on utilisera rng-tools pour alimenter /dev/random.

Rtl-sdr

Un hacking particulièrement intéressant à ce sujet, c’est de transformer une clé USB qui était à l’origine un tuner TNT basée sur le chipset rtl-sdr, pour générer des données aléatoires provenant du bruit électromagnétique ambiant (jusqu’à 2,8 Mbit/s). On peut s’en procurer une pour une somme modique, mais son inconvénient est de nécessiter une antenne. Il existe un article détaillé sur cette méthode que j’ai moi-même testée avec succès.

Le paquet rtl-entropy nous explique sur sa home page que l’on peut connecter une résistance de 75 ohms sur la prise antenne, et mettre l’ensemble dans une boite métallique qui fait office de cage de faraday. Cette méthode permet de mesurer un bruit thermique, qui est une source physique d’aléatoire d’excellente qualité, impossible à influencer par ondes radio. Il ne manque plus qu’à trouver un fablab qui pourrait vendre ces blindages, et on pourrait alors utiliser ce générateur USB professionnellement à l’intérieur d’un châssis de serveur.

En creusant, on se rend compte que le dispositif rtl-sdr n’égale pas un générateur aléatoire comme le BitBabbler. J’ai d’ailleurs consacré tout un article à ce sujet.

Raspberry pi et son bcm2708

Le Raspberry Pi fait mieux que la plupart de nos ordinateurs et serveurs : il a un chipset matériel qui génère des données aléatoires. Il faut croire que ses concepteurs se doutaient que certaines applications isolées, avec peu de stimuli externes, nécessiteraient une bonne source aléatoire. Voici un article pour l’exploiter.

Intel rdrand

Intel a ajouté à ces processeurs Ivy Bridge une instruction rdrand pour générer des nombres aléatoires. Les performances sont très importantes, jusqu’à 3 Gbit/s.

A l’époque en 2013 cela a provoqué de nombreux questionnements sur la fiabilité de cette instruction, et sa potentielle compromission par la NSA.

Le noyau Linux utilise cette instruction rdrand pour alimenter son générateur de nombres aléatoires, mais il continue à combiner plusieurs sources, ce qui garantit normalement que le noyau ne souffrira pas de failles dues à une seule de ces sources. A toutes les personnes réticentes, Linus Torvalds a exprimé à ce sujet « We actually know what we are doing. You don’t« . Ce sujet conflictuel a été la cause du départ du mainteneur du RNG Linux. Le bon sens nous pousse à croire que le mélange de différentes sources d’entropie est préférable, même si l’une d’entre elle est compromise. En réalité les sources d’entropie faibles sont dangereuses, même si utilisées parmi d’autres (source).

Il y aurait apparemment eu des pressions sur le noyau Linux pour utiliser rdrand comme seule et unique source d’entropie du noyau (source), ce qui serait mauvais du point de vue sécuritaire. Imaginons un scénario catastrophe dans lequel la NSA a imposé une backdoor dans rdrand, et que cette backdoor soit découverte par des personnes mal intentionnées, les dégâts seraient immenses. Edit Juin 2017 : j’ai rédigé ce scénario catastrophe en Mars 2017 et le mois qui a suivi, il s’est réalisé avec WannaCry, une faille découverte par la NSA et qui a été volée.

Pour plus d’information sur Rdrand, voir l’article de Ars Technica, la discussion sur Stack Exchange et les commentaires de Ycombinator.

Les assistances logicielles

haveged

Le paquet le plus connu pour alimenter le noyau en entropie et lui permettre de générer de l’aléatoire, c’est haveged. Son fonctionnement consiste à lire des états fugaces du processeur, qui devraient normalement être imprévisibles. Personne n’est en mesure de dire aujourd’hui si l’utilisation de haveged est sécurisée. La question fait débat mais le principe de précaution nous pousse à dire « non, pas trop ».

Ce qui est certain, c’est qu’il permet de générer des certificats SSL et GPG plus rapidement (exemple avec ce tutoriel).

Le principal risque lié à l’utilisation de haveged sur des machines virtuelles, c’est que les extensions du processeur sur lesquelles s’appuie haveged ne soient pas disponibles, ce qui pourrait conduire à générer une suite de zéro ou de un en lieu et place de données aléatoires. Ce serait la pire chose à faire pour la sécurité.

jitterentropy_rng

Depuis la version 4.2 du noyau Linux, un module est disponible : jitterentropy_rng. Il s’appuie sur la présence du timer haute résolution des processeurs modernes pour proposer une source aléatoire. Étant donné qu’il fait partie intégrante du noyau et que le développement de haveged semble en pause, c’est je pense une meilleure option que haveged. Voir plus d’information sur pthree.org.

Il semblerait néanmoins que le rythme de regénération de l’entropie soit inférieur avec jitterentropy_rng plutôt que haveged.

rng-tools

Le paquet rng-tools fournit le daemon rngd qui permet d’utiliser un périphérique matériel comme /dev/hwrng afin d’alimenter le noyau et /dev/random. Sur une machine physique, /dev/hwrng fait référence à un dispositif matériel comme ceux qui sont cités plus haut. Sur un hyperviseur comme KVM ou Xen, on peut utiliser virtio-rng qui permet à l’hyperviseur de donner accès à sa propre source d’aléatoire (matérielle ou logicielle).

On peut utiliser rngd pour injecter n’importe quel device ou FIFO dans /dev/random. Certains tutoriels conseillent d’utiliser /dev/urandom (exemple rngd -r /dev/urandom). Cela consiste à transformer urandom  en random  : à proscrire absolument car cela va à l’encontre de ce pourquoi ces devices ont été créés. Cela affaiblit énormément la qualité des nombres aléatoires produits, et fragilise les algorithmes cryptographiques qui reposent dessus.

De mon coté je l’utilise pour injecter le périphérique /dev/hwrng fourni à mes machines virtuelles KVM par le device virtio-rng dans /dev/random sur les noyaux les plus anciens (plus besoin avec Linux 4.2 et supérieurs).

Ecrire dans /dev/random

Cela n’a pas toujours été vrai dans les anciennes versions du noyau, mais on peut maintenant écrire dans /dev/random et le noyau utilisera les données envoyées pour alimenter son générateur de nombres aléatoires. Il vaut mieux savoir ce qu’on fait avant d’envoyer n’importe quoi.

random.org

Random-as-a-Service, c’est un peu la proposition de random.org. On interroge une API qui nous retourne des octets aléatoires grâce à un équipement matériel élaboré, un peu comme un serveur de temps basé sur une horloge atomique. Apparemment cet équipement est basé sur le bruit électromagnétique atmosphérique, c’est exactement ce que chacun peut faire chez soi avec rtl-sdr.

Pour tout ce qui a trait aux échanges chiffrés et la sécurité, je pense que c’est un non-sens d’utiliser random.org. Le risque d’interception des données est trop grand. C’est le générateur aléatoire local qui doit permettre de sécuriser des échanges, et non pas des échanges qui doivent sécuriser d’autres échanges voire un noyau complet.

Pour toutes les application non sécuritaires, pourquoi pas.

/dev/urandom ou /dev/random ?

La question se pose souvent dans la communauté, et pourtant la réponse est souvent la même : utilisez toujours /dev/urandom, même pour les applications de sécurité. D’un point de vue crypto, le niveau de qualité des deux périphériques est très proche, si bien qu’un n’existe aucune bonne raison d’utiliser /dev/random. Les développeurs de GPG et d’OpenSSL ont peut-être leurs raisons pour le faire, mais pas l’administrateur système lambda.

La différence entre ces deux périphériques, c’est que /dev/random est bloquant, c’est à dire qu’il va s’arrêter de délivrer des données si jamais le noyau vient à manquer d’entropie. A l’inverse, /dev/urandom est non-bloquant et le noyau fera ce qu’il faut à l’aide de fonctions de hachage pour continuer à débiter des octets.

Il existe un risque important à utiliser /dev/random, c’est de rendre l’application voire le serveur entier instable à cause d’un blocage de génération de données aléatoires. Une faille de sécurité béante qui pourrait être utilisée à mauvais escient. J’ai l’impression que lorsque /dev/random est utilisé, c’est pour des opérations rares, hors-ligne, et qui ont tout leur temps, comme la génération de certificats.

Regardez donc le fichier de configuration par défaut de mod_ssl, il n’est pas avare en explications.

Pour une discussion très détaillée sur ces deux périphériques, regardez la page « Myths about /dev/urandom« .

Conclusion

Connaître le fonctionnement du générateur de nombres pseudo-aléatoires est très intéressant, cela alimente la réflexion globale sur la sécurité du noyau et des échanges réseau.

Néanmoins, c’est à vouloir trop en faire à la va-vite qu’on risque d’altérer le comportement naturel du noyau et de commettre des bêtises. Pour un administrateur qui souhaite accélérer la génération des certificats, le réflexe c’est d’utiliser rngd à tort (en injectant urandom dans random) ou d’installer haveged à toutes les sauces. Il ne faut pas confondre le besoin pragmatique avec la théorie sous-jacente et les implications sécuritaires. Ce n’est pas parce que le chiffre d’entropie a miraculeusement augmenté que tous les moyens sont bons.

Il existe des suites logicielles supposées tester la qualité des nombres aléatoires comme rngtest et dieharder. Malheureusement, un test réussi ne signifie pas forcément que le système aléatoire est véritablement adapté à un usage sécuritaire. A vrai dire j’ai même pu lire que le nombre Pi pourrait bien passer certains tests.

Vous vous interrogez sur la meilleure source possible d’entropie pour votre usage ? C’est précisment le sujet de mon article Quel générateur RNG, et pour quel usage ?.