From mboxrd@z Thu Jan 1 00:00:00 1970 From: Leo Famulari Subject: bug#23605: /dev/urandom not seeded across reboots Date: Mon, 23 May 2016 13:58:32 -0400 Message-ID: <20160523175832.GA10646@jasmine> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="VS++wcV0S1rZb1Fb" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:51825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b4u8B-00044X-U9 for bug-guix@gnu.org; Mon, 23 May 2016 13:59:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b4u87-0006jH-Hw for bug-guix@gnu.org; Mon, 23 May 2016 13:59:06 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:51005) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b4u86-0006j4-0Z for bug-guix@gnu.org; Mon, 23 May 2016 13:59:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1b4u85-0005bI-Rb for bug-guix@gnu.org; Mon, 23 May 2016 13:59:01 -0400 Sender: "Debbugs-submit" Resent-Message-ID: Received: from eggs.gnu.org ([2001:4830:134:3::10]:51715) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b4u7r-00043H-2T for bug-guix@gnu.org; Mon, 23 May 2016 13:58:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b4u7m-0006dG-LP for bug-guix@gnu.org; Mon, 23 May 2016 13:58:46 -0400 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:60331) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b4u7l-0006ax-9c for bug-guix@gnu.org; Mon, 23 May 2016 13:58:42 -0400 Received: from localhost (c-73-188-17-148.hsd1.pa.comcast.net [73.188.17.148]) by mail.messagingengine.com (Postfix) with ESMTPA id BC50CF29F6 for ; Mon, 23 May 2016 13:58:32 -0400 (EDT) Content-Disposition: inline List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org Sender: "bug-Guix" To: 23605@debbugs.gnu.org --VS++wcV0S1rZb1Fb Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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). --VS++wcV0S1rZb1Fb Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="random.scm" ;;; 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"))) --VS++wcV0S1rZb1Fb Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="urandom-seed.patch" 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 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) --VS++wcV0S1rZb1Fb Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=backtrace $ ./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 [#] 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 # ...] 157: 14 [catch system-error ...] In guix/scripts/system.scm: 882: 13 [#] 788: 12 [process-action vm # #] In guix/store.scm: 1163: 11 [run-with-store # ...] In guix/scripts/system.scm: 800: 10 [# #] 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 # (# # #)] In gnu/services.scm: 573: 4 [loop #< type: # parameters: #>] In srfi/srfi-1.scm: 578: 3 [map # (# # #)] In gnu/services.scm: 573: 2 [loop #< type: # parameters: ()>] In srfi/srfi-1.scm: 578: 1 [map # (# # # # ...)] 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 # --VS++wcV0S1rZb1Fb--