Grsecurity/PaX
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
features
render entire classes of exploits inert without additional efforts on the
part of the adversary.
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
grsecurity wikibook
and the
Arch
Linux wiki page on grsecurity.
grsecurity/PaX is only available for the latest linux -stable
kernel; patches against older kernels are available from upstream only for
a fee.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..
Enabling grsecurity/PaX
To make use of grsecurity/PaX on NixOS, add the following to your
configuration.nix:
security.grsecurity.enable = true;
followed by
# nixos-rebuild boot
# reboot
Enabling the grsecurity module overrides
, to reduce the risk of
misconfiguration.
describes how to use a custom kernel package set.
For most users, further configuration should be unnecessary. All users
are encouraged to look over before
using the system, however. If you experience problems, please refer to
.
Once booted into the new system, you can optionally use
paxtest to exercise various PaX features:
Declarative tuning
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.
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
(see
) and
(the wikibook
contains an
exhaustive listing of grsecurity sysctl tunables).
Manual tuning
To permit manual tuning of grsecurity runtime parameters, set:
security.grsecurity.lockTunables = false;
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 sysctl utility.
To lock all grsecurity tunables until the next boot, do:
# systemctl start grsec-lock
Security considerations
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.
There may be additional problems not covered here!.
The following hardening features are disabled in the NixOS kernel:
Kernel symbol hiding: rendered useless by redistributing
kernel objects.Randomization of kernel structures: rendered useless by
redistributing kernel objects.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 and also manage to initiate
a TCP simultaneous OPEN on that port before the connection is actually
established.Trusted path execution: a desirable feature, but
requires some more work to operate smoothly on NixOS.
The NixOS module conditionally weakens chroot
restrictions to accommodate NixOS lightweight containers and sandboxed Nix
builds. This is problematic if the deployment also runs a privileged
network facing process that relies on
chroot for isolation.
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., modprobe. 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.
The following features are disabled because they overlap with
vanilla kernel mechanisms:
/proc hardening:
use instead. This
trades weaker protection for greater compatibility.
dmesg restrictions:
use instead
Using a custom grsecurity/PaX kernel
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.
To build a custom kernel using upstream's recommended settings for server
deployments, while still using the NixOS module:
nixpkgs.config.packageOverrides = super: {
linux_grsec_nixos = super.linux_grsec_nixos.override {
extraConfig = ''
GRKERNSEC_CONFIG_AUTO y
GRKERNSEC_CONFIG_SERVER y
GRKERNSEC_CONFIG_SECURITY y
'';
};
}
The wikibook provides an exhaustive listing of
kernel configuration options.
The NixOS module makes several assumptions about the kernel and so
may be incompatible with your customised kernel. Currently, the only way
to work around incompatibilities is to eschew the NixOS module.
If not using the NixOS module, a custom grsecurity package set can
be specified inline instead, as in
boot.kernelPackages =
let
kernel = pkgs.linux_grsec_nixos.override {
extraConfig = /* as above */;
};
self = pkgs.linuxPackagesFor kernel self;
in self;
Per-executable PaX flags
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 dmesg output).
For executables installed outside of the Nix store, PaX flags can be set
using the paxctl utility:
paxctl -czem foopaxctl overwrites files in-place.
Equivalently, on file systems that support extended attributes:
setfattr -n user.pax.flags -v em fooIssues and work-aroundsUser namespaces require CAP_SYS_ADMIN:
consequently, unprivileged namespaces are unsupported. Applications that
rely on namespaces for sandboxing must use a privileged helper. For chromium
there is .Access to EFI runtime services is disabled by default:
this plugs a potential code injection attack vector; use
to override
this behavior.User initiated autoloading of modules (e.g., when
using fuse or loop devices) is disallowed; either load requisite modules
as root or add them to.Virtualization: KVM is the preferred virtualization
solution. Xen, Virtualbox, and VMWare are
unsupported and most likely require a custom kernel.
Attaching gdb 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
boot.kernel.sysctl."kernel.grsecurity.harden_ptrace" = 0;
Overflows in boot critical code (e.g., the root filesystem module) can
render the system unbootable. Work around by setting
boot.kernel.kernelParams = [ "pax_size_overflow_report_only" ];
The modify_ldt
2 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
boot.kernel.sysctl."kernel.modify_ldt" = 1;
The gitlab service ()
requires a variant of the ruby interpreter
built without `mprotect()` hardening, as in
services.gitlab.packages.gitlab = pkgs.gitlab.override {
ruby = pkgs.ruby.overrideAttrs (attrs: {
postFixup = "paxmark m $out/bin/ruby";
});
};
Grsecurity/PaX kernel parameters
The NixOS kernel supports the following kernel command line parameters:
pax_nouderef: disable UDEREF (separate kernel and
user address spaces).
pax_weakuderef: enable a faster but
weaker variant of UDEREF on 64-bit processors with PCID support
(check grep pcid /proc/cpuinfo).
pax_sanitize_slab={off|fast|full}: control kernel
slab object sanitization. Defaults to fastpax_size_overflow_report_only: log size overflow
violations but leave the violating task running
grsec_sysfs_restrict=[0|1]: toggle sysfs
restrictions. The NixOS module sets this to 0
for systemd compatibility