Ubuntu – How to get /dev/random to work on an Ubuntu virtual machine

kerberosrandom-number-generatorUbuntuvirtual-machines

Apparently, /dev/random is based on hardware interrupts or similar unpredictable aspects of physical hardware. Since virtual machines don't have physical hardware, running cat /dev/random within a virtual machine produces nothing. I'm using Ubuntu Server 11.04 as the host and guest, with libvirt/KVM.

I need to set-up Kerberos inside a VM, but krb5_newrealm just hangs forever "Loading random data", since the system isn't producing any.

Does anyone know how to work around this? Is is possible to pass the host's /dev/random (which is very chatty) into the vm so the vm can use it's random data?

I've read that there are some software alternatives, but they aren't good for cryptology since they aren't random enough.

EDIT: It appears that cat /dev/random on the vm does produce output, just very, very slowly. I got my realm set-up by waiting about two hours while it was "Loading random data". Eventually it got enough to continue. I'm still interested in a way to accelerate this though.

Best Answer

It should 'just work'. Even though the vm has no dedicated physical hardware, it still has access to several very good sources of randomness. For example, it can use the CPU's TSC to time its read from virtual disks, which will ultimately wind up timing physical disks to the billionth of a second. These timings depend on turbulent airflow shear in the hard drive, which is unpredictable.

Similar logic applies to network traffic. Even though the interface is virtualized, so long as the packet originates on a physical network (and isn't local to the box, say originating in another vm), the packet timing depends on the phase offset between the crystal oscillator on the network card and the crystal oscillator that drives the TSC. This is dependent on microscopic zone temperature variations in the two quartz crystals. This too is unpredictable.

If for some reason it's not working, the simplest solution is to write a program to mine entropy and add it to the system pool. The network interface is your most reliable source. For example, you can write code to:

1) Query the TSC.

2) Issue a DNS query to a server known not to be on the same physical machine.

3) Query the TSC when the query completes.

4) Repeat this a few times, accumulating all the TSC values.

5) Perform a secure hash on the accumulated TSC functions.

6) Pass the secure hash function's output to the system's entropy pool.

7) Monitor the entropy pool level, and wait until it's low. When it is, go back to step 1.

Linux has simple IOCTL calls to add entropy to the pool, check the pool's level, and so on. You probably have rngd, which can take entropy from a pipe and feed it to the system pool. You can fill the pipe from any source you want, whether it's the TSC or 'wget' requests from your own entropy source.