KVM: Wenig Entropie in Guests | Virtualisierter Hardware RNG

Achtung! Dieser Artikel ist älter als ein Jahr. Der Inhalt ist möglicherweise nicht mehr aktuell!

Ich habe bei der Diagnose bezüglich langsamen TLS/SSL Verbindungen festgestellt, dass die verfügbare Entropie meiner KVM Guests sehr gering war. Der Wert Betrug ungefähr 150 – 190.

Nach dem Start eines Guests konnte ich sehen, wie der Pool nur sehr langsam gefüllt wurde. Dabei ist es eigentlich kein Wunder, dass die Werte bei KVM Guests ziemlich gering ist: Die Maschinen haben im Vergleich zu physischen Servern fast keine Last oder Hardware, die gute Zufallszahlen zulassen würden.

Exkurs: Entropie und Linux

Linux hat einen Entropie-Pool, der stets mit „qualitativ hochwertige“ Zufallszahlen gefüllt sein sollte. Diesen Pool kann man via den beiden Device Files

anzapfen.

Jedes Programm, das Zufallszahlen braucht, benutzt sich im Normalfall aus einem der beiden Files. Stark beansprucht wird der Entropie Pool, wenn zum Beispiel mit Kryptographie gearbeitet wird (TLS-Verbindungen, Schlüsselpaare erzeugen, usw).

In meinem Fall war der Entropie Pool fast nicht gefüllt und mein nginx bedient sich aus /dev/random. Anders als bei /dev/urandom blockiert _/dev/random_ so lange, bis genügend Bits vorhanden sind. Das führte zu einem langsamen Verbindungsaufbau.

Ein Fix wäre gewesen, dass nginx sich nicht aus dem nicht-blockierenden /dev/urandom bedient. Eine dauerhafte und sinnvolle Lösung ist das aber nicht.

Die aktuell Füllstand kann man via Kernel-Schnittstelle auslesen:

:~$ cat /proc/sys/kernel/random/entropy_avail

Das Kommando spuckt die Anzahl an verfügbaren Bits aus. Bei meinem Guests war der Wert zu niedrig. Alles unter 250 gilt als zu gering. Das Maximum sind 4096 Bits.

Lösung

Eine Lösung wäre ein „Entropie Gathering Daemon“ wie HAVEGED in jedem Gast zu installieren. Das würde aber nur mehr CPU Last auf dem Hostsystem verursachen.

Stattdessen wollte ich die Proc-Schnittstelle /dev/random vom Hostsystem an die Maschinen weitergeben. Via QEMU/KVM kann man einen Hardware Random Number Generator virtualisieren, der genau das macht.

Wichtig: Zu Hause habe ich KEIN Cluster aus KVM Hosts. Zufallszahlen an Guests durchzureichen ist bei einem Cluster viel schwieriger und hat eventuell sogar einen gegenteiligen Effekt!

Arbeiten am Hostsystem

HAVEGED installieren

Damit genügend Zufallszahlen auf dem Hostsystem verfügbar sind, braucht man unter Umständen Hilfsmittel. Ich benutze dabei immer den oben genannten HAVEGE-Daemon (oder kurz: HAVEGED). Dieser zieht sich von verschiedenen Quellen Zufallszahlen und speist sie in den Entropie-Pool.

Installation von HAVEGED auf Debian basierten Systemen ist einfach:

:-$ apt-get install haveged

Danach startet der Daemon automatisch und speist in der Standardkonfiguration ab einem Wert unter 1024 Bits den Entropie Pool des Systems. Es ist also keine permanente CPU Belastung zu erwarten.

Ich habe das Limit auf 2048 Bits hochgesetzt. Im Normalfall muss man das nicht tun. Nachfolgend sind die Schritte aufgeführt, falls man es doch tun will:

Bei Upstart/Init muss man in der Datei /etc/default/haveged folgende Zeile finden und abändern:

DAEMON_ARGS="-w 2048"

Verwendet man Systemd muss man die Datei /lib/systemd/system/haveged.service abändern und diese Zeile anpassen:

[Service]
ExecStart=/usr/sbin/haveged --Foreground --verbose=1 --write=2048

Guests anpassen

Den Guests muss man nun einen RNG spendieren. Am besten macht man das über den virt-manager. Die Guests müssen nach dem Hinzufügen eines RNG neu gestartet werden.

virt-manager-add-rng

Die Option „Gerät“ entspricht dabei der Quelle auf dem Hostsystem. Wenn dort _/dev/random _steht ist alles okay.

Arbeiten in den Guests

Nach dem Start des Guests findet man unter /dev/hwrng nun ein Device-File zum soeben hinzugefügten RNG. Leider reicht das noch nicht aus, da dieser Generator nicht in den Entropie Pool des Systems schreibt.

Bei manchen Programmen kann man angeben, aus welchem Pool sie Zufallszahlen ziehen. Besser ist es aber, wenn die Zufallszahlen in den systemweiten Pool geschrieben werden. Dadurch kann man sicher sein, dass alle Programme genug Zufallszahlen erhalten.

Auf Debian basierten Systemen gibt es das Paket rng-tools. Die Installation einfach wieder via apt:

:~$ apt-get install rng-tools

Danach startet sich der rngd automatisch, der im Normalfall den Hardware RNG erkennt und dessen Bits nun in den systemweiten Pool schreibt. Überprüfen kann man das zum Beispiel via systemctl:

:~$ systemctl status rng-tools.service
● rng-tools.service - (null)
 Loaded: loaded (/etc/init.d/rng-tools)
 Active: active (running) since Mo 2016-03-07 20:28:01 CET; 37min ago
 Process: 730 ExecStop=/etc/init.d/rng-tools stop (code=exited, status=0/SUCCESS)
 Process: 733 ExecStart=/etc/init.d/rng-tools start (code=exited, status=0/SUCCESS)
 CGroup: /system.slice/rng-tools.service
 └─735 /usr/sbin/rngd -r /dev/hwrng

Mär 07 20:28:01 dns1 rng-tools[730]: Stopping Hardware RNG entropy gatherer daemon: rngd.
Mär 07 20:28:01 dns1 rng-tools[733]: Starting Hardware RNG entropy gatherer daemon: rngd.
Mär 07 20:28:01 dns1 rngd[735]: rngd 2-unofficial-mt.14 starting up...
Mär 07 20:28:01 dns1 rngd[735]: entropy feed to the kernel ready

Steht wie im Beispiel oben bei CGroup ein „-r /dev/hwrng“, dann hat rngd den Hardware RNG richtig erkannt. Bilder sagen bekanntlich mehr als 1000 Worte. Deshalb hier ein Screenshot aus meinem Monitoring:

grafana-available-entropy

Man sieht, dass nach einem Neustart um ca. 20:16 Uhr ganz wenig Bits im Pool vorhanden sind. Nachdem rngd den Pool kräftig aufgestockt hat, geht der Graph auch steil nach oben.

Further Reading


Du hast einen Kommentar, einen Wunsch oder eine Verbeserung? Schreib mir doch eine E-Mail! Die Infos dazu stehen hier.

🖇️ = Link zu anderer Webseite
🔐 = Webseite nutzt HTTPS (verschlüsselter Transportweg)
Zurück