summary refs log tree commit diff
path: root/nixos/doc/manual/configuration/grsecurity.xml
blob: 06e7617d58eb27478c94f7441036c03b9943abca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
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 &#x2014; 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>