Subject: bug#29773: urandom-seed-service should run earlier in the boot process

From: [email-masked] (Ludovic Courtès)
Date: Thu, 21 Dec 2017 10:10:29 +0100

Leo Famulari <[email-masked]> skribis:

> On Wed, Dec 20, 2017 at 11:19:36AM +0100, Ludovic Courtès wrote:
>> There’s a ‘user-processes’ service that serves a similar purpose.
>> 
>> With the attached patches ‘urandom-seed’ becomes a dependency of
>> ‘user-processes’, meaning that daemons & co. start after
>> ‘urandom-seed’.
>> 
>> WDYT?
>
> In general, I think it's a good approach.
>
> Currently, the urandom-seed-service seems to non-deterministically but
> typically start after the udev-service, so that /dev/hwrng is always set
> up by udev before the urandom-seed-service tries to use it.
>
> With these patches, that's not the case. This breaks the hwrng seeding
> feature added in 9a56cf2b5b (services: urandom-seed: Try using a HWRNG
> to seed the Linux CRNG at boot).
>
> I'll try rearranging the service dependency graph.

The attached patch does the trick, AFAICS:

diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index acc5c33f5..7fc8f6aa7 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -529,7 +529,10 @@ in KNOWN-MOUNT-POINTS when it is stopped."
   (list (shepherd-service
          (documentation "Preserve entropy across reboots for /dev/urandom.")
          (provision '(urandom-seed))
-         (requirement '(file-systems))
+
+         ;; Depend on udev so that /dev/hwrng is available.
+         (requirement '(file-systems udev))
+
          (start #~(lambda _
                     ;; On boot, write random seed into /dev/urandom.
                     (when (file-exists? #$%random-seed-file)

> Watching a fresh system boot repeatedly, I noticed that the host keys
> always seem to be generated immediately after Linux reports "random:
> crng init done".
>
> To me, this suggests that OpenSSH is using the getrandom() syscall. If
> so, any GuixSD host keys created with glibc >= 2.25 and OpenSSH >= 7.2
> should be unpredictable. But I'm not sure if that's what's happening or
> not.

Nice.

The problem though is that ‘ssh-keygen -A’ runs from the activation
snippet, which itself runs before shepherd is started.

To work around that, we should either introduce a separate ‘ssh-keygen’
service that ‘ssh-daemon’ would depend on, or invoke ‘ssh-keygen’ from
the ‘start’ method of the ‘ssh-daemon’ service.

>> +(define (user-processes-shepherd-service requirements)
>> +  "Return the 'user-processes' Shepherd service with dependencies on
>> +REQUIREMENTS (a list of service names).
>> +
>> +This is a synchronization point used to make sure user processes and daemons
>> +get started only after crucial initial services have been started---file
>> +system mounts, etc.  This is similar to 'target' in systemd."
>
> To clarify, user-processes may be similar to the sysinit target in
> systemd. Systemd targets are sort of like run-levels, and there are
> several of them, such as the multi-user target, the graphical target,
> etc.

Indeed, I’ve fixed it locally.

If that’s OK I’ll push these patches later today.

Thank you,
Ludo’.