at 17.09-beta 6.3 kB view raw
1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.security.grsecurity; 7 grsecLockPath = "/proc/sys/kernel/grsecurity/grsec_lock"; 8 9 # Ascertain whether NixOS container support is required 10 containerSupportRequired = 11 config.boot.enableContainers && config.containers != {}; 12in 13 14{ 15 meta = { 16 maintainers = with maintainers; [ ]; 17 doc = ./grsecurity.xml; 18 }; 19 20 options.security.grsecurity = { 21 22 enable = mkOption { 23 type = types.bool; 24 default = false; 25 description = '' 26 Enable grsecurity/PaX. 27 ''; 28 }; 29 30 lockTunables = mkOption { 31 type = types.bool; 32 default = true; 33 description = '' 34 Whether to automatically lock grsecurity tunables 35 (<option>boot.kernel.sysctl."kernel.grsecurity.*"</option>). Disable 36 this to allow runtime configuration of grsecurity features. Activate 37 the <literal>grsec-lock</literal> service unit to prevent further 38 configuration until the next reboot. 39 ''; 40 }; 41 42 disableEfiRuntimeServices = mkOption { 43 type = types.bool; 44 default = true; 45 description = '' 46 Whether to disable access to EFI runtime services. Enabling EFI runtime 47 services creates a venue for code injection attacks on the kernel and 48 should be disabled if at all possible. Changing this option enters into 49 effect upon reboot. 50 ''; 51 }; 52 53 }; 54 55 config = mkIf cfg.enable { 56 57 boot.kernelPackages = mkForce pkgs.linuxPackages_grsec_nixos; 58 59 boot.kernelParams = [ "grsec_sysfs_restrict=0" ] 60 ++ optional cfg.disableEfiRuntimeServices "noefi"; 61 62 nixpkgs.config.grsecurity = true; 63 64 # Install PaX related utillities into the system profile. 65 environment.systemPackages = with pkgs; [ gradm paxctl pax-utils ]; 66 67 # Install rules for the grsec device node 68 services.udev.packages = [ pkgs.gradm ]; 69 70 # This service unit is responsible for locking the grsecurity tunables. The 71 # unit is always defined, but only activated on bootup if lockTunables is 72 # toggled. When lockTunables is toggled, failure to activate the unit will 73 # enter emergency mode. The intent is to make it difficult to silently 74 # enter multi-user mode without having locked the tunables. Some effort is 75 # made to ensure that starting the unit is an idempotent operation. 76 systemd.services.grsec-lock = { 77 description = "Lock grsecurity tunables"; 78 79 wantedBy = optional cfg.lockTunables "multi-user.target"; 80 81 wants = [ "local-fs.target" "systemd-sysctl.service" ]; 82 after = [ "local-fs.target" "systemd-sysctl.service" ]; 83 conflicts = [ "shutdown.target" ]; 84 85 restartIfChanged = false; 86 87 script = '' 88 if ${pkgs.gnugrep}/bin/grep -Fq 0 ${grsecLockPath} ; then 89 echo -n 1 > ${grsecLockPath} 90 fi 91 ''; 92 93 unitConfig = { 94 ConditionPathIsReadWrite = grsecLockPath; 95 DefaultDependencies = false; 96 } // optionalAttrs cfg.lockTunables { 97 OnFailure = "emergency.target"; 98 }; 99 100 serviceConfig = { 101 Type = "oneshot"; 102 RemainAfterExit = true; 103 }; 104 }; 105 106 # Configure system tunables 107 boot.kernel.sysctl = { 108 # Read-only under grsecurity 109 "kernel.kptr_restrict" = mkForce null; 110 111 # All grsec tunables default to off, those not enabled below are 112 # *disabled*. We use mkDefault to allow expert users to override 113 # our choices, but use mkForce where tunables would outright 114 # conflict with other settings. 115 116 # Enable all chroot restrictions by default (overwritten as 117 # necessary below) 118 "kernel.grsecurity.chroot_caps" = mkDefault 1; 119 "kernel.grsecurity.chroot_deny_bad_rename" = mkDefault 1; 120 "kernel.grsecurity.chroot_deny_chmod" = mkDefault 1; 121 "kernel.grsecurity.chroot_deny_chroot" = mkDefault 1; 122 "kernel.grsecurity.chroot_deny_fchdir" = mkDefault 1; 123 "kernel.grsecurity.chroot_deny_mknod" = mkDefault 1; 124 "kernel.grsecurity.chroot_deny_mount" = mkDefault 1; 125 "kernel.grsecurity.chroot_deny_pivot" = mkDefault 1; 126 "kernel.grsecurity.chroot_deny_shmat" = mkDefault 1; 127 "kernel.grsecurity.chroot_deny_sysctl" = mkDefault 1; 128 "kernel.grsecurity.chroot_deny_unix" = mkDefault 1; 129 "kernel.grsecurity.chroot_enforce_chdir" = mkDefault 1; 130 "kernel.grsecurity.chroot_findtask" = mkDefault 1; 131 "kernel.grsecurity.chroot_restrict_nice" = mkDefault 1; 132 133 # Enable various grsec protections 134 "kernel.grsecurity.consistent_setxid" = mkDefault 1; 135 "kernel.grsecurity.deter_bruteforce" = mkDefault 1; 136 "kernel.grsecurity.fifo_restrictions" = mkDefault 1; 137 "kernel.grsecurity.harden_ipc" = mkDefault 1; 138 "kernel.grsecurity.harden_ptrace" = mkDefault 1; 139 "kernel.grsecurity.harden_tty" = mkDefault 1; 140 "kernel.grsecurity.ip_blackhole" = mkDefault 1; 141 "kernel.grsecurity.linking_restrictions" = mkDefault 1; 142 "kernel.grsecurity.ptrace_readexec" = mkDefault 1; 143 144 # Enable auditing 145 "kernel.grsecurity.audit_ptrace" = mkDefault 1; 146 "kernel.grsecurity.forkfail_logging" = mkDefault 1; 147 "kernel.grsecurity.rwxmap_logging" = mkDefault 1; 148 "kernel.grsecurity.signal_logging" = mkDefault 1; 149 "kernel.grsecurity.timechange_logging" = mkDefault 1; 150 } // optionalAttrs config.nix.useSandbox { 151 # chroot(2) restrictions that conflict with sandboxed Nix builds 152 "kernel.grsecurity.chroot_caps" = mkForce 0; 153 "kernel.grsecurity.chroot_deny_chmod" = mkForce 0; 154 "kernel.grsecurity.chroot_deny_chroot" = mkForce 0; 155 "kernel.grsecurity.chroot_deny_mount" = mkForce 0; 156 "kernel.grsecurity.chroot_deny_pivot" = mkForce 0; 157 } // optionalAttrs containerSupportRequired { 158 # chroot(2) restrictions that conflict with NixOS lightweight containers 159 "kernel.grsecurity.chroot_caps" = mkForce 0; 160 "kernel.grsecurity.chroot_deny_chmod" = mkForce 0; 161 "kernel.grsecurity.chroot_deny_mount" = mkForce 0; 162 "kernel.grsecurity.chroot_restrict_nice" = mkForce 0; 163 # Disable privileged IO by default, unless X is enabled 164 } // optionalAttrs (!config.services.xserver.enable) { 165 "kernel.grsecurity.disable_priv_io" = mkDefault 1; 166 }; 167 168 }; 169}