RedHat logo

According to Wikipedia, entropy is the randomness collected by an operating system or application for use in cryptography or other uses that require random data.

Entropy is often overlooked, misconfigured or forgotten and it can originate in sporadic errors whether it can be timeouts, refused connections, etc. Such errors are difficult to debug as the errors happen only when there is not enough entropy available.

This article tries to explain briefly how to check if this can be a problem in a RHEL system and how to fix it.

NOTE: This article is meant to provide some helpful hints about entropy. It is not meant to be exhaustive or definitive. There are hundreds of information sources on the Internet such as KCS articles; https://access.redhat.com/articles/221583 and https://access.redhat.com/solutions/19866 where this article is based. Check the bibliography section for more information.

What is entropy and why is important?

Many processes generate certificates, keys, IDs, etc., so they need a random source to avoid generating those assets in a predictable way.

In RHEL there are a couple of special devices that can be used for gathering random numbers for those processes:

  • /dev/random
  • /dev/urandom

They serve as pseudorandom number generators as they access environmental noise collected from device drivers and other sources like mouse movement and keyboarding.

The kernel random number generator (RNG) constantly estimates the number of bits of noise in the entropy pool and when processes read from /dev/random, the kernel only returns random bytes within this estimate -- that is, the read will block until the kernel estimates that there's enough randomness in the RNG to feed out another byte.

The /dev/urandom device gets its data from the kernel RNG just like /dev/random; however, it doesn't pay any attention to the available entropy estimate--think "u" for "unlocked" (i.e., doesn't lock/block). So, when applications request data from /dev/urandom, the kernel starts feeding out random bytes and the entropy_avail value starts dropping, but unlike with /dev/random, the kernel keeps returning bytes after the estimated number of bits in the entropy pool drops below a certain point. There's no waiting for the additional environmental noise to be integrated into the entropy pool.

NOTE: There are hundreds of articles speaking about /dev/random vs. /dev/urandom so it won’t be covered in this article.

Where in workstations with mouse and keyboards the entropy shouldn’t be a problem, in headless systems like cloud instances it can be more complicated and dependent on the hardware where the instances are running.

Check available entropy

The following command will tell you the available entropy in your system:

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

The consensus is that numbers below 1000 will lead to processes blocking waiting for more entropy.

You can use “rngtest” from the rng-tools package to perform some tests as well:

$ sudo yum install -y rng-tools
$ cat /dev/random | rngtest -c 100
rngtest 5
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests...
rngtest: bits received from input: 2000032
rngtest: FIPS 140-2 successes: 100
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=182.820; avg=243.932; max=309.926)Kibits/s
rngtest: FIPS tests speed: (min=110.892; avg=154.893; max=179.939)Mibits/s
rngtest: Program run time: 8019371 microseconds

While in a host with low entropy it can take minutes.

Methods to improve entropy in cloud instances

The entropy sources in cloud instances are very dependent on the provider of choice where the instance is running but there are some methods to try to improve it.

Preferred method: hardware random number generator

Some system/motherboard chipsets include hardware random number generator devices. The kernel includes drivers like amd-rng and intel-rng to support these devices. Add-on hardware random number generators (hardware-based entropy tools) are available as well.

However, to use a hardware random number generator within a cloud environment is a challenge, as it will require 1:1 mapping from instances to hardware random number generators connected to the hypervisors.

Preferred method: direct hardware instructions to processor

There are certain processors that include a random number generator, which the kernel uses to generate entropy with the processor instructions RDRAND and RDSEED.

You can check if your processor has the RDRAND instruction by typing:

$ grep rdrand /proc/cpuinfo

If available, it can be used by the instances as well as will be explained in this article later.

Preferred method: paravirtual random number generator

Within a KVM virtual machine (RHEL KVM, RHEV, Red Hat OpenStack) a RHEL 7 hypervisor can provide a paravirtual random device to a RHEL6 or RHEL7 guest, this paravirtual device draws from the hypervisor's true hardware entropy source.

This is discussed in greater detail on the RHEL Blog at Red Hat Enterprise Linux Virtual Machines: Access to Random Numbers Made Easy.

There are certain cloud providers like OpenStack where even if they are KVM based, they need specific configuration to share entropy with the instances like https://access.redhat.com/solutions/2529281.

Non-preferred method: seed randomness source from non-blocking source

WARNING: This method is potentially insecure and should only be used when no other source of entropy can be supplied and the application being configured is hard-coded to use /dev/random device.

The idea of this method is to use /dev/urandom as an entropy source for /dev/random and it will be explained later.

Introducing rngd service

If your RHEL based cloud instance doesn’t have enough entropy, the rngd service can help to feed the /dev/random device by gathering entropy from an entropy source. Installing the rng-tools package provides both rngtest and rngd service:

$ sudo yum install -y rng-tools

To identify the different sources of entropy available in the system, use

$ sudo rngd -v
hwrng: no available rng
Unable to open file: /dev/tpm0
Available entropy sources:
DRNG

In this example, rngd output can be evaluated as there isn’t a hardware generator but there is a DRNG entropy source.

To enable the rngd service at boot and start the rngd service, perform the following commands:

# systemctl enable rngd.service
# systemctl start rngd.service

The rngd service will check and feed random data from the hardware device to kernel entropy pool automatically.

Check the available entropy after starting the rngd service and observe the difference!

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

Use rngd to seed randomness from non-blocking source

If you run the previous rngd -v command in a system without any other entropy source, you should get the following result:

$ sudo rngd -v
Unable to open file: /dev/tpm0
can't open any entropy source
Maybe RNG device modules are not loaded

WARNING: Seeding /dev/random with data derived from /dev/urandom plays a trick on the system - the entropy_avail reported will increase, but the real entropy is actually decreasing. A software-only random number generator like rngd is not a proper substitute for a good hardware random number generator. Do not use rngd in this fashion unless you understand and accept this difference.

Run rndg using /dev/urandom as entropy source:

# rngd -r /dev/urandom -o /dev/random

Check available entropy:

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

To make this permanent (as before, it is not recommended):

  • Create a specific directory to override rndg systemd configuration
$ sudo mkdir -p /etc/systemd/system/rngd.d/
  • Create a systemd configuration file /etc/systemd/system/rngd.d/customexec.conf to just override the rngd ExecStart command with the following content:
[Service]
ExecStart=
ExecStart=/sbin/rngd -f -r /dev/urandom

NOTE: The empty “ExecStart” is required

Reload the Systemd configuration:

$ sudo systemctl daemon-reload

Enable and start the rngd service:

$ sudo systemctl restart rngd.service
$ sudo systemctl enable rngd.service

Final notes

Entropy should be taken into account when running instances in cloud environments as it can be a source of strange errors. Check the cloud provider's official documentation to learn how to ensure entropy is not going to be a problem for your instances.

Bibliography

Last updated: March 22, 2023