Harden systemd service for Nix module #919

open
opened by hauleth.dev targeting master

This introduces set of hardening options to systemd's unit to isolate service more.

Applied restrictions are (among other):

  • no capabilities, and these cannot be changed (so calling binary with capabilities may cause an issue)
  • cannot call SUID/GUID binaries
  • restrict view on the OS to minimum
  • hide some shared resources (like users or /tmp)
  • disallow non-UNIX and non-INET(4/6) sockets
  • protect kernel settings and logs
  • force native syscalls (so for example on x86-64 there is no way to call x86 syscalls)
  • limit executables to Nix store

These shouldn't be too restrictive for most users.

Changed files
+43
nix
modules
+43
nix/modules/knot.nix
··· 275 ]; 276 ExecStart = "${cfg.package}/bin/knot server"; 277 Restart = "always"; 278 }; 279 }; 280
··· 275 ]; 276 ExecStart = "${cfg.package}/bin/knot server"; 277 Restart = "always"; 278 + 279 + # Hardening 280 + NoNewPrivileges = true; 281 + LockPersonality = true; 282 + RemoveIPC = true; 283 + 284 + MemoryDenyWriteExecute = true; 285 + 286 + CapabilityBoundingSet = [""]; 287 + 288 + RestrictNamespaces = true; 289 + RestrictRealtime = true; 290 + RestrictSUIDGUID = true; 291 + 292 + ProtectHostname = true; 293 + ProtectHome = false; # Important to be false, as Knot is using home path for storing repos 294 + ProtectClock = true; 295 + ProtectControlGroups = true; 296 + ProtectProc = "invisible"; 297 + ProcSubset = "pid"; 298 + 299 + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AD_INET6"]; 300 + 301 + DeviceAllow = [""]; 302 + 303 + PrivateDevices = true; 304 + PrivateTmp = true; 305 + PrivateMounts = true; 306 + PrivateUsers = true; 307 + 308 + # TODO: Maybe we could make it more restrictive 309 + ExecPaths = ["/nix/store"]; 310 + NoExecPaths = ["/"]; 311 + 312 + ProtectSystem = "strict"; 313 + 314 + ProtectKernelLogs = true; 315 + ProtectKernelModules = true; 316 + ProtectKernelTunables = true; 317 + 318 + SystemCallFilter = ["@system-service", "~@privileged"]; 319 + SystemCallArchitecture = ["native"]; 320 + SystemCallErrorNumber = "EPERM"; 321 }; 322 }; 323