---
Title: Ameliorer l'entropie de votre serveur
Subtitle: : aka boostez votre openssl
date: 2017-12-08 11:04
Authors: Victor
Slug: ameliorer-l-entropie-de-votre-serveur
Category: Système
Tags: entropie, debian, centos
keywords: entropie, debian, centos
Status: published
---
[TOC]

# Gimme me more Entropy !
La génération de clef privée sécurisée se sert de l'entropie dont dispose votre serveur.  
Très grossièrement (pardon aux puristes), l'entropie représente la qualité de l'aléatoire du votre serveur, la prédictabilité des résultats de certaines commandes. Plus il y a d'entropie, plus vite et plus efficacement vous pouvez générer des clefs (entre autres).

Sur un serveur physique avec un CPU récent, l'entropie est en générale assez élevée. Sur des VM ou si votre CPU est trop basique, elle peut être très faible, et cela augmente de manière assez exponentielle le temps de génération des clefs...  
Vous pouvez voir l'entropie disponible sur votre serveur grâce à

    cat /proc/sys/kernel/random/entropy_avail

En général, une valeur inférieure à 1000 est assez mauvais signe. Attention sur un Containeur (openvz notamment), cela affiche directement l'entropie de l'hyperviseur, mais openssl sera extrêmement lent même si l'entropie est élevée...

Je vais ici m'inspirer de l'excellent article [How to speed up OpenSSL/GnuPG Entropy](https://www.cyberciti.biz/open-source/debian-ubuntu-centos-linux-setup-additional-entropy-for-server-using-aveged-rng-tools-utils/) du tout autant excellent [NixCraft](https://www.cyberciti.biz/). Référez vous aux Sources en fin d'article pour plus de références :-)

## Testez votre entropie
Il existe un outil qui permet de tester la qualité et la vitesse de génération de l'entropie de votre serveur.  
Il s'agit de **rng-tools**.

Cet outil est disponible sous debian et centos :

    apt-get install rng-tools
    systemctl stop rngd.service # Le daemon rngd est installé avec les tools, mais on le coupe sinon ça fausse les tests ;-)

    yum install epel-release
    yum install rng-tools.x86_64
    systemctl stop rngd.service # Le daemon rngd est installé avec les tools, mais on le coupe sinon ça fausse les tests ;-)

Et il va vous permettre de tester le `/dev/random` de votre PC/serveur/VM/whatever pour faire quelques benchmark afin de vérifier si vous pouvez réellement améliorer la qualité de l'entropie.

Une fois l'outil installé, c'est très simple :

    cat /dev/random | rngtest -c 1 # 1, parce que si votre entropie est mauvaise, avec plus vous êtes partis pour des heures...

La commande peut prendre trèès longtemps selon la qualité actuelle de votre entropie, mais notez le résultat, ça servira pour comparer plus tard :-)  
Notez particulièrement le "input channel speed" qui est vraiment très lent par défaut (de l'ordre du bit/s).

## Quelques exemples pour comparaison
Parce que le nions pas, c'est toujours d'actualité de savoir qui a la plus grosse !  
Par ordre de puissance :

** Xeon(R) E3-1241 v3 @ 3.50GHz ** : input channel speed: (min=90.908; avg=90.908; max=90.908)bits/s ---- Program run time: 220002767 microseconds  
** Core i7-3632QM @ 2.20GHz ** : input channel speed: (min=33.471; avg=33.471; max=33.471)bits/s ---- Program run time: 597524821 microseconds  
** Pentium(R) G3450 @ 3.40GHz ** : input channel speed: (min=25.983; avg=25.983; max=25.983)bits/s ---- Program run time: 769745403 microseconds  
** Atom(TM) N2800   @ 1.86GHz ** (à l'intérieur d'un containeur) : input channel speed: (min=37.391; avg=37.391; max=37.391)bits/s ---- Program run time: 534922002 microseconds  

Je précise pour la science que ces tests sont fait sur des machines en production, donc avec le CPU fortement sollicité, difficile de déterminer exactement en quoi cela impacte l'entropie..  
On voit d'ailleurs que ce n'est pas forcément le CPU le plus costaud qui est le plus efficace !

# L'entropie, l'univers et le reste avec RNGD
Voyons maintenant comme on peut améliorer tout ça :-)

rng-tools vient par défaut avec rngd : un daemon dont l'unique rôle est de générer plus d'entropie à travers le matériel présent sur le serveur :-)

Si vous êtes sur un serveur physique, il ne devrait pas y avoir trop de souci. Le service rngd devrait démarrer sans douleur.  
** Debian : **

    systemctl start rng-tools

** Centos : **

    systemctl start rngd.service

Vous pouvez ensuite vérifier qu'il tourne bien avec le classique `systemctl status nom_du_service`

Après ça, ça va dépoter fort !

    cat /dev/random | rngtest -c 1

Comparé à tout à l'heure :  

** Xeon(R) E3-1241 v3 @ 3.50GHz ** : input channel speed: (min=327.959; avg=327.959; max=327.959)Kibits/s ---- Program run time: 59779 microseconds  
** Core i7-3632QM @ 2.20GHz ** : input channel speed: (min=744.473; avg=744.473; max=744.473)Kibits/s ---- Program run time: 26636 microseconds

On voit que le temps s'est incomparablement amélioré pour sortir 1 passe aléatoire. On peut même obtenir des temps bien plus raisonnables sur de très longues passe, 1000 par exemple :

    cat /dev/random | rngtest -c 1000

Nous donne :

    rngtest: input channel speed: (min=296.094; avg=520.690; max=1218.039)Kibits/s
    rngtest: Program run time: 37824064 microseconds

On voit clairement l'amélioration.

Si par contre RNGD démarre pas correctement, les sections suivantes discutent de solutions possibles.

# Pas de source d'entropie ?
Vous pouvez obtenir au démarrage les erreurs suivantes :

    read error
    hwrng: no available rng
    Unable to open file: /dev/tpm0
    can't open any entropy source
    Maybe RNG device modules are not loaded

Ou :

    Starting Hardware RNG entropy gatherer daemon: (Hardware RNG device inode not found)
    /etc/init.d/rng-tools: Cannot find a hardware RNG device to use.

Dans ces 2 cas, cela signifie que votre serveur ne dispose d'aucun composant matériel permettant de générer de l'entropie. Dit plus simplement, votre CPU est trop pourri...

Vous pouvez vérifier si rngd trouve un générateur d'entropie avec :

    # rngd -v # Avec le -v sous Centos, ou sans le -v sous debian
    /dev/hwrng: No such device
    /dev/tpm0: No such file or directory
    Available entropy sources:
    DRNG

(ici il a par exemple trouvé DRNG comme source)

## Trick avec RNGD (Pour la culture générale)
(va y avoir du **gras** dans le texte)  
Une des solutions peut consister à configurer rngd pour se nourrir de `/dev/urandom`.

**MAIS** (je mets un gros MAIS) cette solution n'est pas idéale, voir même dangereuse !  
En effet, on se retrouve alors à nourrir `/dev/random` avec `/dev/urandom`, ce qui revient à tromper le système en lui faisant croire que ces 2 périphériques donnent des résultats aléatoires différents **alors que ce sont les mêmes**.

En conséquence, bien que le système pense que l'entropie augmente, elle est en fait de très mauvaise qualité, et dans certains cas elle peut même **décroître** en réalité.

Si vous comptez vous servir de votre entropie pour de la production (et notamment des clefs de chiffrement) cette technique est **à éviter ** !

Mais comme je sais que vous êtes curieux, je vous la mets quand même pour la culture générale :-)

On va se servir de systemd pour modifier les options de lancement du daemon rngd et lui forcer `/dev/urandom` comme source d'entropie.

** Debian **

    mkdir -p /etc/systemd/system/rng-tools.service.d
    vim /etc/systemd/system/rng-tools.service.d/customexec.conf

Indiquez dans le fichier :

    [Service]
    ExecStart=
    ExecStart=/usr/sbin/rngd -f -r /dev/urandom

** Centos **

    mkdir -p /etc/systemd/system/rngd.d/
    vim /etc/systemd/system/rngd.service.d/customexec.conf

Indiquez dans le fichier :

    [Service]
    ExecStart=
    ExecStart=/sbin/rngd -f -r /dev/urandom

Et redémarrez ensuite le service (rng-tools sous Debian, rngd sous Centos).  
**Je le répète, cette méthode n'est pas à utiliser en production !**

On voit que les résultat d'un test d'entropie sont bien plus rapides, mais la qualité ne sera pas au rendez vous :

    cat /dev/random | rngtest -c 1000

    rngtest: input channel speed: (min=2.918; avg=19.656; max=41.374)Mibits/s
    rngtest: Program run time: 1110683 microseconds

## Utilisation de Haveged (bon pour la production)
La solution marrante mais moche étant vue, voyons comment s'en tirer sans générateur matériel, de manière réellement utilisable.

Ici, tant qu'à devoir utiliser du logiciel pour générer de l'aléatoire (c'était le concept de `/dev/urandom`), on va utiliser un algorithme qui est conçu pour et maitrisé :-)  
Cet algorithme, c'est [HAVEGE](http://www.irisa.fr/caps/projects/hipsor/), et nous allons l'utiliser via le daemon [haveged](http://issihosts.com/haveged/index.html).

Il suffit donc d'installer le paquet et d'activer le service (désactivé par défaut) :

** Debian **

    aptitude install haveged
    systemctl disable rng-tools.service # On désactive rngd pour être sûr de pas avoir de conflits
    systemctl start haveged
    systemctl enable haveged

Dans le cas de Debian, allez modifier la configuration de `/etc/default/haveged` pour indiquer : `DAEMON_ARGS="-w 1024"`.

** Centos **

    yum install haveged
    systemctl disable rngd.service # On désactive rngd pour être sûr de pas avoir de conflits
    systemctl start haveged
    systemctl enable haveged

Vous pouvez aussi le laisser désactivé (systemctl disable) et ne le démarrer qu'en cas de besoin.

Avec Haveged, on obtiens également de très bon résultats lors des tests !  
Pour 1000 passes :

** Pentium(R) G3450 @ 3.40GHz ** : input channel speed: (min=2.708; avg=19.129; max=34.553)Mibits/s ---- Program run time: 1196145 microseconds  
** Atom(TM) N2800   @ 1.86GHz ** (à l'intérieur d'un containeur) : input channel speed: (min=484.190; avg=5526.698; max=3906250.000)Kibits/s ---- Program run time: 4801478 microseconds

## Le cas des Containeurs
Si vous utilisez des containeurs (Openvz, et très probablement LXC et Docker), c'est l'entropie de l'hyperviseur qui est directement utilisée.

Il est donc dans ce cas nécessaire d'installer rng ou haveged directement sur l'hyperviseur, de même que la configuration du service. Dans les résultats précédent lancés dans un containeur, le service tournait sur l'hyperviseur, mais le test était effectué depuis l'intérieur.


# Sources

Merci à ces différents articles qui m'ont été bien utiles !

  * [How to speed up OpenSSL/GnuPG Entropy](https://www.cyberciti.biz/open-source/debian-ubuntu-centos-linux-setup-additional-entropy-for-server-using-aveged-rng-tools-utils/)
  * [Entropy on red hat](https://developers.redhat.com/blog/2017/10/05/entropy-rhel-based-cloud-instances/)
  * [Systemd : Arch Linux wiki Examples](https://wiki.archlinux.org/index.php/Systemd#Examples)
  * [How to setup additionnal Entropy](https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged)
