From fa44e401a8ca5cddc2c5506984f0cd476e0b7d57 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 31 Oct 2007 18:01:56 +0000 Subject: [PATCH] * Documented multi-user Nix. --- doc/manual/env-common.xml | 11 ++ doc/manual/installation.xml | 248 +++++++++++++++++++++++++++++++----- doc/manual/nix-env.xml | 43 ++++--- doc/manual/opt-inst-syn.xml | 15 +++ src/libexpr/primops.cc | 3 + 5 files changed, 274 insertions(+), 46 deletions(-) create mode 100644 doc/manual/opt-inst-syn.xml diff --git a/doc/manual/env-common.xml b/doc/manual/env-common.xml index 89ee78c76..fdfbaf59a 100644 --- a/doc/manual/env-common.xml +++ b/doc/manual/env-common.xml @@ -263,6 +263,17 @@ $ mount -o bind /mnt/otherdisk/nix /nix +NIX_REMOTE + + This variable should be set to + daemon if you want to use the Nix daemon to + executed Nix operations, which is necessary in multi-user Nix installations. + Otherwise, it should be left unset. + + + + diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index 3a143e44f..72e4b541a 100644 --- a/doc/manual/installation.xml +++ b/doc/manual/installation.xml @@ -100,14 +100,16 @@ ubiquitous 2.5.4a won't. Note that these are only required if you modify the parser or when you are building from the Subversion repository. -Nix uses Sleepycat's Berkeley DB and CWI's ATerm library. These -are included in the Nix source distribution. If you build from the -Subversion repository, you must download them yourself and place them -in the externals/ directory. See +Nix uses Sleepycat's Berkeley DB, CWI's ATerm library and the +bzip2 compressor (including the bzip2 library). These are included in +the Nix source distribution. If you build from the Subversion +repository, you must download them yourself and place them in the +externals/ directory. See externals/Makefile.am for the precise URLs of these packages. Alternatively, if you already have them installed, -you can use configure's -and options to point to their respective +you can use configure's +, and + options to point to their respective locations. Note that Berkeley DB must be version 4.5; other versions may not have compatible database formats. @@ -118,19 +120,21 @@ locations. Note that Berkeley DB must be version After unpacking or checking out the Nix sources, issue the following commands: - $ ./configure options... $ make $ make install + + When building from the Subversion repository, these should be preceded by the command: - -$ ./boostrap +$ ./bootstrap + + The installation path can be specified by passing the to @@ -165,20 +169,24 @@ Hat Linux. They have been known to work work on SuSE Linux 8.1 and distribution based on glibc 2.3 or later. Once downloaded, the RPMs can be installed or upgraded using -rpm -U. For example, +rpm -U. For example, $ rpm -U nix-0.5pre664-1.i386.rpm + + The RPMs install into the directory /nix. Nix can be uninstalled using rpm -e nix. After this it will be necessary to manually remove the Nix store and other -auxiliary data: +auxiliary data: $ rm -rf /nix/store $ rm -rf /nix/var + + @@ -187,7 +195,7 @@ $ rm -rf /nix/var You can install the latest stable version of Nix through Nix itself by subscribing to the channel , -or the latest unstable version by subscribing to the channel. You can also do a one-click installation by clicking on the package links at root all the time. -
Multi-user mode +
Multi-user mode - +To allow a Nix store to be shared safely among multiple users, +it is important that users are not able to run builders that modify +the Nix store or database in arbitrary ways, or that interfere with +builds started by other users. If they could do so, they could +install a Trojan horse in some package and compromise the accounts of +other users. - - +To prevent this, the Nix store and database are owned by some +privileged user (usually root) and builders are +executed under special user accounts (usually named +nixbld1, nixbld2, etc.). When a +unprivileged user runs a Nix command, actions that operate on the Nix +store (such as builds) are forwarded to a Nix +daemon running under the owner of the Nix store/database +that performs the operation. Multi-user mode has one important limitation: only root can run nix-pull to register the availability -of pre-built binaries. However, those registrations -are used by all users to speed up -builds. +of pre-built binaries. However, those registrations are shared by all +users, so they still get the benefit from nix-pulls +done by root. + + +
Setting up the build users + +The build users are the special UIDs under +which builds are performed. They should all be members of the +build users group (usually called +nixbld). This group should have no other members. +The build users should not be members of any other group. + +Here is a typical /etc/group definition of +the build users group with 10 build users: + + +nixbld:!:30000:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10 + + +In this example the nixbld group has UID 30000, but +of course it can be anything that doesn’t collide with an existing +group. + +Here is the corresponding part of +/etc/passwd: + + +nixbld1:x:30001:65534:Nix build user 1:/var/empty:/noshell +nixbld2:x:30002:65534:Nix build user 2:/var/empty:/noshell +nixbld3:x:30003:65534:Nix build user 3:/var/empty:/noshell +... +nixbld10:x:30010:65534:Nix build user 10:/var/empty:/noshell + + +The home directory of the build users should not exist or should be an +empty directory to which they do not have write access. + +The build users should have write access to the Nix store, but +they should not have the right to delete files. Thus the Nix store’s +group should be the build users group, and it should have the sticky +bit turned on (like /tmp): + + +$ chgrp nixbld /nix/store +$ chmod 1777 /nix/store + + + + +Finally, you should tell Nix to use the build users by +specifying the build users group in the build-users-group +option in the Nix configuration +file (/nix/etc/nix/nix.conf): + + +build-users-group = nixbld + + +
-
+
Nix store/database owned by root + +The simplest setup is to let root own the Nix +store and database. I.e., + + +$ chown -R root /nix/store /nix/var/nix + + + +The Nix daemon should be started as follows (as +root): + + +$ nix-worker --daemon + +You’ll want to put that line somewhere in your system’s boot +scripts. + +To let unprivileged users use the daemon, they should set the +NIX_REMOTE environment +variable to daemon. So you should put a +line like + + +export NIX_REMOTE=daemon + +into the users’ login scripts. + +
+ + +
Nix store/database not owned by root + +It is also possible to let the Nix store and database be owned +by a non-root user, which should be more secureNote +however that even when the Nix daemon runs as root, not +that much code is executed as root: Nix +expression evaluation is performed by the calling (unprivileged) user, +and builds are performed under the special build user accounts. So +only the code that accesses the database and starts builds is executed +as root.. Typically, this user +is a special account called nix, but it can be +named anything. It should own the Nix store and database: + + +$ chown -R root /nix/store /nix/var/nix + +and of course nix-worker --daemon should be started +under that user, e.g., + + +$ su - nix -c "exec /nix/bin/nix-worker --daemon" + + + +There is a catch, though: non-root users +cannot start builds under the build user accounts, since the +setuid system call is obviously privileged. To +allow a non-root Nix daemon to use the build user +feature, it calls a setuid-root helper program, +nix-setuid-helper. This program is installed in +prefix/libexec/nix-setuid-helper. +To set the permissions properly (Nix’s make install +doesn’t do this, since we don’t want to ship setuid-root programs +out-of-the-box): + + +$ chown root.root /nix/libexec/nix-setuid-helper +$ chmod 4755 /nix/libexec/nix-setuid-helper + + +(This example assumes that the Nix binaries are installed in +/nix.) + +Of course, the nix-setuid-helper command +should not be usable by just anybody, since then anybody could run +commands under the Nix build user accounts. For that reason there is +a configuration file /etc/nix-setuid.conf that +restricts the use of the helper. This file should be a text file +containing precisely two lines, the first being the Nix daemon user +and the second being the build users group, e.g., + + +nix +nixbld + + +The setuid-helper barfs if it is called by a user other than the one +specified on the first line, or if it is asked to execute a build +under a user who is not a member of the group specified on the second +line. The file /etc/nix-setuid.conf must be +owned by root, and must not be group- or world-writable. The +setuid-helper barfs if this is not the case. + +
+ + +
Restricting access + +To limit which users can perform Nix operations, you can use the +permissions on the directory +/nix/var/nix/daemon-socket. For instance, if you +want to restrict the use of Nix to the members of a group called +nix-users, do + + +$ chgrp nix-users /nix/var/nix/daemon-socket +$ chmod ug=rwx,o= /nix/var/nix/daemon-socket + + +This way, users who are not in the nix-users group +cannot connect to the Unix domain socket +/nix/var/nix/daemon-socket/socket, so they cannot +perform Nix operations. + +
+ + +
+ + +
Using Nix diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml index 9b9127921..9af8c0c02 100644 --- a/doc/manual/nix-env.xml +++ b/doc/manual/nix-env.xml @@ -19,13 +19,6 @@ nix-env name value - - - - - - attrPath - @@ -45,9 +38,6 @@ system - - - path operation options arguments @@ -190,6 +180,7 @@ linkend="sec-common-options" />. + @@ -397,6 +388,7 @@ the following paths will be substituted: + @@ -592,25 +584,21 @@ $ nix-env -e '*' (remove everything) - + + - - - - - - + @@ -622,6 +610,27 @@ $ nix-env -e '*' (remove everything) + + + + + + + + + + + + + + + + + attribute-path + + + + names diff --git a/doc/manual/opt-inst-syn.xml b/doc/manual/opt-inst-syn.xml new file mode 100644 index 000000000..1c32325e5 --- /dev/null +++ b/doc/manual/opt-inst-syn.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + path + + diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index b9ba3da64..2a96e25a8 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -789,6 +789,7 @@ static Expr prim_listToAttrs(EvalState & state, const ATermVector & args) } } + static Expr prim_removeAttrs(EvalState & state, const ATermVector & args) { ATermMap attrs; @@ -803,6 +804,7 @@ static Expr prim_removeAttrs(EvalState & state, const ATermVector & args) return makeAttrs(attrs); } + /* Determine whether the argument is a list. */ static Expr prim_isAttrs(EvalState & state, const ATermVector & args) { @@ -810,6 +812,7 @@ static Expr prim_isAttrs(EvalState & state, const ATermVector & args) return makeBool(matchAttrs(evalExpr(state, args[0]), list)); } + /************************************************************* * Lists *************************************************************/