diff --git a/nixos/doc/manual/release-notes/rl-2003.xml b/nixos/doc/manual/release-notes/rl-2003.xml
index 579b8d53744..55bd88ba850 100644
--- a/nixos/doc/manual/release-notes/rl-2003.xml
+++ b/nixos/doc/manual/release-notes/rl-2003.xml
@@ -249,6 +249,18 @@
SD images are now compressed by default using bzip2.
+
+
+ The nginx web server previously started its master process as root
+ privileged, then ran worker processes as a less privileged identity user.
+ This was changed to start all of nginx as a less privileged user (defined by
+ services.nginx.user and
+ services.nginx.group). As a consequence, all files that
+ are needed for nginx to run (included configuration fragments, SSL
+ certificates and keys, etc.) must now be readable by this less privileged
+ user/group.
+
+
OpenSSH has been upgraded from 7.9 to 8.1, improving security and adding features
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index eb90dae94df..9b476ba7f1e 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -47,7 +47,7 @@ let
''));
configFile = pkgs.writers.writeNginxConfig "nginx.conf" ''
- user ${cfg.user} ${cfg.group};
+ pid /run/nginx/nginx.pid;
error_log ${cfg.logError};
daemon off;
@@ -366,12 +366,7 @@ in
preStart = mkOption {
type = types.lines;
- default = ''
- test -d ${cfg.stateDir}/logs || mkdir -m 750 -p ${cfg.stateDir}/logs
- test `stat -c %a ${cfg.stateDir}` = "750" || chmod 750 ${cfg.stateDir}
- test `stat -c %a ${cfg.stateDir}/logs` = "750" || chmod 750 ${cfg.stateDir}/logs
- chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir}
- '';
+ default = "";
description = "
Shell commands executed before the service's nginx is started.
";
@@ -673,23 +668,35 @@ in
}
];
+ systemd.tmpfiles.rules = [
+ "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"
+ "d '${cfg.stateDir}/logs' 0750 ${cfg.user} ${cfg.group} - -"
+ ];
+
systemd.services.nginx = {
description = "Nginx Web Server";
wantedBy = [ "multi-user.target" ];
wants = concatLists (map (vhostConfig: ["acme-${vhostConfig.serverName}.service" "acme-selfsigned-${vhostConfig.serverName}.service"]) acmeEnabledVhosts);
after = [ "network.target" ] ++ map (vhostConfig: "acme-selfsigned-${vhostConfig.serverName}.service") acmeEnabledVhosts;
stopIfChanged = false;
- preStart =
- ''
+ preStart = ''
${cfg.preStart}
- ${cfg.package}/bin/nginx -c ${configPath} -p ${cfg.stateDir} -t
- '';
+ ${cfg.package}/bin/nginx -c '${configPath}' -p '${cfg.stateDir}' -t
+ '';
serviceConfig = {
- ExecStart = "${cfg.package}/bin/nginx -c ${configPath} -p ${cfg.stateDir}";
+ ExecStart = "${cfg.package}/bin/nginx -c '${configPath}' -p '${cfg.stateDir}'";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
Restart = "always";
RestartSec = "10s";
StartLimitInterval = "1min";
+ # User and group
+ User = cfg.user;
+ Group = cfg.group;
+ # Runtime directory and mode
+ RuntimeDirectory = "nginx";
+ RuntimeDirectoryMode = "0750";
+ # Capabilities
+ AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_SYS_RESOURCE" ];
};
};