Package: guix-patches;
Reported by: Mike Gerwitz <mtg <at> gnu.org>
Date: Fri, 26 Jan 2018 03:31:04 UTC
Severity: normal
Tags: fixed, patch
Done: ludo <at> gnu.org (Ludovic Courtès)
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 30257 in the body.
You can then email your comments to 30257 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
guix-patches <at> gnu.org
:bug#30257
; Package guix-patches
.
(Fri, 26 Jan 2018 03:31:04 GMT) Full text and rfc822 format available.Mike Gerwitz <mtg <at> gnu.org>
:guix-patches <at> gnu.org
.
(Fri, 26 Jan 2018 03:31:04 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Mike Gerwitz <mtg <at> gnu.org> To: guix-patches <at> gnu.org Subject: [PATCH 2/3] scripts: environment: Add --user. Date: Thu, 25 Jan 2018 22:29:32 -0500
[Message part 1 (text/plain, inline)]
This change allows overriding the home directory of all filesystem mappings to help hide the identity of the calling user in a container. * doc/guix.texi (Invoking guix environment)[--container]: Mention --user. [--user]: Add item. * guix/scripts/environment.scm (show-help): Add --user. (%options): Add --user. (launch-environment/container) Add 'user' parameter. Update doc. Override 'user-mappings' using 'override-user-mappings'. Consider override for chdir. (mock-passwd, user-override-home, overrid-euser-dir): New procedures. (guix-environment): Disallow --user without --container. Provide user to 'launch-environment/container'. * tests/guix-environment.sh: Add user test. --- doc/guix.texi | 34 ++++++++++-- guix/scripts/environment.scm | 122 ++++++++++++++++++++++++++++++++++--------- tests/guix-environment.sh | 10 ++++ 3 files changed, 137 insertions(+), 29 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 3b6ae1ab9..8218c6637 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -7156,10 +7156,11 @@ Attempt to build for @var{system}---e.g., @code{i686-linux}. @cindex container Run @var{command} within an isolated container. The current working directory outside the container is mapped inside the container. -Additionally, a dummy home directory is created that matches the current -user's home directory, and @file{/etc/passwd} is configured accordingly. -The spawned process runs as the current user outside the container, but -has root privileges in the context of the container. +Additionally, unless overridden with @code{--user}, a dummy home +directory is created that matches the current user's home directory, and +@file{/etc/passwd} is configured accordingly. The spawned process runs +as the current user outside the container, but has root privileges in +the context of the container. @item --network @itemx -N @@ -7183,6 +7184,31 @@ example, the @code{fontconfig} package inspects @code{--link-profile} allows these programs to behave as expected within the environment. +@item --user=@var{user} +@itemx -u @var{user} +For containers, use the username @var{user} in place of the current +user. The generated @file{/etc/passwd} entry within the container will +contain the name @var{user}; the home directory will be +@file{/home/USER}; and no user GECOS data will be copied. @var{user} +need not exist on the system. + +Additionally, any shared or exposed path (see @code{--share} and +@code{--expose} respectively) whose target is within the current user's +home directory will be remapped relative to @file{/home/USER}; this +includes the automatic mapping of the current working directory. + +@example +# will expose paths as /home/foo/wd, /home/foo/test, and /home/foo/target +cd $HOME/wd +guix environment --container --user=foo \ + --expose=$HOME/test \ + --expose=/tmp/target=$HOME/target +@end example + +While this will limit the leaking of user identity through home paths +and each of the user fields, this is only one useful component of a +broader privacy/anonymity solution---not one in and of itself. + @item --expose=@var{source}[=@var{target}] For containers, expose the file system @var{source} from the host system as the read-only file system @var{target} within the container. If diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index 771574c15..f50018faf 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -161,6 +161,10 @@ COMMAND or an interactive shell in that environment.\n")) (display (G_ " -P, --link-profile link environment profile to ~/.guix-profile within an isolated container")) + (display (G_ " + -u, --user=USER instead of copying the name and home of the current + user into an isolated container, use the name USER + with home directory /home/USER")) (display (G_ " --share=SPEC for containers, share writable host file system according to SPEC")) @@ -243,6 +247,10 @@ COMMAND or an interactive shell in that environment.\n")) (option '(#\P "link-profile") #f #f (lambda (opt name arg result) (alist-cons 'link-profile? #t result))) + (option '(#\u "user") #t #f + (lambda (opt name arg result) + (alist-cons 'user arg + (alist-delete 'user result eq?)))) (option '("share") #t #f (lambda (opt name arg result) (alist-cons 'file-system-mapping @@ -390,43 +398,50 @@ environment variables are cleared before setting the new ones." (pid (match (waitpid pid) ((_ . status) status))))) -(define* (launch-environment/container #:key command bash user-mappings +(define* (launch-environment/container #:key command bash user user-mappings profile paths link-profile? network?) "Run COMMAND within a container that features the software in PROFILE. Environment variables are set according to PATHS, a list of native search paths. The global shell is BASH, a file name for a GNU Bash binary in the store. When NETWORK?, access to the host system network is permitted. USER-MAPPINGS, a list of file system mappings, contains the user-specified -host file systems to mount inside the container. LINK-PROFILE? creates a -symbolic link from ~/.guix-profile to the environment profile." +host file systems to mount inside the container. If USER is not #f, each +target of USER-MAPPINGS will be re-written relative to '/home/USER', and USER +will be used for the passwd entry. LINK-PROFILE? creates a symbolic link from +~/.guix-profile to the environment profile." (mlet %store-monad ((reqs (inputs->requisites (list (direct-store-path bash) profile)))) (return (let* ((cwd (getcwd)) - (passwd (getpwuid (getuid))) + (home (getenv "HOME")) + (passwd (mock-passwd (getpwuid (getuid)) + user + bash)) (home-dir (passwd:dir passwd)) ;; Bind-mount all requisite store items, user-specified mappings, ;; /bin/sh, the current working directory, and possibly networking ;; configuration files within the container. (mappings - (append user-mappings - ;; Current working directory. - (list (file-system-mapping - (source cwd) - (target cwd) - (writable? #t))) - ;; When in Rome, do as Nix build.cc does: Automagically - ;; map common network configuration files. - (if network? - %network-file-mappings - '()) - ;; Mappings for the union closure of all inputs. - (map (lambda (dir) - (file-system-mapping - (source dir) - (target dir) - (writable? #f))) - reqs))) + (override-user-mappings + user home + (append user-mappings + ;; Current working directory. + (list (file-system-mapping + (source cwd) + (target cwd) + (writable? #t))) + ;; When in Rome, do as Nix build.cc does: Automagically + ;; map common network configuration files. + (if network? + %network-file-mappings + '()) + ;; Mappings for the union closure of all inputs. + (map (lambda (dir) + (file-system-mapping + (source dir) + (target dir) + (writable? #f))) + reqs)))) (file-systems (append %container-file-systems (map file-system-mapping->bind-mount mappings)))) @@ -447,8 +462,7 @@ symbolic link from ~/.guix-profile to the environment profile." ;; The same variables as in Nix's 'build.cc'. '("TMPDIR" "TEMPDIR" "TMP" "TEMP")) - ;; Create a dummy home directory under the same name as on the - ;; host. + ;; Create a dummy home directory. (mkdir-p home-dir) (setenv "HOME" home-dir) @@ -475,7 +489,7 @@ symbolic link from ~/.guix-profile to the environment profile." ;; For convenience, start in the user's current working ;; directory rather than the root directory. - (chdir cwd) + (chdir (override-user-dir user home cwd)) (primitive-exit/status ;; A container's environment is already purified, so no need to @@ -485,6 +499,60 @@ symbolic link from ~/.guix-profile to the environment profile." (delq 'net %namespaces) ; share host network %namespaces))))))) +(define (mock-passwd passwd user-override shell) + "Generate mock information for '/etc/passwd'. If USER-OVERRIDE is not '#f', +it is expected to be a string representing the mock username; it will produce +a user of that name, with a home directory of '/home/USER-OVERRIDE', and no +GECOS field. If USER-OVERRIDE is '#f', data will be inherited from PASSWD. +In either case, the shadow password and UID/GID are cleared, since the user +runs as root within the container. SHELL will always be used in place of the +shell in PASSWD. + +The resulting vector is suitable for use with Guile's POSIX user procedures. + +See passwd(5) for more information each of the fields." + (if user-override + (vector + user-override + "x" "0" "0" ;; no shadow, user is now root + "" ;; no personal information + (user-override-home user-override) + shell) + (vector + (passwd:name passwd) + "x" "0" "0" ;; no shadow, user is now root + (passwd:gecos passwd) + (passwd:dir passwd) + shell))) + +(define (user-override-home user) + "Return home directory for override user USER." + (string-append "/home/" user)) + +(define (override-user-mappings user home mappings) + "If a username USER is provided, rewrite each HOME prefix in file system +mappings MAPPINGS to a home directory determined by 'override-user-dir'; +otherwise, return MAPPINGS." + (if (not user) + mappings + (map (lambda (mapping) + (let ((target (file-system-mapping-target mapping))) + (if (string-prefix? home target) + (file-system-mapping + (source (file-system-mapping-source mapping)) + (target (override-user-dir user home target)) + (writable? (file-system-mapping-writable? mapping))) + mapping))) + mappings))) + +(define (override-user-dir user home dir) + "If username USER is provided, overwrite string prefix HOME in DIR with a +directory determined by 'user-override-home'; otherwise, return DIR." + (if (and user (string-prefix? home dir)) + (string-append (user-override-home user) + (substring dir (string-length home))) + dir)) + (define (link-environment profile home-dir) "Create a symbolic link from HOME-DIR/.guix-profile to PROFILE." (let ((profile-dir (string-append home-dir "/.guix-profile"))) @@ -572,6 +640,7 @@ message if any test fails." (container? (assoc-ref opts 'container?)) (link-prof? (assoc-ref opts 'link-profile?)) (network? (assoc-ref opts 'network?)) + (user (assoc-ref opts 'user)) (bootstrap? (assoc-ref opts 'bootstrap?)) (system (assoc-ref opts 'system)) (command (or (assoc-ref opts 'exec) @@ -606,6 +675,8 @@ message if any test fails." (when (and (not container?) link-prof?) (leave (G_ "--link-prof cannot be used without --container~%"))) + (when (and (not container?) user) + (leave (G_ "--user cannot be used without --container~%"))) (with-store store (set-build-options-from-command-line store opts) @@ -653,6 +724,7 @@ message if any test fails." "/bin/sh")))) (launch-environment/container #:command command #:bash bash-binary + #:user user #:user-mappings mappings #:profile profile #:paths paths diff --git a/tests/guix-environment.sh b/tests/guix-environment.sh index e995636df..a1ce96579 100644 --- a/tests/guix-environment.sh +++ b/tests/guix-environment.sh @@ -74,6 +74,16 @@ guix environment --bootstrap --ad-hoc guile-bootstrap --pure \ -- guile -c "$linktest" ) +# Test that user can be mocked. +usertest='(exit (and (string=? (getenv "HOME") "/home/foognu") + (string=? (passwd:name (getpwuid 0)) "foognu") + (file-exists? "/home/foognu/umock")))' +touch "$tmpdir/umock" +HOME="$tmpdir" guix environment --bootstrap --container --user=foognu \ + --ad-hoc guile-bootstrap --pure \ + --share="$tmpdir/umock" \ + -- guile -c "$usertest" + # Make sure '-r' works as expected. rm -f "$gcroot" expected="`guix environment --bootstrap --ad-hoc guile-bootstrap \ -- 2.15.1
[signature.asc (application/pgp-signature, inline)]
guix-patches <at> gnu.org
:bug#30257
; Package guix-patches
.
(Fri, 02 Mar 2018 10:34:01 GMT) Full text and rfc822 format available.Message #8 received at 30257 <at> debbugs.gnu.org (full text, mbox):
From: ludo <at> gnu.org (Ludovic Courtès) To: Mike Gerwitz <mtg <at> gnu.org> Cc: 30257 <at> debbugs.gnu.org Subject: Re: [bug#30257] [PATCH 2/3] scripts: environment: Add --user. Date: Fri, 02 Mar 2018 11:33:45 +0100
Mike Gerwitz <mtg <at> gnu.org> skribis: > This change allows overriding the home directory of all filesystem mappings to > help hide the identity of the calling user in a container. > > * doc/guix.texi (Invoking guix environment)[--container]: Mention --user. > [--user]: Add item. > * guix/scripts/environment.scm (show-help): Add --user. > (%options): Add --user. > (launch-environment/container) Add 'user' parameter. Update doc. Override > 'user-mappings' using 'override-user-mappings'. Consider override for chdir. > (mock-passwd, user-override-home, overrid-euser-dir): New procedures. > (guix-environment): Disallow --user without --container. Provide user to > 'launch-environment/container'. > * tests/guix-environment.sh: Add user test. Awesome, I moved the test to guix-environment-container.sh and applied. Ludo’.
ludo <at> gnu.org (Ludovic Courtès)
to control <at> debbugs.gnu.org
.
(Sat, 03 Mar 2018 21:22:02 GMT) Full text and rfc822 format available.ludo <at> gnu.org (Ludovic Courtès)
to control <at> debbugs.gnu.org
.
(Sat, 03 Mar 2018 21:22:02 GMT) Full text and rfc822 format available.Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Sun, 01 Apr 2018 11:24:04 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.