diff --git a/nixos/modules/services/web-servers/unit/default.nix b/nixos/modules/services/web-servers/unit/default.nix index f8a18954fc9..989866144e1 100644 --- a/nixos/modules/services/web-servers/unit/default.nix +++ b/nixos/modules/services/web-servers/unit/default.nix @@ -91,41 +91,47 @@ in { description = "Unit App Server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - path = with pkgs; [ curl ]; preStart = '' - test -f '${cfg.stateDir}/conf.json' || rm -f '${cfg.stateDir}/conf.json' + [ ! -e '${cfg.stateDir}/conf.json' ] || rm -f '${cfg.stateDir}/conf.json' ''; postStart = '' - curl -X PUT --data-binary '@${configFile}' --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config' + ${pkgs.curl}/bin/curl -X PUT --data-binary '@${configFile}' --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config' ''; serviceConfig = { + Type = "forking"; + PIDFile = "/run/unit/unit.pid"; ExecStart = '' ${cfg.package}/bin/unitd --control 'unix:/run/unit/control.unit.sock' --pid '/run/unit/unit.pid' \ - --log '${cfg.logDir}/unit.log' --state '${cfg.stateDir}' --no-daemon \ + --log '${cfg.logDir}/unit.log' --state '${cfg.stateDir}' \ --user ${cfg.user} --group ${cfg.group} ''; - # User and group - User = cfg.user; - Group = cfg.group; - # Capabilities - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" ]; + ExecStop = '' + ${pkgs.curl}/bin/curl -X DELETE --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config' + ''; + # Runtime directory and mode + RuntimeDirectory = "unit"; + RuntimeDirectoryMode = "0750"; + # Access write directories + ReadWritePaths = [ cfg.stateDir cfg.logDir ]; # Security NoNewPrivileges = true; # Sandboxing - ProtectSystem = "full"; + ProtectSystem = "strict"; ProtectHome = true; - RuntimeDirectory = "unit"; - RuntimeDirectoryMode = "0750"; PrivateTmp = true; PrivateDevices = true; ProtectHostname = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; LockPersonality = true; MemoryDenyWriteExecute = true; RestrictRealtime = true; + RestrictSUIDSGID = true; PrivateMounts = true; + # System Call Filtering + SystemCallArchitectures = "native"; }; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 46f552b26a4..d1b1acc292d 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -321,6 +321,7 @@ in trickster = handleTest ./trickster.nix {}; tuptime = handleTest ./tuptime.nix {}; udisks2 = handleTest ./udisks2.nix {}; + unit-php = handleTest ./web-servers/unit-php.nix {}; upnp = handleTest ./upnp.nix {}; uwsgi = handleTest ./uwsgi.nix {}; vault = handleTest ./vault.nix {}; diff --git a/nixos/tests/web-servers/unit-php.nix b/nixos/tests/web-servers/unit-php.nix new file mode 100644 index 00000000000..c6327a1f825 --- /dev/null +++ b/nixos/tests/web-servers/unit-php.nix @@ -0,0 +1,47 @@ +import ../make-test-python.nix ({pkgs, ...}: + let + testdir = pkgs.writeTextDir "www/info.php" "capabilities.setid; - -+ drop_caps = cap_setid; -+ - #if (NXT_HAVE_CLONE_NEWUSER) -- if (!cap_setid && NXT_CLONE_USER(init->isolation.clone.flags)) { -+ if (NXT_CLONE_USER(init->isolation.clone.flags)) { - cap_setid = 1; -+ drop_caps = 0; - } - #endif - -@@ -301,6 +304,12 @@ nxt_process_start(nxt_task_t *task, nxt_ - if (nxt_slow_path(ret != NXT_OK)) { - goto fail; - } -+ -+#if (NXT_HAVE_LINUX_CAPABILITY) -+ if (drop_caps && nxt_capability_drop_all(task) != NXT_OK) { -+ goto fail; -+ } -+#endif - } - - rt->type = init->type; \ No newline at end of file