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.