summaryrefslogtreecommitdiff
path: root/gnu/services/virtualization.scm
diff options
context:
space:
mode:
authorLiliana Marie Prikler <liliana.prikler@gmail.com>2023-10-09 21:21:29 +0200
committerLiliana Marie Prikler <liliana.prikler@gmail.com>2023-10-09 21:21:29 +0200
commit24fee2615ce7a18a7fcd6054b73375a890556cf3 (patch)
tree353f9e87b8ec736f32eed840c58dc7d5651c19cf /gnu/services/virtualization.scm
parent7d134b57b79188f8c878625d4e09f9bd6181e8c0 (diff)
parent7937c8827b8d23347a3159b4696335bd19fc17aa (diff)
Merge branch 'master' into gnome-team
Diffstat (limited to 'gnu/services/virtualization.scm')
-rw-r--r--gnu/services/virtualization.scm173
1 files changed, 162 insertions, 11 deletions
diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm
index e1a206e0eb..f0f0ab3bf1 100644
--- a/gnu/services/virtualization.scm
+++ b/gnu/services/virtualization.scm
@@ -27,7 +27,9 @@
#:use-module (gnu bootloader grub)
#:use-module (gnu image)
#:use-module (gnu packages admin)
+ #:use-module (gnu packages bash)
#:use-module (gnu packages gdb)
+ #:autoload (gnu packages gnupg) (guile-gcrypt)
#:use-module (gnu packages package-management)
#:use-module (gnu packages ssh)
#:use-module (gnu packages virtualization)
@@ -50,6 +52,8 @@
#:use-module (guix records)
#:use-module (guix store)
#:use-module (guix utils)
+ #:autoload (guix self) (make-config.scm)
+ #:autoload (guix platform) (platform-system)
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-26)
@@ -1061,6 +1065,40 @@ that will be listening to receive secret keys on port 1004, TCP."
;;; The Hurd in VM service: a Childhurd.
;;;
+(define (operating-system-with-offloading-account os)
+ (define accounts
+ (list (user-group
+ (name "offloading")
+ (system? #t))
+ (user-account
+ (name "offloading")
+ (group "offloading")
+ (system? #t)
+ (comment "Offloading privilege separation user")
+ (home-directory "/var/run/offloading")
+ (shell (file-append bash-minimal "/bin/sh")))))
+
+ (operating-system
+ (inherit os)
+ (services (cons (simple-service 'offloading-account
+ account-service-type
+ accounts)
+ (operating-system-user-services os)))))
+
+(define (operating-system-with-locked-root-account os)
+ "Return OS with a 'root' account whose password is uninitialized, thereby
+preventing password-based authentication as 'root'."
+ (define root
+ ;; %ROOT-ACCOUNT has an empty password; change that to an uninitialized
+ ;; password.
+ (user-account
+ (inherit %root-account)
+ (password #f)))
+
+ (operating-system
+ (inherit os)
+ (users (cons root (operating-system-users os)))))
+
(define %hurd-vm-operating-system
(operating-system
(inherit %hurd-default-operating-system)
@@ -1078,8 +1116,7 @@ that will be listening to receive secret keys on port 1004, TCP."
(openssh-configuration
(openssh openssh-sans-x)
(use-pam? #f)
- (port-number 2222)
- (permit-root-login #t)
+ (permit-root-login 'prohibit-password)
(allow-empty-passwords? #t)
(password-authentication? #t)))
@@ -1100,7 +1137,7 @@ that will be listening to receive secret keys on port 1004, TCP."
(default %hurd-vm-operating-system))
(qemu hurd-vm-configuration-qemu ;file-like
(default qemu-minimal))
- (image hurd-vm-configuration-image ;string
+ (image hurd-vm-configuration-image ;<image>
(thunked)
(default (hurd-vm-disk-image this-record)))
(disk-size hurd-vm-configuration-disk-size ;number or 'guess
@@ -1114,20 +1151,32 @@ that will be listening to receive secret keys on port 1004, TCP."
(net-options hurd-vm-configuration-net-options ;list of string
(thunked)
(default (hurd-vm-net-options this-record)))
+ (offloading? hurd-vm-configuration-offloading? ;Boolean
+ (default #t))
(secret-root hurd-vm-configuration-secret-root ;string
(default "/etc/childhurd")))
(define (hurd-vm-disk-image config)
"Return a disk-image for the Hurd according to CONFIG. The secret-service
is added to the OS specified in CONFIG."
- (let* ((os (secret-service-operating-system
- (hurd-vm-configuration-os config)))
+ (define transform
+ (compose secret-service-operating-system
+ ;; When offloading is enabled, (1) add the 'offloading' account,
+ ;; and (2) prevent users from logging in as 'root' without a
+ ;; password as this would allow any user on the host to populate
+ ;; the host's store indirectly (for example by logging in as root
+ ;; in the Hurd VM over VNC).
+ (if (hurd-vm-configuration-offloading? config)
+ (compose operating-system-with-locked-root-account
+ operating-system-with-offloading-account)
+ identity)))
+
+ (let* ((os (transform (hurd-vm-configuration-os config)))
(disk-size (hurd-vm-configuration-disk-size config))
(type (lookup-image-type-by-name 'hurd-qcow2))
(os->image (image-type-constructor type)))
- (system-image
- (image (inherit (os->image os))
- (size disk-size)))))
+ (image (inherit (os->image os))
+ (size disk-size))))
(define (hurd-vm-port config base)
"Return the forwarded vm port for this childhurd config."
@@ -1146,7 +1195,7 @@ is added to the OS specified in CONFIG."
"-:1004"
",hostfwd=tcp:127.0.0.1:"
(number->string (hurd-vm-port config %hurd-vm-ssh-port))
- "-:2222"
+ "-:22"
",hostfwd=tcp:127.0.0.1:"
(number->string (hurd-vm-port config %hurd-vm-vnc-port))
"-:5900")))
@@ -1169,7 +1218,7 @@ is added to the OS specified in CONFIG."
"-m" (number->string #$memory-size)
#$@net-options
#$@options
- "--hda" #+image
+ "--hda" #+(system-image image)
;; Cause the service to be respawned if the guest
;; reboots (it can reboot for instance if it did not
@@ -1272,6 +1321,50 @@ is added to the OS specified in CONFIG."
(program-file "initialize-hurd-vm-substitutes" run))
+(define (authorize-guest-substitutes-on-host)
+ "Return a program that authorizes the guest's archive signing key (passed as
+an argument) on the host."
+ (define not-config?
+ (match-lambda
+ ('(guix config) #f)
+ (('guix _ ...) #t)
+ (('gnu _ ...) #t)
+ (_ #f)))
+
+ (define run
+ (with-extensions (list guile-gcrypt)
+ (with-imported-modules `(((guix config) => ,(make-config.scm))
+ ,@(source-module-closure
+ '((guix pki)
+ (guix build utils))
+ #:select? not-config?))
+ #~(begin
+ (use-modules (ice-9 match)
+ (ice-9 textual-ports)
+ (gcrypt pk-crypto)
+ (guix pki)
+ (guix build utils))
+
+ (match (command-line)
+ ((_ guest-config-directory)
+ (let ((guest-key (string-append guest-config-directory
+ "/signing-key.pub")))
+ (if (file-exists? guest-key)
+ ;; Add guest key to the host's ACL.
+ (let* ((key (string->canonical-sexp
+ (call-with-input-file guest-key
+ get-string-all)))
+ (acl (public-keys->acl
+ (cons key (acl->public-keys (current-acl))))))
+ (with-atomic-file-replacement %acl-file
+ (lambda (_ port)
+ (write-acl acl port))))
+ (format (current-error-port)
+ "warning: guest key missing from '~a'~%"
+ guest-key)))))))))
+
+ (program-file "authorize-guest-substitutes-on-host" run))
+
(define (hurd-vm-activation config)
"Return a gexp to activate the Hurd VM according to CONFIG."
(with-imported-modules '((guix build utils))
@@ -1287,15 +1380,71 @@ is added to the OS specified in CONFIG."
(define guix-directory
(string-append secret-directory "/etc/guix"))
+ (define offloading-ssh-key
+ #$(hurd-vm-configuration-offloading-ssh-key config))
+
(unless (file-exists? ssh-directory)
;; Generate SSH host keys under SSH-DIRECTORY.
(mkdir-p ssh-directory)
(invoke #$(file-append openssh "/bin/ssh-keygen")
"-A" "-f" secret-directory))
+ (unless (or (not #$(hurd-vm-configuration-offloading? config))
+ (file-exists? offloading-ssh-key))
+ ;; Generate a user SSH key pair for the host to use when offloading
+ ;; to the guest.
+ (mkdir-p (dirname offloading-ssh-key))
+ (invoke #$(file-append openssh "/bin/ssh-keygen")
+ "-t" "ed25519" "-N" ""
+ "-f" offloading-ssh-key)
+
+ ;; Authorize it in the guest for user 'offloading'.
+ (let ((authorizations
+ (string-append ssh-directory
+ "/authorized_keys.d/offloading")))
+ (mkdir-p (dirname authorizations))
+ (copy-file (string-append offloading-ssh-key ".pub")
+ authorizations)
+ (chmod (dirname authorizations) #o555)))
+
(unless (file-exists? guix-directory)
(invoke #$(initialize-hurd-vm-substitutes)
- guix-directory)))))
+ guix-directory))
+
+ (when #$(hurd-vm-configuration-offloading? config)
+ ;; Authorize the archive signing key from GUIX-DIRECTORY in the host.
+ (invoke #$(authorize-guest-substitutes-on-host) guix-directory)))))
+
+(define (hurd-vm-configuration-offloading-ssh-key config)
+ "Return the name of the file containing the SSH key of user 'offloading'."
+ (string-append "/etc/guix/offload/ssh/childhurd"
+ (or (and=> (hurd-vm-configuration-id config)
+ number->string)
+ "")))
+
+(define (hurd-vm-guix-extension config)
+ "When offloading is enabled, add this childhurd to the list of offlading
+machines in /etc/guix/machines.scm."
+ (if (hurd-vm-configuration-offloading? config)
+ (let* ((image (hurd-vm-configuration-image config))
+ (platform (image-platform image))
+ (system (platform-system platform))
+ (vm-ssh-key (string-append
+ (hurd-vm-configuration-secret-root config)
+ "/etc/ssh/ssh_host_ed25519_key.pub"))
+ (host-ssh-key (hurd-vm-configuration-offloading-ssh-key config)))
+ (guix-extension
+ (build-machines
+ (list #~(build-machine
+ (name "localhost")
+ (port #$(hurd-vm-port config %hurd-vm-ssh-port))
+ (systems '(#$system))
+ (host-key (call-with-input-file #$vm-ssh-key
+ (@ (ice-9 textual-ports)
+ get-string-all)))
+ (user "offloading")
+ (private-key #$host-ssh-key))))))
+ (guix-extension)))
(define hurd-vm-service-type
(service-type
@@ -1304,6 +1453,8 @@ is added to the OS specified in CONFIG."
hurd-vm-shepherd-service)
(service-extension account-service-type
(const %hurd-vm-accounts))
+ (service-extension guix-service-type
+ hurd-vm-guix-extension)
(service-extension activation-service-type
hurd-vm-activation)))
(default-value (hurd-vm-configuration))