820 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			820 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
<chapter xmlns="http://docbook.org/ns/docbook"
 | 
						||
         xmlns:xlink="http://www.w3.org/1999/xlink"
 | 
						||
         xml:id="ch-configuration">
 | 
						||
 | 
						||
<title>Configuring NixOS</title>
 | 
						||
 | 
						||
<para>This chapter describes how to configure various aspects of a
 | 
						||
NixOS machine through the configuration file
 | 
						||
<filename>/etc/nixos/configuration.nix</filename>.  As described in
 | 
						||
<xref linkend="sec-changing-config" />, changes to that file only take
 | 
						||
effect after you run <command>nixos-rebuild</command>.</para>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section xml:id="sec-configuration-syntax"><title>Configuration syntax</title>
 | 
						||
 | 
						||
<para>TODO</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section><title>Package management</title>
 | 
						||
 | 
						||
<para>This section describes how to add additional packages to your
 | 
						||
system.  NixOS has two distinct styles of package management:
 | 
						||
 | 
						||
<itemizedlist>
 | 
						||
 | 
						||
  <listitem><para><emphasis>Declarative</emphasis>, where you declare
 | 
						||
  what packages you want in your
 | 
						||
  <filename>configuration.nix</filename>.  Every time you run
 | 
						||
  <command>nixos-rebuild</command>, NixOS will ensure that you get a
 | 
						||
  consistent set of binaries corresponding to your
 | 
						||
  specification.</para></listitem>
 | 
						||
 | 
						||
  <listitem><para><emphasis>Ad hoc</emphasis>, where you install,
 | 
						||
  upgrade and uninstall packages via the <command>nix-env</command>
 | 
						||
  command.  This style allows mixing packages from different Nixpkgs
 | 
						||
  versions.  It’s the only choice for non-root
 | 
						||
  users.</para></listitem>
 | 
						||
 | 
						||
</itemizedlist>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
<para>The next two sections describe these two styles.</para>
 | 
						||
 | 
						||
 | 
						||
<section><title>Declarative package management</title>
 | 
						||
 | 
						||
<para>With declarative package management, you specify which packages
 | 
						||
you want on your system by setting the option
 | 
						||
<option>environment.systemPackages</option>.  For instance, adding the
 | 
						||
following line to <filename>configuration.nix</filename> enables the
 | 
						||
Mozilla Thunderbird email application:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
environment.systemPackages = [ pkgs.thunderbird ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
The effect of this specification is that the Thunderbird package from
 | 
						||
Nixpkgs will be built or downloaded as part of the system when you run
 | 
						||
<command>nixos-rebuild switch</command>.</para>
 | 
						||
 | 
						||
<para>You can get a list of the available packages as follows:
 | 
						||
<screen>
 | 
						||
$ nix-env -qaP '*' --description
 | 
						||
nixos.pkgs.firefox   firefox-23.0   Mozilla Firefox - the browser, reloaded
 | 
						||
<replaceable>...</replaceable>
 | 
						||
</screen>
 | 
						||
 | 
						||
The first column in the output is the <emphasis>attribute
 | 
						||
name</emphasis>, such as
 | 
						||
<literal>nixos.pkgs.thunderbird</literal>. (The
 | 
						||
<literal>nixos</literal> prefix allows distinguishing between
 | 
						||
different channels that you might have.)</para>
 | 
						||
 | 
						||
<para>To “uninstall” a package, simply remove it from
 | 
						||
<option>environment.systemPackages</option> and run
 | 
						||
<command>nixos-rebuild switch</command>.</para>
 | 
						||
 | 
						||
 | 
						||
<section xml:id="sec-customising-packages"><title>Customising packages</title>
 | 
						||
 | 
						||
<para>Some packages in Nixpkgs have options to enable or disable
 | 
						||
optional functionality or change other aspects of the package.  For
 | 
						||
instance, the Firefox wrapper package (which provides Firefox with a
 | 
						||
set of plugins such as the Adobe Flash player) has an option to enable
 | 
						||
the Google Talk plugin.  It can be set in
 | 
						||
<filename>configuration.nix</filename> as follows:
 | 
						||
 | 
						||
<filename>
 | 
						||
nixpkgs.config.firefox.enableGoogleTalkPlugin = true;
 | 
						||
</filename>
 | 
						||
</para>
 | 
						||
 | 
						||
<warning><para>Unfortunately, Nixpkgs currently lacks a way to query
 | 
						||
available configuration options.</para></warning>
 | 
						||
 | 
						||
<para>Apart from high-level options, it’s possible to tweak a package
 | 
						||
in almost arbitrary ways, such as changing or disabling dependencies
 | 
						||
of a package.  For instance, the Emacs package in Nixpkgs by default
 | 
						||
has a dependency on GTK+ 2.  If you want to build it against GTK+ 3,
 | 
						||
you can specify that as follows:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
environment.systemPackages = [ (pkgs.emacs.override { gtk = pkgs.gtk3; }) ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
The function <varname>override</varname> performs the call to the Nix
 | 
						||
function that produces Emacs, with the original arguments amended by
 | 
						||
the set of arguments specified by you.  So here the function argument
 | 
						||
<varname>gtk</varname> gets the value <literal>pkgs.gtk3</literal>,
 | 
						||
causing Emacs to depend on GTK+ 3.  (The parentheses are necessary
 | 
						||
because in Nix, function application binds more weakly than list
 | 
						||
construction, so without them,
 | 
						||
<literal>environment.systemPackages</literal> would be a list with two
 | 
						||
elements.)</para>
 | 
						||
 | 
						||
<para>Even greater customisation is possible using the function
 | 
						||
<varname>overrideDerivation</varname>.  While the
 | 
						||
<varname>override</varname> mechanism above overrides the arguments of
 | 
						||
a package function, <varname>overrideDerivation</varname> allows
 | 
						||
changing the <emphasis>result</emphasis> of the function.  This
 | 
						||
permits changing any aspect of the package, such as the source code.
 | 
						||
For instance, if you want to override the source code of Emacs, you
 | 
						||
can say:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
environment.systemPackages =
 | 
						||
  [ (pkgs.lib.overrideDerivation pkgs.emacs (attrs: {
 | 
						||
      name = "emacs-25.0-pre";
 | 
						||
      src = /path/to/my/emacs/tree;
 | 
						||
    }))
 | 
						||
  ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
Here, <varname>overrideDerivation</varname> takes the Nix derivation
 | 
						||
specified by <varname>pkgs.emacs</varname> and produces a new
 | 
						||
derivation in which the original’s <literal>name</literal> and
 | 
						||
<literal>src</literal> attribute have been replaced by the given
 | 
						||
values.  The original attributes are accessible via
 | 
						||
<varname>attrs</varname>.</para>
 | 
						||
 | 
						||
<para>The overrides shown above are not global.  They do not affect
 | 
						||
the original package; other packages in Nixpkgs continue to depend on
 | 
						||
the original rather than the customised package.  This means that if
 | 
						||
another package in your system depends on the original package, you
 | 
						||
end up with two instances of the package.  If you want to have
 | 
						||
everything depend on your customised instance, you can apply a
 | 
						||
<emphasis>global</emphasis> override as follows:
 | 
						||
 | 
						||
<screen>
 | 
						||
nixpkgs.config.packageOverrides = pkgs:
 | 
						||
  { emacs = pkgs.emacs.override { gtk = pkgs.gtk3; };
 | 
						||
  };
 | 
						||
</screen>
 | 
						||
 | 
						||
The effect of this definition is essentially equivalent to modifying
 | 
						||
the <literal>emacs</literal> attribute in the Nixpkgs source tree.
 | 
						||
Any package in Nixpkgs that depends on <literal>emacs</literal> will
 | 
						||
be passed your customised instance.  (However, the value
 | 
						||
<literal>pkgs.emacs</literal> in
 | 
						||
<varname>nixpkgs.config.packageOverrides</varname> refers to the
 | 
						||
original rather than overriden instance, to prevent an infinite
 | 
						||
recursion.)</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
<section><title>Adding custom packages</title>
 | 
						||
 | 
						||
<para>It’s possible that a package you need is not available in NixOS.
 | 
						||
In that case, you can do two things.  First, you can clone the Nixpkgs
 | 
						||
repository, add the package to your clone, and (optionally) submit a
 | 
						||
patch or pull request to have it accepted into the main Nixpkgs
 | 
						||
repository.  This is described in detail in the <link
 | 
						||
xlink:href="http://nixos.org/nixpkgs/manual">Nixpkgs manual</link>.
 | 
						||
In short, you clone Nixpkgs:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ git clone git://github.com/NixOS/nixpkgs.git
 | 
						||
$ cd nixpkgs
 | 
						||
</screen>
 | 
						||
 | 
						||
Then you write and test the package as described in the Nixpkgs
 | 
						||
manual.  Finally, you add it to
 | 
						||
<literal>environment.systemPackages</literal>, e.g.
 | 
						||
 | 
						||
<programlisting>
 | 
						||
environment.systemPackages = [ pkgs.my-package ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
and you run <command>nixos-rebuild</command>, specifying your own
 | 
						||
Nixpkgs tree:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
<para>The second possibility is to add the package outside of the
 | 
						||
Nixpkgs tree.  For instance, here is how you specify a build of the
 | 
						||
<link xlink:href="http://www.gnu.org/software/hello/">GNU Hello</link>
 | 
						||
package directly in <filename>configuration.nix</filename>:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
environment.systemPackages =
 | 
						||
  let
 | 
						||
    my-hello = with pkgs; stdenv.mkDerivation rec {
 | 
						||
      name = "hello-2.8";
 | 
						||
      src = fetchurl {
 | 
						||
        url = "mirror://gnu/hello/${name}.tar.gz";
 | 
						||
        sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
 | 
						||
      };
 | 
						||
    };
 | 
						||
  in
 | 
						||
  [ my-hello ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
Of course, you can also move the definition of
 | 
						||
<literal>my-hello</literal> into a separate Nix expression, e.g.
 | 
						||
<programlisting>
 | 
						||
environment.systemPackages = [ (import ./my-hello.nix) ];
 | 
						||
</programlisting>
 | 
						||
where <filename>my-hello.nix</filename> contains:
 | 
						||
<programlisting>
 | 
						||
with <nixpkgs> {}; # bring all of Nixpkgs into scope
 | 
						||
 | 
						||
stdenv.mkDerivation rec {
 | 
						||
  name = "hello-2.8";
 | 
						||
  src = fetchurl {
 | 
						||
    url = "mirror://gnu/hello/${name}.tar.gz";
 | 
						||
    sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
 | 
						||
  };
 | 
						||
}
 | 
						||
</programlisting>
 | 
						||
 | 
						||
This allows testing the package easily:
 | 
						||
<screen>
 | 
						||
$ nix-build my-hello.nix
 | 
						||
$ ./result/bin/hello
 | 
						||
Hello, world!
 | 
						||
</screen>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>Ad hoc package management</title>
 | 
						||
 | 
						||
<para>With the command <command>nix-env</command>, you can install and
 | 
						||
uninstall packages from the command line.  For instance, to install
 | 
						||
Mozilla Thunderbird:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ nix-env -iA nixos.pkgs.thunderbird</screen>
 | 
						||
 | 
						||
If you invoke this as root, the package is installed in the Nix
 | 
						||
profile <filename>/nix/var/nix/profiles/default</filename> and visible
 | 
						||
to all users of the system; otherwise, the package ends up in
 | 
						||
<filename>/nix/var/nix/profiles/per-user/<replaceable>username</replaceable>/profile</filename>
 | 
						||
and is not visible to other users.  The <option>-A</option> flag
 | 
						||
specifies the package by its attribute name; without it, the package
 | 
						||
is installed by matching against its package name
 | 
						||
(e.g. <literal>thunderbird</literal>).  The latter is slower because
 | 
						||
it requires matching against all available Nix packages, and is
 | 
						||
ambiguous if there are multiple matching packages.</para>
 | 
						||
 | 
						||
<para>Packages come from the NixOS channel.  You typically upgrade a
 | 
						||
package by updating to the latest version of the NixOS channel:
 | 
						||
<screen>
 | 
						||
$ nix-channel --update nixos
 | 
						||
</screen>
 | 
						||
and then running <literal>nix-env -i</literal> again.  Other packages
 | 
						||
in the profile are <emphasis>not</emphasis> affected; this is the
 | 
						||
crucial difference with the declarative style of package management,
 | 
						||
where running <command>nixos-rebuild switch</command> causes all
 | 
						||
packages to be updated to their current versions in the NixOS channel.
 | 
						||
You can however upgrade all packages for which there is a newer
 | 
						||
version by doing:
 | 
						||
<screen>
 | 
						||
$ nix-env -u '*'
 | 
						||
</screen>
 | 
						||
</para>
 | 
						||
 | 
						||
<para>A package can be uninstalled using the <option>-e</option>
 | 
						||
flag:
 | 
						||
<screen>
 | 
						||
$ nix-env -e thunderbird
 | 
						||
</screen>
 | 
						||
</para>
 | 
						||
 | 
						||
<para>Finally, you can roll back an undesirable
 | 
						||
<command>nix-env</command> action:
 | 
						||
<screen>
 | 
						||
$ nix-env --rollback
 | 
						||
</screen>
 | 
						||
</para>
 | 
						||
 | 
						||
<para><command>nix-env</command> has many more flags.  For details,
 | 
						||
see the
 | 
						||
<citerefentry><refentrytitle>nix-env</refentrytitle><manvolnum>1</manvolnum></citerefentry>
 | 
						||
manpage or the Nix manual.</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section><title>User management</title>
 | 
						||
 | 
						||
<para>NixOS supports both declarative and imperative styles of user
 | 
						||
management.  In the declarative style, users are specified in
 | 
						||
<filename>configuration.nix</filename>.  For instance, the following
 | 
						||
states that a user account named <literal>alice</literal> shall exist:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
users.extraUsers.alice =
 | 
						||
  { createHome = true;
 | 
						||
    home = "/home/alice";
 | 
						||
    description = "Alice Foobar";
 | 
						||
    extraGroups = [ "wheel" ];
 | 
						||
    isSystemUser = false;
 | 
						||
    useDefaultShell = true;
 | 
						||
    openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... alice@foobar" ];
 | 
						||
  };
 | 
						||
</programlisting>
 | 
						||
 | 
						||
Note that <literal>alice</literal> is a member of the
 | 
						||
<literal>wheel</literal> group, which allows her to use
 | 
						||
<command>sudo</command> to execute commands as
 | 
						||
<literal>root</literal>.  Also note the SSH public key that allows
 | 
						||
remote logins with the corresponding private key.  Users created in
 | 
						||
this way do not have a password by default, so they cannot log in via
 | 
						||
mechanisms that require a password.  However, you can use the
 | 
						||
<command>passwd</command> program to set a password, which is retained
 | 
						||
across invocations of <command>nixos-rebuild</command>.</para>
 | 
						||
 | 
						||
<para>A user ID (uid) is assigned automatically.  You can also specify
 | 
						||
a uid manually by adding
 | 
						||
 | 
						||
<programlisting>
 | 
						||
    uid = 1000;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
to the user specification.</para>
 | 
						||
 | 
						||
<para>Groups can be specified similarly.  The following states that a
 | 
						||
group named <literal>students</literal> shall exist:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
users.extraGroups.students.gid = 1000;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
As with users, the group ID (gid) is optional and will be assigned
 | 
						||
automatically if it’s missing.</para>
 | 
						||
 | 
						||
<warning><para>Currently declarative user management is not perfect:
 | 
						||
<command>nixos-rebuild</command> does not know how to realise certain
 | 
						||
configuration changes.  This includes removing a user or group, and
 | 
						||
removing group membership from a user.</para></warning>
 | 
						||
 | 
						||
<para>In the imperative style, users and groups are managed by
 | 
						||
commands such as <command>useradd</command>,
 | 
						||
<command>groupmod</command> and so on.  For instance, to create a user
 | 
						||
account named <literal>alice</literal>:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ useradd -m alice</screen>
 | 
						||
 | 
						||
The flag <option>-m</option> causes the creation of a home directory
 | 
						||
for the new user, which is generally what you want.  The user does not
 | 
						||
have an initial password and therefore cannot log in.  A password can
 | 
						||
be set using the <command>passwd</command> utility:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ passwd alice
 | 
						||
Enter new UNIX password: ***
 | 
						||
Retype new UNIX password: ***
 | 
						||
</screen>
 | 
						||
 | 
						||
A user can be deleted using <command>userdel</command>:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ userdel -r alice</screen>
 | 
						||
 | 
						||
The flag <option>-r</option> deletes the user’s home directory.
 | 
						||
Accounts can be modified using <command>usermod</command>.  Unix
 | 
						||
groups can be managed using <command>groupadd</command>,
 | 
						||
<command>groupmod</command> and <command>groupdel</command>.</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section><title>File systems</title>
 | 
						||
 | 
						||
<para>You can define file systems using the
 | 
						||
<option>fileSystems</option> configuration option.  For instance, the
 | 
						||
following definition causes NixOS to mount the Ext4 file system on
 | 
						||
device <filename>/dev/disk/by-label/data</filename> onto the mount
 | 
						||
point <filename>/data</filename>:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
fileSystems."/data" =
 | 
						||
  { device = "/dev/disk/by-label/data";
 | 
						||
    fsType = "ext4";
 | 
						||
  };
 | 
						||
</programlisting>
 | 
						||
 | 
						||
Mount points are created automatically if they don’t already exist.
 | 
						||
For <option>device</option>, it’s best to use the topology-independent
 | 
						||
device aliases in <filename>/dev/disk/by-label</filename> and
 | 
						||
<filename>/dev/disk/by-uuid</filename>, as these don’t change if the
 | 
						||
topology changes (e.g. if a disk is moved to another IDE
 | 
						||
controller).</para>
 | 
						||
 | 
						||
<para>You can usually omit the file system type
 | 
						||
(<option>fsType</option>), since <command>mount</command> can usually
 | 
						||
detect the type and load the necessary kernel module automatically.
 | 
						||
However, if the file system is needed at early boot (in the initial
 | 
						||
ramdisk) and is not <literal>ext2</literal>, <literal>ext3</literal>
 | 
						||
or <literal>ext4</literal>, then it’s best to specify
 | 
						||
<option>fsType</option> to ensure that the kernel module is
 | 
						||
available.</para>
 | 
						||
 | 
						||
<section><title>LUKS-encrypted file systems</title>
 | 
						||
 | 
						||
<para>NixOS supports file systems that are encrypted using
 | 
						||
<emphasis>LUKS</emphasis> (Linux Unified Key Setup).  For example,
 | 
						||
here is how you create an encrypted Ext4 file system on the device
 | 
						||
<filename>/dev/sda2</filename>:
 | 
						||
 | 
						||
<screen>
 | 
						||
$ cryptsetup luksFormat /dev/sda2
 | 
						||
 | 
						||
WARNING!
 | 
						||
========
 | 
						||
This will overwrite data on /dev/sda2 irrevocably.
 | 
						||
 | 
						||
Are you sure? (Type uppercase yes): YES
 | 
						||
Enter LUKS passphrase: ***
 | 
						||
Verify passphrase: ***
 | 
						||
 | 
						||
$ cryptsetup luksOpen /dev/sda2 crypted
 | 
						||
Enter passphrase for /dev/sda2: ***
 | 
						||
 | 
						||
$ mkfs.ext4 /dev/mapper/crypted
 | 
						||
</screen>
 | 
						||
 | 
						||
To ensure that this file system is automatically mounted at boot time
 | 
						||
as <filename>/</filename>, add the following to
 | 
						||
<filename>configuration.nix</filename>:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
boot.initrd.luks.devices = [ { device = "/dev/sda2"; name = "crypted"; } ];
 | 
						||
fileSystems."/".device = "/dev/mapper/crypted";
 | 
						||
</programlisting>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section><title>X Window System</title>
 | 
						||
 | 
						||
<para>The X Window System (X11) provides the basis of NixOS’ graphical
 | 
						||
user interface.  It can be enabled as follows:
 | 
						||
<programlisting>
 | 
						||
services.xserver.enable = true;
 | 
						||
</programlisting>
 | 
						||
The X server will automatically detect and use the appropriate video
 | 
						||
driver from a set of X.org drivers (such as <literal>vesa</literal>
 | 
						||
and <literal>intel</literal>).  You can also specify a driver
 | 
						||
manually, e.g.
 | 
						||
<programlisting>
 | 
						||
services.xserver.videoDrivers = [ "r128" ];
 | 
						||
</programlisting>
 | 
						||
to enable X.org’s <literal>xf86-video-r128</literal> driver.</para>
 | 
						||
 | 
						||
<para>You also need to enable at least one desktop or window manager.
 | 
						||
Otherwise, you can only log into a plain undecorated
 | 
						||
<command>xterm</command> window.  Thus you should pick one or more of
 | 
						||
the following lines:
 | 
						||
<programlisting>
 | 
						||
services.xserver.desktopManager.kde4.enable = true;
 | 
						||
services.xserver.desktopManager.xfce.enable = true;
 | 
						||
services.xserver.windowManager.xmonad.enable = true;
 | 
						||
services.xserver.windowManager.twm.enable = true;
 | 
						||
services.xserver.windowManager.icewm.enable = true;
 | 
						||
</programlisting>
 | 
						||
</para>
 | 
						||
 | 
						||
<para>NixOS’s default <emphasis>display manager</emphasis> (the
 | 
						||
program that provides a graphical login prompt and manages the X
 | 
						||
server) is SLiM.  You can select KDE’s <command>kdm</command> instead:
 | 
						||
<programlisting>
 | 
						||
services.xserver.displayManager.kdm.enable = true;
 | 
						||
</programlisting>
 | 
						||
</para>
 | 
						||
 | 
						||
<para>The X server is started automatically at boot time.  If you
 | 
						||
don’t want this to happen, you can set:
 | 
						||
<programlisting>
 | 
						||
services.xserver.autorun = false;
 | 
						||
</programlisting>
 | 
						||
The X server can then be started manually:
 | 
						||
<screen>
 | 
						||
$ systemctl start display-manager.service
 | 
						||
</screen>
 | 
						||
</para>
 | 
						||
 | 
						||
 | 
						||
<section><title>NVIDIA graphics cards</title>
 | 
						||
 | 
						||
<para>NVIDIA provides a proprietary driver for its graphics cards that
 | 
						||
has better 3D performance than the X.org drivers.  It is not enabled
 | 
						||
by default because it’s not free software.  You can enable it as follows:
 | 
						||
<programlisting>
 | 
						||
services.xserver.videoDrivers = [ "nvidia" ];
 | 
						||
</programlisting>
 | 
						||
You may need to reboot after enabling this driver to prevent a clash
 | 
						||
with other kernel modules.</para>
 | 
						||
 | 
						||
<para>On 64-bit systems, if you want full acceleration for 32-bit
 | 
						||
programs such as Wine, you should also set the following:
 | 
						||
<programlisting>
 | 
						||
service.xserver.driSupport32Bit = true;
 | 
						||
</programlisting>
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>Touchpads</title>
 | 
						||
 | 
						||
<para>Support for Synaptics touchpads (found in many laptops such as
 | 
						||
the Dell Latitude series) can be enabled as follows:
 | 
						||
<programlisting>
 | 
						||
services.xserver.synaptics.enable = true;
 | 
						||
</programlisting>
 | 
						||
The driver has many options (see <xref linkend="ch-options"/>).  For
 | 
						||
instance, the following enables two-finger scrolling:
 | 
						||
<programlisting>
 | 
						||
services.xserver.synaptics.twoFingerScroll = true;
 | 
						||
</programlisting>
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section><title>Networking</title>
 | 
						||
 | 
						||
<section><title>Secure shell access</title>
 | 
						||
 | 
						||
<para>Secure shell (SSH) access to your machine can be enabled by
 | 
						||
setting:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
services.openssh.enable = true;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
By default, root logins using a password are disallowed.  They can be
 | 
						||
disabled entirely by setting
 | 
						||
<literal>services.openssh.permitRootLogin</literal> to
 | 
						||
<literal>"no"</literal>.</para>
 | 
						||
 | 
						||
<para>You can declaratively specify authorised RSA/DSA public keys for
 | 
						||
a user as follows:
 | 
						||
 | 
						||
<!-- FIXME: this might not work if the user is unmanaged. -->
 | 
						||
<programlisting>
 | 
						||
users.extraUsers.alice.openssh.authorizedKeys.keys =
 | 
						||
  [ "ssh-dss AAAAB3NzaC1kc3MAAACBAPIkGWVEt4..." ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>IPv4 configuration</title>
 | 
						||
 | 
						||
<para>By default, NixOS uses DHCP (specifically,
 | 
						||
<command>dhcpcd</command>) to automatically configure network
 | 
						||
interfaces.  However, you can configure an interface manually as
 | 
						||
follows:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.interfaces.eth0 = { ipAddress = "192.168.1.2"; prefixLength = 24; };
 | 
						||
</programlisting>
 | 
						||
 | 
						||
(The network prefix can also be specified using the option
 | 
						||
<literal>subnetMask</literal>,
 | 
						||
e.g. <literal>"255.255.255.0"</literal>, but this is deprecated.)
 | 
						||
Typically you’ll also want to set a default gateway and set of name
 | 
						||
servers:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.defaultGateway = "192.168.1.1";
 | 
						||
networking.nameservers = [ "8.8.8.8" ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
<note><para>Statically configured interfaces are set up by the systemd
 | 
						||
service
 | 
						||
<replaceable>interface-name</replaceable><literal>-cfg.service</literal>.
 | 
						||
The default gateway and name server configuration is performed by
 | 
						||
<literal>network-setup.service</literal>.</para></note>
 | 
						||
 | 
						||
<para>The host name is set using <option>networking.hostName</option>:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.hostName = "cartman";
 | 
						||
</programlisting>
 | 
						||
 | 
						||
The default host name is <literal>nixos</literal>.  Set it to the
 | 
						||
empty string (<literal>""</literal>) to allow the DHCP server to
 | 
						||
provide the host name.</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>IPv6 configuration</title>
 | 
						||
 | 
						||
<para>IPv6 is enabled by default.  Stateless address autoconfiguration
 | 
						||
is used to automatically assign IPv6 addresses to all interfaces.  You
 | 
						||
can disable IPv6 support globally by setting:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.enableIPv6 = false;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>Firewall</title>
 | 
						||
 | 
						||
<para>NixOS has a simple stateful firewall that blocks incoming
 | 
						||
connections and other unexpected packets.  The firewall applies to
 | 
						||
both IPv4 and IPv6 traffic.  It can be enabled as follows:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.firewall.enable = true;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
You can open specific TCP ports to the outside world:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.firewall.allowedTCPPorts = [ 80 443 ];
 | 
						||
</programlisting>
 | 
						||
 | 
						||
Note that TCP port 22 (ssh) is opened automatically if the SSH daemon
 | 
						||
is enabled (<option>services.openssh.enable = true</option>).  UDP
 | 
						||
ports can be opened through
 | 
						||
<option>networking.firewall.allowedUDPPorts</option>.  Also of
 | 
						||
interest is
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.firewall.allowPing = true;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
to allow the machine to respond to ping requests.  (ICMPv6 pings are
 | 
						||
always allowed.)</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>Wireless networks</title>
 | 
						||
 | 
						||
<para>
 | 
						||
NixOS will start wpa_supplicant for you if you enable this setting:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.wireless.enable = true;
 | 
						||
</programlisting>
 | 
						||
 | 
						||
NixOS currently does not generate wpa_supplicant's
 | 
						||
configuration file, <literal>/etc/wpa_supplicant.conf</literal>. You should edit this file
 | 
						||
yourself to define wireless networks, WPA keys and so on (see
 | 
						||
wpa_supplicant.conf(5)).
 | 
						||
</para>
 | 
						||
 | 
						||
<para>
 | 
						||
If you are using WPA2 the <command>wpa_passphrase</command> tool might be useful
 | 
						||
to generate the <literal>wpa_supplicant.conf</literal>.
 | 
						||
 | 
						||
<screen>
 | 
						||
$ wpa_passphrase ESSID PSK > /etc/wpa_supplicant.conf</screen>
 | 
						||
 | 
						||
After you have edited the <literal>wpa_supplicant.conf</literal>,
 | 
						||
you need to restart the wpa_supplicant service.
 | 
						||
 | 
						||
<screen>
 | 
						||
$ systemctl restart wpa_supplicant.service</screen>
 | 
						||
</para>
 | 
						||
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<section><title>Ad-hoc configuration</title>
 | 
						||
 | 
						||
<para>You can use <option>networking.localCommands</option> to specify
 | 
						||
shell commands to be run at the end of
 | 
						||
<literal>network-setup.service</literal>.  This is useful for doing
 | 
						||
network configuration not covered by the existing NixOS modules.  For
 | 
						||
instance, to statically configure an IPv6 address:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
networking.localCommands =
 | 
						||
  ''
 | 
						||
    ip -6 addr add 2001:610:685:1::1/64 dev eth0
 | 
						||
  '';
 | 
						||
</programlisting>
 | 
						||
 | 
						||
</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!-- TODO: OpenVPN, NAT -->
 | 
						||
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!--===============================================================-->
 | 
						||
 | 
						||
<section><title>Linux kernel</title>
 | 
						||
 | 
						||
<para>You can override the Linux kernel and associated packages using
 | 
						||
the option <option>boot.kernelPackages</option>.  For instance, this
 | 
						||
selects the Linux 3.10 kernel:
 | 
						||
<programlisting>
 | 
						||
boot.kernelPackages = pkgs.linuxPackages_3_10;
 | 
						||
</programlisting>
 | 
						||
Note that this not only replaces the kernel, but also packages that
 | 
						||
are specific to the kernel version, such as the NVIDIA video drivers.
 | 
						||
This ensures that driver packages are consistent with the
 | 
						||
kernel.</para>
 | 
						||
 | 
						||
<para>The default Linux kernel configuration should be fine for most
 | 
						||
users.  You can see the configuration of your current kernel in
 | 
						||
<filename>/run/booted-system/kernel-modules/config</filename>.  If you
 | 
						||
want to change the kernel configuration, you can use the
 | 
						||
<option>packageOverrides</option> feature (see <xref
 | 
						||
linkend="sec-customising-packages" />).  For instance, to enable
 | 
						||
support for the kernel debugger KGDB:
 | 
						||
 | 
						||
<programlisting>
 | 
						||
nixpkgs.config.packageOverrides = pkgs:
 | 
						||
  { linux_3_4 = pkgs.linux_3_4.override {
 | 
						||
      extraConfig =
 | 
						||
        ''
 | 
						||
          KGDB y
 | 
						||
        '';
 | 
						||
    };
 | 
						||
  };
 | 
						||
</programlisting>
 | 
						||
 | 
						||
<varname>extraConfig</varname> takes a list of Linux kernel
 | 
						||
configuration options, one per line.  The name of the option should
 | 
						||
not include the prefix <literal>CONFIG_</literal>.  The option value
 | 
						||
is typically <literal>y</literal>, <literal>n</literal> or
 | 
						||
<literal>m</literal> (to build something as a kernel module).</para>
 | 
						||
 | 
						||
<para>Kernel modules for hardware devices are generally loaded
 | 
						||
automatically by <command>udev</command>.  You can force a module to
 | 
						||
be loaded via <option>boot.kernelModules</option>, e.g.
 | 
						||
<programlisting>
 | 
						||
boot.kernelModules = [ "fuse" "kvm-intel" "coretemp" ];
 | 
						||
</programlisting>
 | 
						||
If the module is required early during the boot (e.g. to mount the
 | 
						||
root file system), you can use
 | 
						||
<option>boot.initrd.extraKernelModules</option>:
 | 
						||
<programlisting>
 | 
						||
boot.initrd.extraKernelModules = [ "cifs" ];
 | 
						||
</programlisting>
 | 
						||
This causes the specified modules and their dependencies to be added
 | 
						||
to the initial ramdark.</para>
 | 
						||
 | 
						||
<para>Kernel runtime parameters can be set through
 | 
						||
<option>boot.kernel.sysctl</option>, e.g.
 | 
						||
<programlisting>
 | 
						||
boot.kernel.sysctl."net.ipv4.tcp_keepalive_time" = 120;
 | 
						||
</programlisting>
 | 
						||
sets the kernel’s TCP keepalive time to 120 seconds.  To see the
 | 
						||
available parameters, run <command>sysctl -a</command>.</para>
 | 
						||
 | 
						||
</section>
 | 
						||
 | 
						||
 | 
						||
<!-- Apache; libvirtd virtualisation -->
 | 
						||
 | 
						||
 | 
						||
</chapter>
 |