Hi! "Jan (janneke) Nieuwenhuizen" skribis: > TODO: This seems to work...but it can keep the shepherd from finishing for > quite some time (half a minute)...not sure what to do here, WDYT? > > A great way to play with it is by doing something like > > sudo -E ./pre-inst-env guile -c '(use-modules (gnu build childhurd)) (hurd-vm-copy-secrets 10022 "/etc/childhurd")' > > * gnu/build/childhurd.scm: New file. > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it. > * gnu/services/virtualization.scm (hurd-vm-shepherd-service): Use it to set > secrets. > (hurd-vm-port): New function. > (hurd-vm-net-options): Use it. > * doc/guix.texi (The Hurd in a Virtual Machine): Document it. Nice, thanks for working on it! > +@item @code{secret-root} (default: @code{#f}) > +If set, the root directory with out-of-band secrets to be injected into > +the childhurd once it runs. Childhurds are volatile which means that on > +every startup, secrets such as the SSH host keys and Guix signing key > +are recreated. > + > +Typical use is setting @code{secret-root} to @code{"/etc/childhurd"} > +pointing at a tree of non-volatile secrets like so > + > +@example > +/etc/childhurd/etc/guix/signing-key.pub > +/etc/childhurd/etc/guix/signing-key.sec > +/etc/childhurd/etc/ssh/ssh_host_ed25519_key > +/etc/childhurd/etc/ssh/ssh_host_ecdsa_key > +/etc/childhurd/etc/ssh/ssh_host_ed25519_key.pub > +/etc/childhurd/etc/ssh/ssh_host_ecdsa_key.pub > +@end example Would it make sense to have a list of source/target pairs instead of a directory: (("/etc/childhurd/pubkey" . "/etc/guix/signing-key.pub") …) ? [...] > +(define-module (gnu build childhurd) > + #:use-module (ice-9 rdelim) > + #:use-module (guix build utils) > + > + ;; #:use-module (ssh auth) > + ;; #:use-module (ssh channel) > + ;; #:use-module (ssh session) > + ;; #:use-module (ssh sftp) > + > + #:autoload (ssh auth) (userauth-password!) You could add the file to MODULES_NOT_COMPILED in gnu/local.mk to avoid the autoload dance. > +(define* (hurd-vm-copy-secrets port secret-root #:key (retry 20)) > + "Copy all files under SECRET-ROOT using ssh to childhurd at local PORT." > + (format (current-error-port) "hurd-vm-copy-secrets\n") > + (let ((session (make-session #:host "127.0.0.1" #:port port > + #:user "root"))) I just realized that we have a bootstrapping issue here: we have to explicitly skip SSH host authentication because we haven’t installed the host keys yet. The boot sequence of the guest is actually: generate SSH host keys, start sshd, receive host keys over SFTP. [...] > - (start #~(make-forkexec-constructor #$vm-command)) > + (requirement '(loopback networking user-processes)) > + (start > + (with-imported-modules (source-module-closure '((gnu build childhurd) > + (guix build utils))) > + (with-extensions (list guile-ssh) > + #~(let ((spawn (make-forkexec-constructor #$vm-command))) > + (use-modules (gnu build childhurd)) We should use the ‘modules’ field of instead of a non-top-level ‘use-modules’. > + (lambda _ > + (let ((pid (spawn)) > + (port #$(hurd-vm-port config %hurd-vm-ssh-port)) > + (root #$(hurd-vm-configuration-secret-root config))) > + (when (and root (directory-exists? root)) > + (catch #t > + (lambda _ > + (hurd-vm-copy-secrets port root)) > + (lambda (key . args) > + (format (current-error-port) "childhurd: ~a ~s\n" key args)))) To avoid race conditions, we probably have to wait until PORT becomes available, no? Also, the VM boots even if we’ve failed to inject the secrets, right? As discussed on IRC, attached is my attempt at addressing this problem: the guest would run an activation snippet early on to receive secret files over raw unauthenticated TCP, blocking until it has received them. What’s missing from this patch is the host side that actually connects to the guest and sends this file. I think it has the advantage of failing in case the secrets haven’t been installed and it avoids the SSH host key bootstrapping issue. (It has at least the disadvantage of not being fully implemented. :-)) Also, longer term, it would allow us to not force password-less root authentication in the VM. I’m tempted to go the raw TCP way; WDYT? We can pair-hack on it if you feel like it! Thanks, Ludo’.