unofficial mirror of bug-guix@gnu.org 
 help / color / mirror / code / Atom feed
* bug#23605: /dev/urandom not seeded across reboots
@ 2016-05-23 17:58 Leo Famulari
  2016-05-24  7:05 ` Taylan Ulrich Bayırlı/Kammer
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Leo Famulari @ 2016-05-23 17:58 UTC (permalink / raw)
  To: 23605

[-- Attachment #1: Type: text/plain, Size: 1391 bytes --]

I realized that we don't seem to be saving any of the entropy in the
kernel's random pool [0] across reboots.

This means that for some period after boot, /dev/urandom may not be safe
to use. From random(4):

---
If  a seed file is saved across reboots as recommended below (all major
Linux distributions have done this since 2000 at least),
[/dev/urandom's] output is cryptographically  secure against  attackers
without  local  root access as soon as it is reloaded in the boot
sequence, and perfectly adequate for network encryption session  keys.
---

I interpret that text to mean that, without use of a seed file,
urandom's output is *not* adequate for network encryption session keys
(SSH, TLS, etc) until enough entropy has been gathered. I don't know how
long that takes.

I've attached my not-yet-working attempt at a urandom-seed-service. I
tried to get it working on my own but I need the assistance of some more
experienced Guix hackers :)

I've also attached a stand-alone Guile script to illustrate what the
effect of the service should be. This script does seem to work. I'm sure
the use of shell tools could be replaced by Guile.

After applying my patch and attempting `guix system vm ...`, I get the
attached backtrace.

Does anyone have advice about the service? Am I wrong that we need to
seed /dev/urandom to make it work properly?

[0] See the man page for random(4).

[-- Attachment #2: random.scm --]
[-- Type: text/plain, Size: 1315 bytes --]

;;; Carry some entropy across reboots. Adapted from examples in random(4).

;;; We assume Linux >= 2.6, where the poolsize is always 4096 bits (according to
;;; random(4). Otherwise, the example in random(4) reads the 'poolsize' file and
;;; creates a seed of equal size.

;;; This should be run during system shutdown.  It saves some random state as a
;;; seed for /dev/urandom, to be used on the next boot.
(define (urandom-shutdown seed)
  (touch seed)
  (chmod seed #o600)
  (write-seed seed))

;;; This should be run at boot, before starting anything that needs random
;;; numbers (sshd, TLS server, etc).
(define (urandom-boot seed)
  (and (if (file-exists? seed)
         (zero? (system (string-append "cat " seed " > /dev/urandom")))
         (touch seed))
       (chmod seed #o600)
       (write-seed seed)))

;;; On Debian, '/var/lib/urandom/random-seed'.
;;; random(4) suggests '/var/run/random-seed'.
(define seed "/tmp/random-seed")

(define (write-seed seed)
    (zero? (system* "dd" "if=/dev/urandom" (string-append "of=" seed)
                    "count=1" "bs=512"))) ;; If Linux is not >= 2.6, then 'bs'
                                          ;; must be calculated as shown in
                                          ;; random(4).

(define (touch file)
  (close-port (open-file file "a0b")))

[-- Attachment #3: urandom-seed.patch --]
[-- Type: text/x-diff, Size: 3184 bytes --]

diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 96bf8da..4a85ed0 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -32,7 +32,7 @@
   #:use-module ((gnu packages linux)
                 #:select (eudev kbd e2fsprogs lvm2 fuse alsa-utils crda gpm))
   #:use-module ((gnu packages base)
-                #:select (canonical-package glibc))
+                #:select (canonical-package glibc coreutils)) ; coreutils for `dd`, `cat`.
   #:use-module (gnu packages package-management)
   #:use-module (gnu packages lsh)
   #:use-module (gnu packages lsof)
@@ -93,6 +93,8 @@
             gpm-service-type
             gpm-service
 
+            urandom-seed-service
+
             %base-services))
 
 ;;; Commentary:
@@ -1200,6 +1202,47 @@ extra rules from the packages listed in @var{rules}."
   "Return a service that uses @var{device} as a swap device."
   (service swap-service-type device))
 
+(define %urandom-seed-activation
+  ;; Activation gexp for the urandom seed
+  #~(begin
+      (use-modules (guix build utils))
+
+      (mkdir-p "/var/run")
+      (close-port (open-file "/var/run/urandom-seed" "a0b"))
+      (chmod "/var/run/urandom-seed" #o600)))
+
+(define (urandom-seed-shepherd-service)
+  "Return a shepherd service for the /dev/urandom seed."
+  (list (shepherd-service
+         (documentation "Preserve entropy across reboots for /dev/urandom.")
+         (provision '(urandom-seed))
+         (requirement '(user-processes)) ; whatever provides file-system /var
+         (start #~(lambda _
+                    (exec-command
+                      (zero?
+                        (system (string-append "cat "
+                                               "/var/run/urandom-seed"
+                                               " > /dev/urandom"))))))
+         (stop #~(lambda _
+                   (exec-command
+                     (zero?
+                       (system* "dd" "if=/dev/urandom"
+                                (string-append "of=" "/var/run/urandom-seed")
+                                "count=1" "bs=512"))))))))
+
+(define urandom-seed-service-type
+  (service-type (name 'urandom-seed)
+                (extensions
+                 (list (service-extension shepherd-root-service-type
+                                          urandom-seed-shepherd-service)
+                       (service-extension activation-service-type
+                                          (const %urandom-seed-activation))
+                       ;; Add urandom-seed to the system profile
+                       ;; Where is profile-service-type defined?
+                       (service-extension profile-service-type list)))))
+
+(define (urandom-seed-service)
+  (service urandom-seed-service-type '()))
 
 (define-record-type* <gpm-configuration>
   gpm-configuration make-gpm-configuration gpm-configuration?
@@ -1281,6 +1324,7 @@ This is the GNU operating system, welcome!\n\n")))
           (static-networking-service "lo" "127.0.0.1"
                                      #:provision '(loopback))
           (syslog-service)
+          (urandom-seed-service)
           (guix-service)
           (nscd-service)
 

[-- Attachment #4: backtrace --]
[-- Type: text/plain, Size: 1571 bytes --]

$ ./pre-inst-env guix system vm --no-grafts ~/work/guix/doc/os-config-bare-bones.texi 
Backtrace:
In ice-9/boot-9.scm:
1724: 19 [%start-stack load-stack ...]
1729: 18 [#<procedure 1503ea0 ()>]
In unknown file:
   ?: 17 [primitive-load "/home/leo/work/guix/scripts/guix"]
In guix/ui.scm:
1197: 16 [run-guix-command system "vm" ...]
In ice-9/boot-9.scm:
 157: 15 [catch srfi-34 #<procedure 3fa0880 at guix/ui.scm:421:2 ()> ...]
 157: 14 [catch system-error ...]
In guix/scripts/system.scm:
 882: 13 [#<procedure 3ed9210 at guix/scripts/system.scm:874:2 ()>]
 788: 12 [process-action vm # #]
In guix/store.scm:
1163: 11 [run-with-store # ...]
In guix/scripts/system.scm:
 800: 10 [#<procedure 46827e0 at guix/scripts/system.scm:792:8 (state)> #]
 564: 9 [perform-action vm # # ...]
In gnu/system/vm.scm:
 496: 8 [system-qemu-image/shared-store-script # # # ...]
In gnu/system.scm:
 601: 7 [operating-system-derivation # # #f]
In gnu/services.scm:
 573: 6 [loop #]
In srfi/srfi-1.scm:
 578: 5 [map #<procedure loop (sink)> (# # #)]
In gnu/services.scm:
 573: 4 [loop #<<service> type: # parameters: #>]
In srfi/srfi-1.scm:
 578: 3 [map #<procedure loop (sink)> (# # #)]
In gnu/services.scm:
 573: 2 [loop #<<service> type: # parameters: ()>]
In srfi/srfi-1.scm:
 578: 1 [map #<procedure 50635e0 at gnu/services.scm:562:4 (service)> (# # # # ...)]
In ice-9/eval.scm:
 416: 0 [urandom-seed-shepherd-service ()]

ice-9/eval.scm:416:20: In procedure urandom-seed-shepherd-service:
ice-9/eval.scm:416:20: Wrong number of arguments to #<procedure urandom-seed-shepherd-service ()>

^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2016-05-29 20:24 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-23 17:58 bug#23605: /dev/urandom not seeded across reboots Leo Famulari
2016-05-24  7:05 ` Taylan Ulrich Bayırlı/Kammer
2016-05-24 16:16   ` Leo Famulari
2016-05-24 16:26     ` Thompson, David
2016-05-24 17:23       ` Leo Famulari
2016-05-24 17:29         ` Thompson, David
2016-05-25 21:53       ` Ludovic Courtès
2016-05-24 12:24 ` Ludovic Courtès
2016-05-25 16:38   ` Leo Famulari
2016-05-25 16:54     ` Ludovic Courtès
2016-05-26 16:47       ` Leo Famulari
2016-05-28 13:57         ` Ludovic Courtès
2016-05-28 18:05           ` Leo Famulari
2016-05-28 18:10             ` Leo Famulari
2016-05-28 18:26             ` Leo Famulari
2016-05-28 20:41               ` Leo Famulari
2016-05-28 20:53             ` Ludovic Courtès
2016-05-29  0:00               ` Leo Famulari
2016-05-29  0:04                 ` Leo Famulari
2016-05-29 20:23                 ` Ludovic Courtès
2016-05-28  1:12   ` Leo Famulari
2016-05-28 13:51     ` Ludovic Courtès
2016-05-28  1:05 ` Leo Famulari
2016-05-28  1:11   ` Ben Woodcroft
2016-05-28  1:45     ` Leo Famulari
2016-05-28  9:40       ` Ben Woodcroft

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).