diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2007-10-31T18·01+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2007-10-31T18·01+0000 |
commit | fa44e401a8ca5cddc2c5506984f0cd476e0b7d57 (patch) | |
tree | 8af89b26ceb3d48deaeb14ad173585c48d26ff44 | |
parent | e007b50eb7ba070c039fc438f49a72bd248e1b5c (diff) |
* Documented multi-user Nix.
-rw-r--r-- | doc/manual/env-common.xml | 11 | ||||
-rw-r--r-- | doc/manual/installation.xml | 248 | ||||
-rw-r--r-- | doc/manual/nix-env.xml | 43 | ||||
-rw-r--r-- | doc/manual/opt-inst-syn.xml | 15 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 3 |
5 files changed, 274 insertions, 46 deletions
diff --git a/doc/manual/env-common.xml b/doc/manual/env-common.xml index 89ee78c76806..fdfbaf59ab2b 100644 --- a/doc/manual/env-common.xml +++ b/doc/manual/env-common.xml @@ -263,6 +263,17 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen> </varlistentry> +<varlistentry xml:id="envar-remote"><term><envar>NIX_REMOTE</envar></term> + + <listitem><para>This variable should be set to + <literal>daemon</literal> if you want to use the Nix daemon to + executed Nix operations, which is necessary in <link + linkend="ssec-multi-user">multi-user Nix installations</link>. + Otherwise, it should be left unset.</para></listitem> + +</varlistentry> + + </variablelist> diff --git a/doc/manual/installation.xml b/doc/manual/installation.xml index 3a143e44fd5e..72e4b541a07e 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.</para> -<para>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 <filename>externals/</filename> directory. See +<para>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 +<filename>externals/</filename> directory. See <filename>externals/Makefile.am</filename> for the precise URLs of these packages. Alternatively, if you already have them installed, -you can use <command>configure</command>'s <option>--with-bdb</option> -and <option>--with-aterm</option> options to point to their respective +you can use <command>configure</command>'s +<option>--with-bdb</option>, <option>--with-aterm</option> and +<option>--with-bzip2</option> options to point to their respective locations. Note that Berkeley DB <emphasis>must</emphasis> be version 4.5; other versions may not have compatible database formats.</para> @@ -118,19 +120,21 @@ locations. Note that Berkeley DB <emphasis>must</emphasis> be version <para>After unpacking or checking out the Nix sources, issue the following commands: - </para> <screen> $ ./configure <replaceable>options...</replaceable> $ make $ make install</screen> +</para> + <para>When building from the Subversion repository, these should be preceded by the command: - </para> <screen> -$ ./boostrap</screen> +$ ./bootstrap</screen> + +</para> <para>The installation path can be specified by passing the <option>--prefix=<replaceable>prefix</replaceable></option> to @@ -165,20 +169,24 @@ Hat Linux. They have been known to work work on SuSE Linux 8.1 and distribution based on <literal>glibc</literal> 2.3 or later.</para> <para>Once downloaded, the RPMs can be installed or upgraded using -<command>rpm -U</command>. For example,</para> +<command>rpm -U</command>. For example, <screen> $ rpm -U nix-0.5pre664-1.i386.rpm</screen> +</para> + <para>The RPMs install into the directory <filename>/nix</filename>. Nix can be uninstalled using <command>rpm -e nix</command>. After this it will be necessary to manually remove the Nix store and other -auxiliary data:</para> +auxiliary data: <screen> $ rm -rf /nix/store $ rm -rf /nix/var</screen> +</para> + </section> @@ -187,7 +195,7 @@ $ rm -rf /nix/var</screen> <para>You can install the latest stable version of Nix through Nix itself by subscribing to the channel <link xlink:href="http://nix.cs.uu.nl/dist/nix/channels-v3/nix-stable" />, -or the latest unstable version by subscribing to the channel<link +or the latest unstable version by subscribing to the channel <link xlink:href="http://nix.cs.uu.nl/dist/nix/channels-v3/nix-unstable" />. You can also do a <link linkend="sec-one-click">one-click installation</link> by clicking on the package links at <link @@ -231,33 +239,215 @@ class="username">root</systemitem> all the time.</para> </section> -<section><title>Multi-user mode</title> - -<para></para> +<section xml:id="ssec-multi-user"><title>Multi-user mode</title> +<para>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.</para> -<!-- - -warning: the nix-builders group should contain *only* the Nix -builders, and nothing else. If the Nix account is compromised, you -can execute programs under the accounts in the nix-builders group, so -it obviously shouldn’t contain any “real” user accounts. So don’t use -an existing group like <literal>users</literal> — just create a new -one. - ---> +<para>To prevent this, the Nix store and database are owned by some +privileged user (usually <literal>root</literal>) and builders are +executed under special user accounts (usually named +<literal>nixbld1</literal>, <literal>nixbld2</literal>, etc.). When a +unprivileged user runs a Nix command, actions that operate on the Nix +store (such as builds) are forwarded to a <emphasis>Nix +daemon</emphasis> running under the owner of the Nix store/database +that performs the operation.</para> <note><para>Multi-user mode has one important limitation: only <systemitem class="username">root</systemitem> can run <command linkend="sec-nix-pull">nix-pull</command> to register the availability -of pre-built binaries. However, those registrations -<emphasis>are</emphasis> used by all users to speed up -builds.</para></note> +of pre-built binaries. However, those registrations are shared by all +users, so they still get the benefit from <command>nix-pull</command>s +done by <systemitem class="username">root</systemitem>.</para></note> + + +<section><title>Setting up the build users</title> + +<para>The <emphasis>build users</emphasis> are the special UIDs under +which builds are performed. They should all be members of the +<emphasis>build users group</emphasis> (usually called +<literal>nixbld</literal>). This group should have no other members. +The build users should not be members of any other group.</para> + +<para>Here is a typical <filename>/etc/group</filename> definition of +the build users group with 10 build users: + +<programlisting> +nixbld:!:30000:nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10 +</programlisting> + +In this example the <literal>nixbld</literal> group has UID 30000, but +of course it can be anything that doesn’t collide with an existing +group.</para> + +<para>Here is the corresponding part of +<filename>/etc/passwd</filename>: + +<programlisting> +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 +</programlisting> + +The home directory of the build users should not exist or should be an +empty directory to which they do not have write access.</para> + +<para>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 <filename>/tmp</filename>): + +<screen> +$ chgrp nixbld /nix/store +$ chmod 1777 /nix/store +</screen> + +</para> + +<para>Finally, you should tell Nix to use the build users by +specifying the build users group in the <link +linkend="conf-build-users-group"><literal>build-users-group</literal> +option</link> in the <link linkend="sec-conf-file">Nix configuration +file</link> (<literal>/nix/etc/nix/nix.conf</literal>): + +<programlisting> +build-users-group = nixbld +</programlisting> + +</para> + +</section> + + +<section><title>Nix store/database owned by root</title> + +<para>The simplest setup is to let <literal>root</literal> own the Nix +store and database. I.e., + +<screen> +$ chown -R root /nix/store /nix/var/nix</screen> + +</para> + +<para>The Nix daemon should be started as follows (as +<literal>root</literal>): + +<screen> +$ nix-worker --daemon</screen> + +You’ll want to put that line somewhere in your system’s boot +scripts.</para> + +<para>To let unprivileged users use the daemon, they should set the +<link linkend="envar-remote"><envar>NIX_REMOTE</envar> environment +variable</link> to <literal>daemon</literal>. So you should put a +line like + +<programlisting> +export NIX_REMOTE=daemon</programlisting> + +into the users’ login scripts.</para> </section> -</section> <!-- end of permissions section --> +<section><title>Nix store/database not owned by root</title> + +<para>It is also possible to let the Nix store and database be owned +by a non-root user, which should be more secure<footnote><para>Note +however that even when the Nix daemon runs as root, not +<emphasis>that</emphasis> 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 <literal>root</literal>.</para></footnote>. Typically, this user +is a special account called <literal>nix</literal>, but it can be +named anything. It should own the Nix store and database: + +<screen> +$ chown -R root /nix/store /nix/var/nix</screen> + +and of course <command>nix-worker --daemon</command> should be started +under that user, e.g., + +<screen> +$ su - nix -c "exec /nix/bin/nix-worker --daemon"</screen> + +</para> + +<para>There is a catch, though: non-<literal>root</literal> users +cannot start builds under the build user accounts, since the +<function>setuid</function> system call is obviously privileged. To +allow a non-<literal>root</literal> Nix daemon to use the build user +feature, it calls a setuid-root helper program, +<command>nix-setuid-helper</command>. This program is installed in +<filename><replaceable>prefix</replaceable>/libexec/nix-setuid-helper</filename>. +To set the permissions properly (Nix’s <command>make install</command> +doesn’t do this, since we don’t want to ship setuid-root programs +out-of-the-box): + +<screen> +$ chown root.root /nix/libexec/nix-setuid-helper +$ chmod 4755 /nix/libexec/nix-setuid-helper +</screen> + +(This example assumes that the Nix binaries are installed in +<filename>/nix</filename>.)</para> + +<para>Of course, the <command>nix-setuid-helper</command> 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 <filename>/etc/nix-setuid.conf</filename> 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., + +<programlisting> +nix +nixbld +</programlisting> + +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 <filename>/etc/nix-setuid.conf</filename> must be +owned by root, and must not be group- or world-writable. The +setuid-helper barfs if this is not the case.</para> + +</section> + + +<section><title>Restricting access</title> + +<para>To limit which users can perform Nix operations, you can use the +permissions on the directory +<filename>/nix/var/nix/daemon-socket</filename>. For instance, if you +want to restrict the use of Nix to the members of a group called +<literal>nix-users</literal>, do + +<screen> +$ chgrp nix-users /nix/var/nix/daemon-socket +$ chmod ug=rwx,o= /nix/var/nix/daemon-socket +</screen> + +This way, users who are not in the <literal>nix-users</literal> group +cannot connect to the Unix domain socket +<filename>/nix/var/nix/daemon-socket/socket</filename>, so they cannot +perform Nix operations.</para> + +</section> + + +</section> <!-- end of multi-user --> + + +</section> <!-- end of security --> <section><title>Using Nix</title> diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml index 9b9127921170..9af8c0c022dc 100644 --- a/doc/manual/nix-env.xml +++ b/doc/manual/nix-env.xml @@ -21,13 +21,6 @@ <arg><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></arg> <arg> <group choice='req'> - <arg choice='plain'><option>--attr</option></arg> - <arg choice='plain'><option>-A</option></arg> - </group> - <replaceable>attrPath</replaceable> - </arg> - <arg> - <group choice='req'> <arg choice='plain'><option>--file</option></arg> <arg choice='plain'><option>-f</option></arg> </group> @@ -45,9 +38,6 @@ <replaceable>system</replaceable> </arg> <arg><option>--dry-run</option></arg> - <arg><option>--from-expression</option></arg> - <arg><option>-E</option></arg> - <arg><option>--from-profile</option> <replaceable>path</replaceable></arg> <arg choice='plain'><replaceable>operation</replaceable></arg> <arg rep='repeat'><replaceable>options</replaceable></arg> <arg rep='repeat'><replaceable>arguments</replaceable></arg> @@ -190,6 +180,7 @@ linkend="sec-common-options" />.</para> <arg choice='plain'><option>--install</option></arg> <arg choice='plain'><option>-i</option></arg> </group> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-inst-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" /> <group choice='opt'> <arg choice='plain'><option>--preserve-installed</option></arg> <arg choice='plain'><option>-P</option></arg> @@ -397,6 +388,7 @@ the following paths will be substituted: <arg choice='plain'><option>--upgrade</option></arg> <arg choice='plain'><option>-u</option></arg> </group> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="opt-inst-syn.xml#xmlns(db=http://docbook.org/ns/docbook)xpointer(/db:nop/*)" /> <group choice='opt'> <arg choice='plain'><option>--lt</option></arg> <arg choice='plain'><option>--leq</option></arg> @@ -592,25 +584,21 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen> <arg choice='plain'><option>--query</option></arg> <arg choice='plain'><option>-q</option></arg> </group> - <arg><option>--xml</option></arg> <group choice='opt'> <arg choice='plain'><option>--installed</option></arg> <arg choice='plain'><option>--available</option></arg> <arg choice='plain'><option>-a</option></arg> </group> + <sbr /> + <arg> <group choice='req'> <arg choice='plain'><option>--status</option></arg> <arg choice='plain'><option>-s</option></arg> </group> </arg> - <arg> - <group choice='req'> - <arg choice='plain'><option>--attr</option></arg> - <arg choice='plain'><option>-A</option></arg> - </group> - </arg> + <arg><option>--attr-path</option></arg> <arg><option>--no-name</option></arg> <arg> <group choice='req'> @@ -622,6 +610,27 @@ $ nix-env -e '*' <lineannotation>(remove everything)</lineannotation></screen> <arg><option>--drv-path</option></arg> <arg><option>--out-path</option></arg> <arg><option>--description</option></arg> + <arg><option>--meta</option></arg> + + <sbr /> + + <arg><option>--xml</option></arg> + <arg> + <group choice='req'> + <arg choice='plain'><option>--prebuilt-only</option></arg> + <arg choice='plain'><option>-b</option></arg> + </group> + </arg> + <arg> + <group choice='req'> + <arg choice='plain'><option>--attr</option></arg> + <arg choice='plain'><option>-A</option></arg> + </group> + <replaceable>attribute-path</replaceable> + </arg> + + <sbr /> + <arg choice='plain' rep='repeat'><replaceable>names</replaceable></arg> </cmdsynopsis> diff --git a/doc/manual/opt-inst-syn.xml b/doc/manual/opt-inst-syn.xml new file mode 100644 index 000000000000..1c32325e5089 --- /dev/null +++ b/doc/manual/opt-inst-syn.xml @@ -0,0 +1,15 @@ +<nop xmlns="http://docbook.org/ns/docbook"> + + <arg> + <group choice='req'> + <arg choice='plain'><option>--attr</option></arg> + <arg choice='plain'><option>-A</option></arg> + </group> + </arg> + + <arg><option>--from-expression</option></arg> + <arg><option>-E</option></arg> + + <arg><option>--from-profile</option> <replaceable>path</replaceable></arg> + +</nop> diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index b9ba3da64880..2a96e25a8484 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 *************************************************************/ |