[systemd-devel] Delaying (SSH) key generation until the urandom pool is initialized

Lennart Poettering lennart at poettering.net
Fri May 2 04:05:47 PDT 2014


On Wed, 30.04.14 14:02, Florian Weimer (fweimer at redhat.com) wrote:

> 
> On 04/30/2014 01:08 PM, Lennart Poettering wrote:
> >On Tue, 29.04.14 20:43, Florian Weimer (fweimer at redhat.com) wrote:
> >
> >>The message at <https://mail.gnome.org/archives/ostree-list/2014-February/msg00010.html>
> >>contains two boot traces from virtual machines which show that the
> >>SSH key is generated before the kernel pool is sufficiently seeded.
> >
> >Are you saying ssh reads from /dev/urandom rather than /dev/random, but
> >it should be reading from the latter?
> 
> No, that's not what I wrote.
> 
> Using /dev/urandom for key generation is fine once its pool is
> seeded. Using existing key generation algorithms with /dev/random
> instead does not work because they consume too much entropy and can
> block for significantly more time than just a few minutes.
> 
> >WHat does that have to do with systemd?
> 
> It seems related to boot ordering, device availability, kernel event
> signaling and so on (although we have little of that at present).
> 
> In particular, what I want is that a one-shot service for key
> generation only blocks on pool seeding when it actually needs to run
> (because the keys do not exist yet).  From a support perspective, it
> seems better to do the waiting outside the one-shot service, so that
> systemd tools can be used to examine what is causing the delay.
> 
> >>Would it be possible using socket activation to create the listening
> >>socket for SSH, but block the actual service startup until the keys
> >>have been generated after sufficient entropy became available?
> >>
> >>What would you need on the kernel side to implement the waiting?
> >>(Textual comparison of a log message is only good for a prototype.)
> >
> >THis already exists. It's called /dev/random...
> 
> No, /dev/random can (and will) block long after booting.

But that's what you want in this case, no? You want this to block after
booting if there never has been enough entropy in the pool, right?

Is there any kernel API currently available to at least query if the
pool is properly initialized?

So you have multiple options:

a) fix the kernel to make /dev/urandom block until enough initial
   entropy has been gathered. Would fix the roblem, but probably slow
   down systemd. In systemd the hash functions used in hash tables are
   keyed off /dev/urandom, in order to make collision attacks
   difficult. This only requires low-quality entropy, as we rehash with
   a new key anyway should the hashtable reach its initial size
   limit. Hence blocking reading of /dev/urandom until the pool is
   initialized will slow down systemd since would have to block without
   actually needing any quality entropy...

b) fix the kernel to make the behaviour explained in a) something
   optional, maybe something that is enabled on /dev/random when
   O_DIRECT or so is passed during opening. i.e. if that flag is
   specifiied that /dev/random will behave like classic /dev/random
   until the initial pool is filled up, and like /dev/urandom
   afterwards.

c) solve this in userspace in the individual apps. if there's a kernel
   api to check whether the pool is properly initialized, then apps
   could check that. If the check fails they'd use /dev/random,
   otherwise /dev/urandom.

I am very conservative howver to simply delay the boot until the pool is
initialized.


Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list