Message ID | 274716c3156aa3290666ee3d33a2f1101d02d572.1716146775.git.go.wigust@gmail.com |
---|---|
State | New |
Headers | show |
Series | [bug#71071] services: nix: Mount Nix store read only. | expand |
Hello, Oleg Pykhalov <go.wigust@gmail.com> skribis: > * gnu/services/nix.scm (nix-shepherd-service): Mount Nix store read only. > (%nix-store-directory, %immutable-nix-store): New variables. > (%nix-store-prefix): New parameter. > (nix-activation): Move /nix/store provision to 'nix-shepherd-service'. > > Change-Id: I18a5d58c92c1f2b5b6dcecc3d5b439cc15bf4e49 That’s a good idea. Some suggestions: > +(define %nix-store-directory > + "/nix/store") > + > +(define %nix-store-prefix > + ;; Absolute path to the Nix store. > + (make-parameter %nix-store-directory)) I think you can omit this parameter and simply use ‘%nix-store-directory’ because… > +(define %immutable-nix-store > + ;; Read-only store to avoid users or daemons accidentally modifying it. > + ;; 'nix-daemon' has provisions to remount it read-write in its own name > + ;; space. > + #~(file-system > + (device #$(%nix-store-prefix)) > + (mount-point #$(%nix-store-prefix)) … the parameter is used at the top-level anyway, so changing its value won’t have any effect. > (start #~(make-forkexec-constructor > - (list (string-append #$package "/bin/nix-daemon") > - #$@extra-options) > + (list > + #$(program-file > + "nix-daemon-wrapper" > + (with-imported-modules (source-module-closure '((gnu build file-systems) > + (gnu system file-systems))) > + #~(begin > + (use-modules (gnu build file-systems) > + (gnu system file-systems) > + (guix build syscalls) > + (guix build utils)) > + (unless (member #$(%nix-store-prefix) (mount-points)) > + (mkdir-p "/nix/store") > + (chown "/nix/store" > + (passwd:uid (getpw "root")) > + (group:gid (getpw "nixbld01"))) > + (chmod "/nix/store" #o775) > + (mount-file-system #$%immutable-nix-store > + #:root "/")) > + (execl #$(file-append package "/bin/nix-daemon") > + "nix-daemon" #$@extra-options))))) > #:environment-variables > (list (string-append "TMPDIR=" #$build-directory) > "PATH=/run/current-system/profile/bin"))) Instead of having this wrapper, what about extending ‘file-system-service-type’ with a read-only bind-mount <file-system> similar to ‘%immutable-store’? The Shepherd service that spawns nix-daemon would depend on that file system: (requirement '(user-processes file-system-/nix/store)) Thanks, Ludo’.
diff --git a/gnu/services/nix.scm b/gnu/services/nix.scm index 82853253f6..343b42c13a 100644 --- a/gnu/services/nix.scm +++ b/gnu/services/nix.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2019, 2020, 2021 Oleg Pykhalov <go.wigust@gmail.com> +;;; Copyright © 2019, 2020, 2021, 2024 Oleg Pykhalov <go.wigust@gmail.com> ;;; Copyright © 2020 Peng Mei Yu <i@pengmeiyu.com> ;;; ;;; This file is part of GNU Guix. @@ -97,12 +97,9 @@ (define (nix-activation _) #~(begin (use-modules (guix build utils) (srfi srfi-26)) - (for-each (cut mkdir-p <>) '("/nix/store" "/nix/var/log" + (for-each (cut mkdir-p <>) '("/nix/var/log" "/nix/var/nix/gcroots/per-user" "/nix/var/nix/profiles/per-user")) - (chown "/nix/store" - (passwd:uid (getpw "root")) (group:gid (getpw "nixbld01"))) - (chmod "/nix/store" #o775) (for-each (cut chmod <> #o777) '("/nix/var/nix/profiles" "/nix/var/nix/profiles/per-user")))) @@ -129,6 +126,24 @@ (define nix-service-etc '#$build-sandbox-items)) (for-each (cut display <>) '#$extra-config))))))))))) +(define %nix-store-directory + "/nix/store") + +(define %nix-store-prefix + ;; Absolute path to the Nix store. + (make-parameter %nix-store-directory)) + +(define %immutable-nix-store + ;; Read-only store to avoid users or daemons accidentally modifying it. + ;; 'nix-daemon' has provisions to remount it read-write in its own name + ;; space. + #~(file-system + (device #$(%nix-store-prefix)) + (mount-point #$(%nix-store-prefix)) + (type "none") + (check? #f) + (flags '(read-only bind-mount)))) + (define nix-shepherd-service ;; Return a <shepherd-service> for Nix. (match-lambda @@ -139,8 +154,26 @@ (define nix-shepherd-service (documentation "Run nix-daemon.") (requirement '()) (start #~(make-forkexec-constructor - (list (string-append #$package "/bin/nix-daemon") - #$@extra-options) + (list + #$(program-file + "nix-daemon-wrapper" + (with-imported-modules (source-module-closure '((gnu build file-systems) + (gnu system file-systems))) + #~(begin + (use-modules (gnu build file-systems) + (gnu system file-systems) + (guix build syscalls) + (guix build utils)) + (unless (member #$(%nix-store-prefix) (mount-points)) + (mkdir-p "/nix/store") + (chown "/nix/store" + (passwd:uid (getpw "root")) + (group:gid (getpw "nixbld01"))) + (chmod "/nix/store" #o775) + (mount-file-system #$%immutable-nix-store + #:root "/")) + (execl #$(file-append package "/bin/nix-daemon") + "nix-daemon" #$@extra-options))))) #:environment-variables (list (string-append "TMPDIR=" #$build-directory) "PATH=/run/current-system/profile/bin")))