KVM: Low entropy in guests | Virtualized Hardware RNG

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

While I diagnosed some slow TLS/SSL connections I found out that some of my KVM guests are low on entropy. The value was between 150 and 190.

Right after booting up the entropy pool was near emptry and slowly increased after quite some time.

This behaviour is pretty normal, because a virtual server has (other than a physical server) nearly no load and hardware to gather good entropy data.

Side fact: Entropy and linux

Linux has an entropy pool where „good“ random data is stored. These pools can be accessed by using the two virtual devices

Normally every application using random numbers is taking it out of the entropy pool. A heavy utilization occures for example when you work much with cryptography (TLS connections, Generating key pairs, etc).

My nginx is using /dev/random. As mentioned above is this pool blocking. That means when there is no entropy available the device waits until there is enough data. This resulted in slow TLS connections.

A possible fix would be forcing nginx to use /dev/urandom which is non-blocking. This may result in bad entropy data if there is low or no entropy in the pool. This is not a good solution.

You can query the value of available bits in the pool using the /proc interface:

Most of my KVM guests reported low values. Everything under 250 is too low. The maximum is 4096.

Solution

At first I wanted to link the guests entropy pool with the one from the host system. Unfortunately this is not possible. The solution is to virtualize a hardware random number generator (HW RNG).

Settings for the host system

The virtualized RNG takes its entropy out of the entropy pool from the host and seeds it into the guests entropy pool. If you are doing this for some guests you have to be carefull! The worst thing what can happen is a low entropy pool on the host.

Install HAVEGED

The host system has some pretty good sources for good entropy data. There is an algorithm for fetching this data. It’s called HAVEGE. There is also an Implementation called HAVEGE-Daemon (or short: HAVEGED).

Installing this on a Debian based System is easy:

That’s it. You don’t have to do more settings. The daemon is smart and only seeds the entropy pool if it’s below 1024 bits. In conclusion the daemon doesn’t take away much CPU time.

I’ve increased the limit to 2048 bits. If you rund the goold old SysV Init/Upstart this can be done in the file under /etc/default/haveged. I’ve changed it to:

If you are using systemd you have to edit the file unter /lib/systemd/system/haveged.service:

Add the RNG to the guest

The next step is to add the RNG to each guest. This can be done for example with virt-manager.

The option „Device“ represents the path on the host system. If it’s /dev/random everything is fine.

Settings in the guest

After adding n RNG you have to full stop the machine. A simple reboot normally isn’t working. After that there should be a device file under /dev/hwrng.

If you can see this you are halfway through. Simply adding an RNG is not enough. A deamon has to take the entropy from the RNG and seed it into the system wide entropy pool.

But installing haveged would be a CPU hog. The ligher daemon out of the package rng-rools is enough. On Debian based systems it’s easy to install:

After the start the daemon automatically recognises the RNG and starts seeding. You can validate it for example with systemctl:

If you see in the CGroup something like „-r /dev/hwrng“ everything works fine.

Further Reading


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

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