Adventures in entropy, part 2
Recap
Back in part 1 I discussed what entropy is as far as Linux is concerned, why I’ve started to look in to entropy as it relates to a Linux/Xen-based virtual hosting platform, how much entropy I have available, and how this might be improved.
If you didn’t read that part yet then you might want to do so, before carrying on with this part.
As before, click on any graph to see the full-size version.
Hosting server with an Entropy Key
Recently I colocated a new hosting server so it seemed like a good opportunity to try out the Entropy Key at the same time. Here’s what the available entropy looks like whilst ekeyd is running.
First impressions are, this is pretty impressive. It hovers very close to 4096 bytes at all times. There is very little jitter.
Trying to deplete the entropy pool, while using an Entropy Key
As per Hugo’s comment in part 1, I tried watch -n 0.25 cat /proc/sys/kernel/random/entropy_avail to see if I could deplete the entropy pool, but it had virtually no effect. I tried with watch -n 0.1 cat /proc/sys/kernel/random/entropy_avail (so every tenth of a second) and the available entropy fluctuated mostly around 4000 bytes with a brief dip to ~3600 bytes:
In the above graph, the first watch invocation was at ~1100 UTC. The second one was at ~1135 UTC.
Disabling the Entropy Key
Unfortunately I forgot to get graphs of urquell before the ekeyd was started, so I have no baseline for this machine.
I assumed it would be the same as all the other host machines, but decided to shut down ekeyd to verify that. Here’s what happened.
The huge chasm of very little entropy in the middle of this graph is urquell running without an ekeyd. At first I was at a loss to explain why it should only have ~400 bytes of entropy by itself, when the other hosting servers manage somewhere between 3250 and 4096 bytes.
I now believe that it’s because urquell is newly installed and has no real load. Looking into how modern Linux kernels obtain entropy, it’s basically:
- keyboard interrupts;
- mouse interrupts;
- other device driver interrupts with the flag IRQF_SAMPLE_RANDOM.
Bear in mind that headless servers usuallly don’t have a mouse or keyboard attached!
You can see which other drivers are candidates for filling up the entropy pool by looking where the IRQF_SAMPLE_RANDOM identifier occurs in the source of the kernel:
http://www.cs.fsu.edu/~baker/devices/lxr/http/ident?i=IRQF_SAMPLE_RANDOM
(as an aside, in 2.4.x kernels, most of the network interface card drivers had IRQF_SAMPLE_RANDOM and then they all got removed through the 2.6.x cycle since it was decided that IRQF_SAMPLE_RANDOM is really only for interrupts that can’t be observed or tampered with by an outside party. That’s why a lot of people reported problems with lack of entropy after upgrading their kernels.)
My hosting servers are typically Supermicro motherboards with Intel gigabit NICs and 3ware RAID controller. The most obvious device in the list that could be supplying entropy is probably block/xen-blkfront since there’s one of those for each block device exported to a Xen virtual machine on the system.
To test the hypothesis that the other servers are getting entropy from busy Xen block devices, I shut down ekeyd and then hammered on a VM filesystem:
The increase you see towards the end of the graph was while I was hammering the virtual machine’s filesystem. I was able to raise the available entropy to a stable ~2000 bytes doing this, so I’m satisfied that if urquell were as busy as the other servers then it would have similar available entropy to them, even without the Entropy Key.
Feeding entropy to other hosts
ekeyd by default feeds entropy from the key directly into the Linux kernel of the host it’s on, but it can be configured to listen on a Unix or TCP socket and mimic the egd protocol. I set it up this way and then put an instance of HAProxy into a VM with my ekeyd as a back end. So at this point I had a service IP which would talk egd protocol, and client machines could use to request entropy.
On the client side, ekeyd-egd-linux can be found in Debian lenny-backports and in Debian squeeze, as well as Ubuntu universe since Jaunty. This daemon can read from a Unix or TCP socket using the egd protocol and will feed the received entropy into the Linux kernel.
I took a look at which of my VMs had the lowest available entropy and installed ekeyd-egd-linux on them, pointing it at my entropy service IP:
Success!
Where next?
- Get some customers using it, explore the limits of how much entropy can be served.
- Buy another Entropy Key so that it doesn’t all grind to a halt if one of them should die.
- Investigate a way to get
egdto read from anotheregdso I can serve the entropy directly from a VM and not have so many connections to my real hardware. Anyone interested in coding that? - Monitor the served entropy both for availability and for quality.







June 7th, 2010 at 13:22
[...] ongoing struggle I’ll get there one day. « Clue- Become Compliant Adventures in entropy, part 2 [...]
June 7th, 2010 at 13:32
Really interesting pair of articles!
I’ve tried running ‘watch -n 0.25 cat entropy_avail’ and my entropy goes down too. What I did find interesting about that command though is that leaving my computer alone the entropy stayed put for up to a few seconds at a time. But, moving the mouse and typing on my keyboard caused the entropy to jump around, obviously as a result of all the interrupts being generated.
June 7th, 2010 at 15:55
The reason entropy drops when you try to look at it is that you’re causing the execution of a program. Modern Linux runtime linkers randomise where shared libraries are loaded to make attacks more difficult. It does this by reading 32 or 64 bytes from /dev/random.
Glad you’re having success with the Entropy Key! (Disclaimer: I work for the manufacturer.)
July 22nd, 2010 at 05:11
I’ve been doing some experiments with Entropy Key too. Thanks for the explanation about why starting a process (such as cat) to read entropy_avail actually uses entropy.
To counteract this, I used the following little Perl script which reads entropy_avail every 0.1 seconds without spawning a process each time:
http://gist.github.com/485595