diff options
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/administration/imperative-containers.xml | 6 | ||||
-rw-r--r-- | nixos/doc/manual/configuration/configuration.xml | 1 | ||||
-rw-r--r-- | nixos/doc/manual/configuration/grsecurity.xml | 335 | ||||
-rw-r--r-- | nixos/doc/manual/release-notes/rl-1609.xml | 11 | ||||
-rw-r--r-- | nixos/modules/config/pulseaudio.nix | 9 | ||||
-rw-r--r-- | nixos/modules/security/grsecurity.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/networking/zerotierone.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/x11/desktop-managers/gnome3.nix | 2 | ||||
-rw-r--r-- | nixos/modules/system/etc/setup-etc.pl | 37 | ||||
-rw-r--r-- | nixos/modules/tasks/kbd.nix | 2 | ||||
-rw-r--r-- | nixos/tests/gnome3_18-gdm.nix | 41 | ||||
-rw-r--r-- | nixos/tests/gnome3_18.nix | 38 | ||||
-rw-r--r-- | nixos/tests/grsecurity.nix | 7 |
13 files changed, 411 insertions, 90 deletions
diff --git a/nixos/doc/manual/administration/imperative-containers.xml b/nixos/doc/manual/administration/imperative-containers.xml index 3a52658436ac..258e1ea948da 100644 --- a/nixos/doc/manual/administration/imperative-containers.xml +++ b/nixos/doc/manual/administration/imperative-containers.xml @@ -7,7 +7,11 @@ <title>Imperative Container Management</title> <para>We’ll cover imperative container management using -<command>nixos-container</command> first. You create a container with +<command>nixos-container</command> first. +Be aware that container management is currently only possible +as <literal>root</literal>.</para> + +<para>You create a container with identifier <literal>foo</literal> as follows: <screen> diff --git a/nixos/doc/manual/configuration/configuration.xml b/nixos/doc/manual/configuration/configuration.xml index cfa5619938bb..48810cc6ac6b 100644 --- a/nixos/doc/manual/configuration/configuration.xml +++ b/nixos/doc/manual/configuration/configuration.xml @@ -23,6 +23,7 @@ effect after you run <command>nixos-rebuild</command>.</para> <xi:include href="x-windows.xml" /> <xi:include href="networking.xml" /> <xi:include href="linux-kernel.xml" /> +<xi:include href="grsecurity.xml" /> <!-- FIXME: auto-include NixOS module docs --> <xi:include href="postgresql.xml" /> diff --git a/nixos/doc/manual/configuration/grsecurity.xml b/nixos/doc/manual/configuration/grsecurity.xml new file mode 100644 index 000000000000..06e7617d58eb --- /dev/null +++ b/nixos/doc/manual/configuration/grsecurity.xml @@ -0,0 +1,335 @@ +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="sec-grsecurity"> + + <title>Grsecurity/PaX</title> + + <para> + Grsecurity/PaX is a set of patches against the Linux kernel that make it + harder to exploit bugs. The patchset includes protections such as + enforcement of non-executable memory, address space layout randomization, + and chroot jail hardening. These and other + <link xlink:href="https://grsecurity.net/features.php">features</link> + render entire classes of exploits inert without additional efforts on the + part of the adversary. + </para> + + <para> + The NixOS grsecurity/PaX module is designed with casual users in mind and is + intended to be compatible with normal desktop usage, without unnecessarily + compromising security. The following sections describe the configuration + and administration of a grsecurity/PaX enabled NixOS system. For + more comprehensive coverage, please refer to the + <link xlink:href="https://en.wikibooks.org/wiki/Grsecurity">grsecurity wikibook</link> + and the + <link xlink:href="https://wiki.archlinux.org/index.php/Grsecurity">Arch + Linux wiki page on grsecurity</link>. + + <note><para>grsecurity/PaX is only available for the latest linux -stable + kernel; patches against older kernels are available from upstream only for + a fee.</para></note> + <note><para>We standardise on a desktop oriented configuration primarily due + to lack of resources. The grsecurity/PaX configuration state space is huge + and each configuration requires quite a bit of testing to ensure that the + resulting packages work as advertised. Defining additional package sets + would likely result in a large number of functionally broken packages, to + nobody's benefit.</para></note>. + </para> + + <sect1 xml:id="sec-grsec-enable"><title>Enabling grsecurity/PaX</title> + + <para> + To make use of grsecurity/PaX on NixOS, add the following to your + <filename>configuration.nix</filename>: + <programlisting> + security.grsecurity.enable = true; + </programlisting> + followed by + <programlisting> + # nixos-rebuild boot + # reboot + </programlisting> + For most users, further configuration should be unnecessary. All users + are encouraged to look over <xref linkend="sec-grsec-security" /> before + using the system, however. If you experience problems, please refer to + <xref linkend="sec-grsec-issues" />. + </para> + + <para> + Once booted into the new system, you can optionally use + <command>paxtest</command> to exercise various PaX features: + <screen><![CDATA[ + # nix-shell -p paxtest --command 'paxtest blackhat' + Executable anonymous mapping : Killed + Executable bss : Killed + # ... remaining output truncated for brevity + ]]></screen> + </para> + + </sect1> + + <sect1 xml:id="sec-grsec-declarative-tuning"><title>Declarative tuning</title> + + <para> + The default configuration mode is strictly declarative. Some features + simply cannot be changed at all after boot, while others are locked once the + system is up and running. Moreover, changes to the configuration enter + into effect only upon booting into the new system. + </para> + + <para> + The NixOS module exposes a limited number of options for tuning the behavior + of grsecurity/PaX. These are options thought to be of particular interest + to most users. For experts, further tuning is possible via + <option>boot.kernelParams</option> (see + <xref linkend="sec-grsec-kernel-params" />) and + <option>boot.kernel.sysctl."kernel.grsecurity.*"</option> (the wikibook + contains an <link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Sysctl_Options"> + exhaustive listing of grsecurity sysctl tunables</link>). + </para> + + </sect1> + + <sect1 xml:id="sec-grsec-manual-tuning"><title>Manual tuning</title> + + <para> + To permit manual tuning of grsecurity runtime parameters, set: + <programlisting> + security.grsecurity.lockTunables = false; + </programlisting> + Once booted into this system, grsecurity features that have a corresponding + sysctl tunable can be changed without rebooting, either by switching into + a new system profile or via the <command>sysctl</command> utility. + </para> + + <para> + To lock all grsecurity tunables until the next boot, do: + <screen> + # systemctl start grsec-lock + </screen> + </para> + + </sect1> + + <sect1 xml:id="sec-grsec-security"><title>Security considerations</title> + + <para> + The NixOS kernel is built using upstream's recommended settings for a + desktop deployment that generally favours security over performance. This + section details deviations from upstream's recommendations that may + compromise operational security. + + <warning><para>There may be additional problems not covered here!</para> + </warning>. + </para> + + <itemizedlist> + + <listitem><para> + The following hardening features are disabled in the NixOS kernel: + <itemizedlist> + <listitem><para>Kernel symbol hiding: rendered useless by redistributing + kernel objects.</para></listitem> + + <listitem><para>Randomization of kernel structures: rendered useless by + redistributing kernel objects.</para></listitem> + + <listitem><para>TCP simultaneous OPEN connection is permitted: breaking + strict TCP conformance is inappropriate for a general purpose kernel. + The trade-off is that an attacker may be able to deny outgoing + connections if they are able to guess the source port allocated by your + OS for that connection <emphasis>and</emphasis> also manage to initiate + a TCP simultaneous OPEN on that port before the connection is actually + established.</para></listitem> + + <listitem><para><filename class="directory">/sys</filename> hardening: + breaks systemd.</para></listitem> + + <listitem><para>Trusted path execution: a desirable feature, but + requires some more work to operate smoothly on NixOS.</para></listitem> + </itemizedlist> + </para></listitem> + + <listitem><para> + The NixOS module conditionally weakens <command>chroot</command> + restrictions to accommodate NixOS lightweight containers and sandboxed Nix + builds. This is problematic if the deployment also runs a privileged + network facing process that <emphasis>relies</emphasis> on + <command>chroot</command> for isolation. + </para></listitem> + + <listitem><para> + The NixOS kernel is patched to allow usermode helpers from anywhere in the + Nix store. A usermode helper is an executable called by the kernel in + certain circumstances, e.g., <command>modprobe</command>. Vanilla + grsecurity only allows usermode helpers from paths typically owned by the + super user. The NixOS kernel allows an attacker to inject malicious code + into the Nix store which could then be executed by the kernel as a + usermode helper. + </para></listitem> + + <listitem><para> + The following features are disabled because they overlap with + vanilla kernel mechanisms: + + <itemizedlist> + <listitem><para><filename class="directory">/proc</filename> hardening: + use <option>security.hideProcessInformation</option> instead. This + trades weaker protection for greater compatibility. + </para></listitem> + + <listitem><para><command>dmesg</command> restrictions: + use <option>boot.kernel.sysctl."kernel.dmesg_restrict"</option> instead + </para></listitem> + </itemizedlist> + </para></listitem> + + </itemizedlist> + + </sect1> + + <sect1 xml:id="sec-grsec-custom-kernel"><title>Using a custom grsecurity/PaX kernel</title> + + <para> + The NixOS kernel is likely to be either too permissive or too restrictive + for many deployment scenarios. In addition to producing a kernel more + suitable for a particular deployment, a custom kernel may improve security + by depriving an attacker the ability to study the kernel object code, adding + yet more guesswork to successfully carry out certain exploits. + </para> + + <para> + To use a custom kernel with upstream's recommended settings for server + deployments: + <programlisting> + boot.kernelPackages = + let + kernel = pkgs.linux_grsec_nixos.override { + extraConfig = '' + GRKERNSEC y + PAX y + GRKERNSEC_CONFIG_AUTO y + GRKERNSEC_CONFIG_SERVER y + GRKERNSEC_CONFIG_SECURITY y + ''; + }; + self = pkgs.linuxPackagesFor kernel self; + in self; + </programlisting> + The wikibook provides an exhaustive listing of + <link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options">kernel configuration options</link>. + </para> + + <para> + The NixOS module makes several assumptions about the kernel and so may be + incompatible with your customised kernel. Most of these assumptions are + encoded as assertions — mismatches should ideally result in a build + failure. Currently, the only way to work around incompatibilities is to + eschew the NixOS module and do all configuration yourself. + </para> + + </sect1> + + <sect1 xml:id="sec-grsec-pax-flags"><title>Per-executable PaX flags</title> + + <para> + Manual tuning of per-file PaX flags for executables in the Nix store is + impossible on a properly configured system. If a package in Nixpkgs fails + due to PaX, that is a bug in the package recipe and should be reported to + the maintainer (including relevant <command>dmesg</command> output). + </para> + + <para> + For executables installed outside of the Nix store, PaX flags can be set + using the <command>paxctl</command> utility: + <programlisting> + paxctl -czem <replaceable>foo</replaceable> + </programlisting> + + <warning> + <para><command>paxctl</command> overwrites files in-place.</para> + </warning> + + Equivalently, on file systems that support extended attributes: + <programlisting> + setfattr -n user.pax.flags -v em <replaceable>foo</replaceable> + </programlisting> + + <!-- TODO: PaX flags via RBAC policy --> + </para> + + </sect1> + + <sect1 xml:id="sec-grsec-issues"><title>Issues and work-arounds</title> + + <itemizedlist> + <listitem><para>Virtualization: KVM is the preferred virtualization + solution. Xen, Virtualbox, and VMWare are + <emphasis>unsupported</emphasis> and most likely require a custom kernel. + </para></listitem> + + <listitem><para> + Attaching <command>gdb</command> to a running process is disallowed by + default: unprivileged users can only ptrace processes that are children of + the ptracing process. To relax this restriction, set + <programlisting> + boot.kernel.sysctl."kernel.grsecurity.harden_ptrace" = 0; + </programlisting> + </para></listitem> + + <listitem><para> + Overflows in boot critical code (e.g., the root filesystem module) can + render the system unbootable. Work around by setting + <programlisting> + boot.kernel.kernelParams = [ "pax_size_overflow_report_only" ]; + </programlisting> + </para></listitem> + + <listitem><para> + The <citerefentry><refentrytitle>modify_ldt + </refentrytitle><manvolnum>2</manvolnum></citerefentry> syscall is disabled + by default. This restriction can interfere with programs designed to run + legacy 16-bit or segmented 32-bit code. To support applications that rely + on this syscall, set + <programlisting> + boot.kernel.sysctl."kernel.modify_ldt" = 1; + </programlisting> + </para></listitem> + + </itemizedlist> + + </sect1> + + <sect1 xml:id="sec-grsec-kernel-params"><title>Grsecurity/PaX kernel parameters</title> + + <para> + The NixOS kernel supports the following kernel command line parameters: + <itemizedlist> + <listitem><para> + <literal>pax_nouderef</literal>: disable UDEREF (separate kernel and + user address spaces). + </para></listitem> + + <listitem><para> + <literal>pax_weakuderef</literal>: enable a faster but + weaker variant of UDEREF on 64-bit processors with PCID support + (check <code>grep pcid /proc/cpuinfo</code>). + </para></listitem> + + <listitem><para> + <literal>pax_sanitize_slab={off|fast|full}</literal>: control kernel + slab object sanitization + </para></listitem> + + <listitem><para> + <literal>pax_size_overflow_report_only</literal>: log size overflow + violations but leave the violating task running + </para></listitem> + </itemizedlist> + </para> + + </sect1> + +</chapter> diff --git a/nixos/doc/manual/release-notes/rl-1609.xml b/nixos/doc/manual/release-notes/rl-1609.xml index be175a54c232..0bea6cbbf2dd 100644 --- a/nixos/doc/manual/release-notes/rl-1609.xml +++ b/nixos/doc/manual/release-notes/rl-1609.xml @@ -45,9 +45,14 @@ following incompatible changes:</para> <para>Other notable improvements:</para> <itemizedlist> - <listitem> - <para>todo</para> - </listitem> + + <listitem><para>Revamped grsecurity/PaX support. There is now only a single + general-purpose distribution kernel and the configuration interface has been + streamlined. Desktop users should be able to simply set + <programlisting>security.grsecurity.enable = true</programlisting> to get + a reasonably secure system without having to sacrifice too much + functionality. See <xref linkend="sec-grsecurity" /> for documentation + </para></listitem> </itemizedlist> diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix index 6984e85603f6..7acf050a9a40 100644 --- a/nixos/modules/config/pulseaudio.nix +++ b/nixos/modules/config/pulseaudio.nix @@ -27,6 +27,7 @@ let clientConf = writeText "client.conf" '' autospawn=${if nonSystemWide then "yes" else "no"} ${optionalString nonSystemWide "daemon-binary=${cfg.package.out}/bin/pulseaudio"} + ${cfg.extraClientConf} ''; # Write an /etc/asound.conf that causes all ALSA applications to @@ -96,6 +97,14 @@ in { ''; }; + extraClientConf = mkOption { + type = types.str; + default = ""; + description = '' + Extra configuration appended to pulse/client.conf file. + ''; + }; + package = mkOption { type = types.package; default = pulseaudioLight; diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix index e825679c343c..4b9a11cf6dc8 100644 --- a/nixos/modules/security/grsecurity.nix +++ b/nixos/modules/security/grsecurity.nix @@ -50,11 +50,11 @@ in (isEnabled "PAX") (isYES "GRKERNSEC_SYSCTL") (isYES "GRKERNSEC_SYSCTL_DISTRO") + (isNO "GRKERNSEC_NO_RBAC") ]; - # Install PaX related utillities into the system profile. Eventually, we - # also want to include gradm here. - environment.systemPackages = with pkgs; [ paxctl pax-utils ]; + # Install PaX related utillities into the system profile. + environment.systemPackages = with pkgs; [ gradm paxctl pax-utils ]; # Install rules for the grsec device node services.udev.packages = [ pkgs.gradm ]; diff --git a/nixos/modules/services/networking/zerotierone.nix b/nixos/modules/services/networking/zerotierone.nix index 6237f95b127b..e66648f683f4 100644 --- a/nixos/modules/services/networking/zerotierone.nix +++ b/nixos/modules/services/networking/zerotierone.nix @@ -26,6 +26,10 @@ in KillMode = "process"; }; }; - environment.systemPackages = [ pkgs.zerotierone ]; + + # ZeroTier does not issue DHCP leases, but some strangers might... + networking.dhcpcd.denyInterfaces = [ "zt0" ]; + + environment.systemPackages = [ pkgs.zerotierone ]; }; } diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 44c87c0760cb..b3da25448029 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -84,7 +84,7 @@ in { environment.gnome3.packageSet = mkOption { default = null; - example = literalExample "pkgs.gnome3_18"; + example = literalExample "pkgs.gnome3_20"; description = "Which GNOME 3 package set to use."; apply = p: if p == null then pkgs.gnome3 else p; }; diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl index 89a49b972ff9..efda74161ff8 100644 --- a/nixos/modules/system/etc/setup-etc.pl +++ b/nixos/modules/system/etc/setup-etc.pl @@ -22,6 +22,33 @@ sub atomicSymlink { # current configuration. atomicSymlink $etc, $static or die; +# Returns 1 if the argument points to the files in /etc/static. That +# means either argument is a symlink to a file in /etc/static or a +# directory with all children being static. +sub isStatic { + my $path = shift; + + if (-l $path) { + my $target = readlink $path; + return substr($target, 0, length "/etc/static/") eq "/etc/static/"; + } + + if (-d $path) { + opendir DIR, "$path" or return 0; + my @names = readdir DIR or die; + closedir DIR; + + foreach my $name (@names) { + next if $name eq "." || $name eq ".."; + unless (isStatic("$path/$name")) { + return 0; + } + } + return 1; + } + + return 0; +} # Remove dangling symlinks that point to /etc/static. These are # configuration files that existed in a previous configuration but not @@ -63,6 +90,16 @@ sub link { my $target = "/etc/$fn"; File::Path::make_path(dirname $target); $created{$fn} = 1; + + # Rename doesn't work if target is directory. + if (-l $_ && -d $target) { + if (isStatic $target) { + rmtree $target or warn; + } else { + warn "$target directory contains user files. Symlinking may fail."; + } + } + if (-e "$_.mode") { my $mode = read_file("$_.mode"); chomp $mode; if ($mode eq "direct-symlink") { diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix index 789a04c7af8a..e001832ec2eb 100644 --- a/nixos/modules/tasks/kbd.nix +++ b/nixos/modules/tasks/kbd.nix @@ -7,7 +7,7 @@ let makeColor = n: value: "COLOR_${toString n}=${value}"; makeColorCS = let positions = [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ]; - in n: value: "\033]P${elemAt position n}${value}"; + in n: value: "\\033]P${elemAt positions (n - 1)}${value}"; colors = concatImapStringsSep "\n" makeColor config.i18n.consoleColors; isUnicode = hasSuffix "UTF-8" (toUpper config.i18n.defaultLocale); diff --git a/nixos/tests/gnome3_18-gdm.nix b/nixos/tests/gnome3_18-gdm.nix deleted file mode 100644 index 8b1e9afedfb9..000000000000 --- a/nixos/tests/gnome3_18-gdm.nix +++ /dev/null @@ -1,41 +0,0 @@ -import ./make-test.nix ({ pkgs, ...} : { - name = "gnome3-gdm"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ lethalman ]; - }; - - machine = - { config, pkgs, ... }: - - { imports = [ ./common/user-account.nix ]; - - services.xserver.enable = true; - - services.xserver.displayManager.gdm = { - enable = true; - autoLogin = { - enable = true; - user = "alice"; - }; - }; - services.xserver.desktopManager.gnome3.enable = true; - environment.gnome3.packageSet = pkgs.gnome3_20; - - virtualisation.memorySize = 512; - }; - - testScript = - '' - $machine->waitForX; - $machine->sleep(15); - - # Check that logging in has given the user ownership of devices. - $machine->succeed("getfacl /dev/snd/timer | grep -q alice"); - - $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'"); - $machine->succeed("xauth merge ~alice/.Xauthority"); - $machine->waitForWindow(qr/Terminal/); - $machine->sleep(20); - $machine->screenshot("screen"); - ''; -}) diff --git a/nixos/tests/gnome3_18.nix b/nixos/tests/gnome3_18.nix deleted file mode 100644 index 2c88e6abe890..000000000000 --- a/nixos/tests/gnome3_18.nix +++ /dev/null @@ -1,38 +0,0 @@ -import ./make-test.nix ({ pkgs, ...} : { - name = "gnome3"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ domenkozar eelco chaoflow lethalman ]; - }; - - machine = - { config, pkgs, ... }: - - { imports = [ ./common/user-account.nix ]; - - services.xserver.enable = true; - - services.xserver.displayManager.auto.enable = true; - services.xserver.displayManager.auto.user = "alice"; - services.xserver.desktopManager.gnome3.enable = true; - - environment.gnome3.packageSet = pkgs.gnome3_18; - - virtualisation.memorySize = 512; - }; - - testScript = - '' - $machine->waitForX; - $machine->sleep(15); - - # Check that logging in has given the user ownership of devices. - $machine->succeed("getfacl /dev/snd/timer | grep -q alice"); - - $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'"); - $machine->succeed("xauth merge ~alice/.Xauthority"); - $machine->waitForWindow(qr/Terminal/); - $machine->mustSucceed("timeout 900 bash -c 'journalctl -f|grep -m 1 \"GNOME Shell started\"'"); - $machine->sleep(10); - $machine->screenshot("screen"); - ''; -}) diff --git a/nixos/tests/grsecurity.nix b/nixos/tests/grsecurity.nix index aadbfd8371ff..e585a7402d34 100644 --- a/nixos/tests/grsecurity.nix +++ b/nixos/tests/grsecurity.nix @@ -9,7 +9,6 @@ import ./make-test.nix ({ pkgs, ...} : { machine = { config, pkgs, ... }: { security.grsecurity.enable = true; boot.kernel.sysctl."kernel.grsecurity.deter_bruteforce" = 0; - security.apparmor.enable = true; }; testScript = '' @@ -33,9 +32,15 @@ import ./make-test.nix ({ pkgs, ...} : { $machine->succeed("${pkgs.paxtest}/lib/paxtest/mprotstack") =~ /Killed/ or die; }; + # tcc -run executes run-time generated code and so allows us to test whether + # paxmark actually works (otherwise, the process should be terminated) subtest "tcc", sub { $machine->execute("echo -e '#include <stdio.h>\nint main(void) { puts(\"hello\"); return 0; }' >main.c"); $machine->succeed("${pkgs.tinycc.bin}/bin/tcc -run main.c"); }; + + subtest "RBAC", sub { + $machine->succeed("[ -c /dev/grsec ]"); + }; ''; }) |