1<chapter xmlns="http://docbook.org/ns/docbook"
2 xmlns:xlink="http://www.w3.org/1999/xlink"
3 xmlns:xi="http://www.w3.org/2001/XInclude"
4 version="5.0"
5 xml:id="sec-grsecurity">
6
7 <title>Grsecurity/PaX</title>
8
9 <para>
10 Grsecurity/PaX is a set of patches against the Linux kernel that make it
11 harder to exploit bugs. The patchset includes protections such as
12 enforcement of non-executable memory, address space layout randomization,
13 and chroot jail hardening. These and other
14 <link xlink:href="https://grsecurity.net/features.php">features</link>
15 render entire classes of exploits inert without additional efforts on the
16 part of the adversary.
17 </para>
18
19 <para>
20 The NixOS grsecurity/PaX module is designed with casual users in mind and is
21 intended to be compatible with normal desktop usage, without unnecessarily
22 compromising security. The following sections describe the configuration
23 and administration of a grsecurity/PaX enabled NixOS system. For
24 more comprehensive coverage, please refer to the
25 <link xlink:href="https://en.wikibooks.org/wiki/Grsecurity">grsecurity wikibook</link>
26 and the
27 <link xlink:href="https://wiki.archlinux.org/index.php/Grsecurity">Arch
28 Linux wiki page on grsecurity</link>.
29
30 <note><para>grsecurity/PaX is only available for the latest linux -stable
31 kernel; patches against older kernels are available from upstream only for
32 a fee.</para></note>
33 <note><para>We standardise on a desktop oriented configuration primarily due
34 to lack of resources. The grsecurity/PaX configuration state space is huge
35 and each configuration requires quite a bit of testing to ensure that the
36 resulting packages work as advertised. Defining additional package sets
37 would likely result in a large number of functionally broken packages, to
38 nobody's benefit.</para></note>.
39 </para>
40
41 <sect1 xml:id="sec-grsec-enable"><title>Enabling grsecurity/PaX</title>
42
43 <para>
44 To make use of grsecurity/PaX on NixOS, add the following to your
45 <filename>configuration.nix</filename>:
46 <programlisting>
47 security.grsecurity.enable = true;
48 </programlisting>
49 followed by
50 <programlisting>
51 # nixos-rebuild boot
52 # reboot
53 </programlisting>
54 For most users, further configuration should be unnecessary. All users
55 are encouraged to look over <xref linkend="sec-grsec-security" /> before
56 using the system, however. If you experience problems, please refer to
57 <xref linkend="sec-grsec-issues" />.
58 </para>
59
60 <para>
61 Once booted into the new system, you can optionally use
62 <command>paxtest</command> to exercise various PaX features:
63 <screen><![CDATA[
64 # nix-shell -p paxtest --command 'paxtest blackhat'
65 Executable anonymous mapping : Killed
66 Executable bss : Killed
67 # ... remaining output truncated for brevity
68 ]]></screen>
69 </para>
70
71 </sect1>
72
73 <sect1 xml:id="sec-grsec-declarative-tuning"><title>Declarative tuning</title>
74
75 <para>
76 The default configuration mode is strictly declarative. Some features
77 simply cannot be changed at all after boot, while others are locked once the
78 system is up and running. Moreover, changes to the configuration enter
79 into effect only upon booting into the new system.
80 </para>
81
82 <para>
83 The NixOS module exposes a limited number of options for tuning the behavior
84 of grsecurity/PaX. These are options thought to be of particular interest
85 to most users. For experts, further tuning is possible via
86 <option>boot.kernelParams</option> (see
87 <xref linkend="sec-grsec-kernel-params" />) and
88 <option>boot.kernel.sysctl."kernel.grsecurity.*"</option> (the wikibook
89 contains an <link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Sysctl_Options">
90 exhaustive listing of grsecurity sysctl tunables</link>).
91 </para>
92
93 </sect1>
94
95 <sect1 xml:id="sec-grsec-manual-tuning"><title>Manual tuning</title>
96
97 <para>
98 To permit manual tuning of grsecurity runtime parameters, set:
99 <programlisting>
100 security.grsecurity.lockTunables = false;
101 </programlisting>
102 Once booted into this system, grsecurity features that have a corresponding
103 sysctl tunable can be changed without rebooting, either by switching into
104 a new system profile or via the <command>sysctl</command> utility.
105 </para>
106
107 <para>
108 To lock all grsecurity tunables until the next boot, do:
109 <screen>
110 # systemctl start grsec-lock
111 </screen>
112 </para>
113
114 </sect1>
115
116 <sect1 xml:id="sec-grsec-security"><title>Security considerations</title>
117
118 <para>
119 The NixOS kernel is built using upstream's recommended settings for a
120 desktop deployment that generally favours security over performance. This
121 section details deviations from upstream's recommendations that may
122 compromise operational security.
123
124 <warning><para>There may be additional problems not covered here!</para>
125 </warning>.
126 </para>
127
128 <itemizedlist>
129
130 <listitem><para>
131 The following hardening features are disabled in the NixOS kernel:
132 <itemizedlist>
133 <listitem><para>Kernel symbol hiding: rendered useless by redistributing
134 kernel objects.</para></listitem>
135
136 <listitem><para>Randomization of kernel structures: rendered useless by
137 redistributing kernel objects.</para></listitem>
138
139 <listitem><para>TCP simultaneous OPEN connection is permitted: breaking
140 strict TCP conformance is inappropriate for a general purpose kernel.
141 The trade-off is that an attacker may be able to deny outgoing
142 connections if they are able to guess the source port allocated by your
143 OS for that connection <emphasis>and</emphasis> also manage to initiate
144 a TCP simultaneous OPEN on that port before the connection is actually
145 established.</para></listitem>
146
147 <listitem><para><filename class="directory">/sys</filename> hardening:
148 breaks systemd.</para></listitem>
149
150 <listitem><para>Trusted path execution: a desirable feature, but
151 requires some more work to operate smoothly on NixOS.</para></listitem>
152 </itemizedlist>
153 </para></listitem>
154
155 <listitem><para>
156 The NixOS module conditionally weakens <command>chroot</command>
157 restrictions to accommodate NixOS lightweight containers and sandboxed Nix
158 builds. This is problematic if the deployment also runs a privileged
159 network facing process that <emphasis>relies</emphasis> on
160 <command>chroot</command> for isolation.
161 </para></listitem>
162
163 <listitem><para>
164 The NixOS kernel is patched to allow usermode helpers from anywhere in the
165 Nix store. A usermode helper is an executable called by the kernel in
166 certain circumstances, e.g., <command>modprobe</command>. Vanilla
167 grsecurity only allows usermode helpers from paths typically owned by the
168 super user. The NixOS kernel allows an attacker to inject malicious code
169 into the Nix store which could then be executed by the kernel as a
170 usermode helper.
171 </para></listitem>
172
173 <listitem><para>
174 The following features are disabled because they overlap with
175 vanilla kernel mechanisms:
176
177 <itemizedlist>
178 <listitem><para><filename class="directory">/proc</filename> hardening:
179 use <option>security.hideProcessInformation</option> instead. This
180 trades weaker protection for greater compatibility.
181 </para></listitem>
182
183 <listitem><para><command>dmesg</command> restrictions:
184 use <option>boot.kernel.sysctl."kernel.dmesg_restrict"</option> instead
185 </para></listitem>
186 </itemizedlist>
187 </para></listitem>
188
189 </itemizedlist>
190
191 </sect1>
192
193 <sect1 xml:id="sec-grsec-custom-kernel"><title>Using a custom grsecurity/PaX kernel</title>
194
195 <para>
196 The NixOS kernel is likely to be either too permissive or too restrictive
197 for many deployment scenarios. In addition to producing a kernel more
198 suitable for a particular deployment, a custom kernel may improve security
199 by depriving an attacker the ability to study the kernel object code, adding
200 yet more guesswork to successfully carry out certain exploits.
201 </para>
202
203 <para>
204 To use a custom kernel with upstream's recommended settings for server
205 deployments:
206 <programlisting>
207 boot.kernelPackages =
208 let
209 kernel = pkgs.linux_grsec_nixos.override {
210 extraConfig = ''
211 GRKERNSEC y
212 PAX y
213 GRKERNSEC_CONFIG_AUTO y
214 GRKERNSEC_CONFIG_SERVER y
215 GRKERNSEC_CONFIG_SECURITY y
216 '';
217 };
218 self = pkgs.linuxPackagesFor kernel self;
219 in self;
220 </programlisting>
221 The wikibook provides an exhaustive listing of
222 <link xlink:href="https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options">kernel configuration options</link>.
223 </para>
224
225 <para>
226 The NixOS module makes several assumptions about the kernel and so may be
227 incompatible with your customised kernel. Most of these assumptions are
228 encoded as assertions — mismatches should ideally result in a build
229 failure. Currently, the only way to work around incompatibilities is to
230 eschew the NixOS module and do all configuration yourself.
231 </para>
232
233 </sect1>
234
235 <sect1 xml:id="sec-grsec-pax-flags"><title>Per-executable PaX flags</title>
236
237 <para>
238 Manual tuning of per-file PaX flags for executables in the Nix store is
239 impossible on a properly configured system. If a package in Nixpkgs fails
240 due to PaX, that is a bug in the package recipe and should be reported to
241 the maintainer (including relevant <command>dmesg</command> output).
242 </para>
243
244 <para>
245 For executables installed outside of the Nix store, PaX flags can be set
246 using the <command>paxctl</command> utility:
247 <programlisting>
248 paxctl -czem <replaceable>foo</replaceable>
249 </programlisting>
250
251 <warning>
252 <para><command>paxctl</command> overwrites files in-place.</para>
253 </warning>
254
255 Equivalently, on file systems that support extended attributes:
256 <programlisting>
257 setfattr -n user.pax.flags -v em <replaceable>foo</replaceable>
258 </programlisting>
259
260 <!-- TODO: PaX flags via RBAC policy -->
261 </para>
262
263 </sect1>
264
265 <sect1 xml:id="sec-grsec-issues"><title>Issues and work-arounds</title>
266
267 <itemizedlist>
268 <listitem><para>User namespaces require <literal>CAP_SYS_ADMIN</literal>:
269 consequently, unprivileged namespaces are unsupported. Applications that
270 rely on namespaces for sandboxing must use a privileged helper. For chromium
271 there is <option>security.chromiumSuidSandbox.enable</option>.</para></listitem>
272
273 <listitem><para>Access to EFI runtime services is disabled by default:
274 this plugs a potential code injection attack vector; use
275 <option>security.grsecurity.disableEfiRuntimeServices</option> to override
276 this behavior.</para></listitem>
277
278 <listitem><para>Virtualization: KVM is the preferred virtualization
279 solution. Xen, Virtualbox, and VMWare are
280 <emphasis>unsupported</emphasis> and most likely require a custom kernel.
281 </para></listitem>
282
283 <listitem><para>
284 Attaching <command>gdb</command> to a running process is disallowed by
285 default: unprivileged users can only ptrace processes that are children of
286 the ptracing process. To relax this restriction, set
287 <programlisting>
288 boot.kernel.sysctl."kernel.grsecurity.harden_ptrace" = 0;
289 </programlisting>
290 </para></listitem>
291
292 <listitem><para>
293 Overflows in boot critical code (e.g., the root filesystem module) can
294 render the system unbootable. Work around by setting
295 <programlisting>
296 boot.kernel.kernelParams = [ "pax_size_overflow_report_only" ];
297 </programlisting>
298 </para></listitem>
299
300 <listitem><para>
301 The <citerefentry><refentrytitle>modify_ldt
302 </refentrytitle><manvolnum>2</manvolnum></citerefentry> syscall is disabled
303 by default. This restriction can interfere with programs designed to run
304 legacy 16-bit or segmented 32-bit code. To support applications that rely
305 on this syscall, set
306 <programlisting>
307 boot.kernel.sysctl."kernel.modify_ldt" = 1;
308 </programlisting>
309 </para></listitem>
310
311 </itemizedlist>
312
313 </sect1>
314
315 <sect1 xml:id="sec-grsec-kernel-params"><title>Grsecurity/PaX kernel parameters</title>
316
317 <para>
318 The NixOS kernel supports the following kernel command line parameters:
319 <itemizedlist>
320 <listitem><para>
321 <literal>pax_nouderef</literal>: disable UDEREF (separate kernel and
322 user address spaces).
323 </para></listitem>
324
325 <listitem><para>
326 <literal>pax_weakuderef</literal>: enable a faster but
327 weaker variant of UDEREF on 64-bit processors with PCID support
328 (check <code>grep pcid /proc/cpuinfo</code>).
329 </para></listitem>
330
331 <listitem><para>
332 <literal>pax_sanitize_slab={off|fast|full}</literal>: control kernel
333 slab object sanitization
334 </para></listitem>
335
336 <listitem><para>
337 <literal>pax_size_overflow_report_only</literal>: log size overflow
338 violations but leave the violating task running
339 </para></listitem>
340 </itemizedlist>
341 </para>
342
343 </sect1>
344
345</chapter>