summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
authorElis Hirwing <elis@hirwing.se>2019-06-27 19:13:53 +0200
committerGitHub <noreply@github.com>2019-06-27 19:13:53 +0200
commitb5478fd1a2ef442a54c36031bf3a27a96b5ea31c (patch)
treea898427ac474957a680888252c810e4bdfe37ecc /nixos/modules
parentdbb00bfcbfb291e79d4d2d512041656e6bcfcd9a (diff)
parenteee87b460ea9a5a9e122dcc313fa20b9962872a5 (diff)
downloadnixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.tar
nixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.tar.gz
nixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.tar.bz2
nixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.tar.lz
nixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.tar.xz
nixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.tar.zst
nixpkgs-b5478fd1a2ef442a54c36031bf3a27a96b5ea31c.zip
Merge pull request #63156 from Izorkin/phpfpm-rootless
phpfpm: do not run anything as root
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/rename.nix6
-rw-r--r--nixos/modules/services/mail/roundcube.nix42
-rw-r--r--nixos/modules/services/misc/zoneminder.nix10
-rw-r--r--nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix36
-rw-r--r--nixos/modules/services/web-apps/limesurvey.nix8
-rw-r--r--nixos/modules/services/web-apps/matomo.nix38
-rw-r--r--nixos/modules/services/web-apps/nextcloud.nix13
-rw-r--r--nixos/modules/services/web-apps/restya-board.nix18
-rw-r--r--nixos/modules/services/web-apps/selfoss.nix45
-rw-r--r--nixos/modules/services/web-apps/tt-rss.nix12
-rw-r--r--nixos/modules/services/web-servers/phpfpm/default.nix186
-rw-r--r--nixos/modules/services/web-servers/phpfpm/pool-options.nix57
12 files changed, 230 insertions, 241 deletions
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 7fa76dc0c68..5be7b25da74 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -241,6 +241,12 @@ with lib;
     # binfmt
     (mkRenamedOptionModule [ "boot" "binfmtMiscRegistrations" ] [ "boot" "binfmt" "registrations" ])
 
+    # PHP-FPM
+    (mkRemovedOptionModule [ "services" "phpfpm" "poolConfigs" ] "Use services.phpfpm.pools instead.")
+    (mkRemovedOptionModule [ "services" "phpfpm" "phpPackage" ] "Use services.phpfpm.pools.<name>.phpPackage instead.")
+    (mkRemovedOptionModule [ "services" "phpfpm" "phpOptions" ] "Use services.phpfpm.pools.<name>.phpOptions instead.")
+    (mkRenamedOptionModule [ "services" "phpfpm" "extraConfig" ] [ "services" "phpfpm" "globalExtraConfig" ])
+
   ] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
                    "jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
                    "snmpExporter" "unifiExporter" "varnishExporter" ]
diff --git a/nixos/modules/services/mail/roundcube.nix b/nixos/modules/services/mail/roundcube.nix
index e8b2e11bf72..12837f7efe7 100644
--- a/nixos/modules/services/mail/roundcube.nix
+++ b/nixos/modules/services/mail/roundcube.nix
@@ -105,7 +105,7 @@ in
             extraConfig = ''
               location ~* \.php$ {
                 fastcgi_split_path_info ^(.+\.php)(/.+)$;
-                fastcgi_pass unix:/run/phpfpm/roundcube;
+                fastcgi_pass unix:/run/phpfpm-roundcube/roundcube.sock;
                 include ${pkgs.nginx}/conf/fastcgi_params;
                 include ${pkgs.nginx}/conf/fastcgi.conf;
               }
@@ -119,24 +119,28 @@ in
       enable = true;
     };
 
-    services.phpfpm.poolConfigs.roundcube = ''
-      listen = /run/phpfpm/roundcube
-      listen.owner = nginx
-      listen.group = nginx
-      listen.mode = 0660
-      user = nginx
-      pm = dynamic
-      pm.max_children = 75
-      pm.start_servers = 2
-      pm.min_spare_servers = 1
-      pm.max_spare_servers = 20
-      pm.max_requests = 500
-      php_admin_value[error_log] = 'stderr'
-      php_admin_flag[log_errors] = on
-      php_admin_value[post_max_size] = 25M
-      php_admin_value[upload_max_filesize] = 25M
-      catch_workers_output = yes
-    '';
+    services.phpfpm.pools.roundcube = {
+      socketName = "roundcube";
+      phpPackage = pkgs.php;
+      user = "${config.services.nginx.user}";
+      group = "${config.services.nginx.group}";
+      extraConfig = ''
+        listen.owner = ${config.services.nginx.user}
+        listen.group = ${config.services.nginx.group}
+        listen.mode = 0600
+        pm = dynamic
+        pm.max_children = 75
+        pm.start_servers = 2
+        pm.min_spare_servers = 1
+        pm.max_spare_servers = 20
+        pm.max_requests = 500
+        php_admin_value[error_log] = 'stderr'
+        php_admin_flag[log_errors] = on
+        php_admin_value[post_max_size] = 25M
+        php_admin_value[upload_max_filesize] = 25M
+        catch_workers_output = yes
+      '';
+    };
     systemd.services.phpfpm-roundcube.after = [ "roundcube-setup.service" ];
 
     systemd.services.roundcube-setup = let
diff --git a/nixos/modules/services/misc/zoneminder.nix b/nixos/modules/services/misc/zoneminder.nix
index 8d58c2b37c8..b0ee961c77f 100644
--- a/nixos/modules/services/misc/zoneminder.nix
+++ b/nixos/modules/services/misc/zoneminder.nix
@@ -19,7 +19,7 @@ let
 
   useCustomDir = cfg.storageDir != null;
 
-  socket = "/run/phpfpm/${dirName}.sock";
+  socket = "/run/phpfpm-zoneminder/zoneminder.sock";
 
   zms = "/cgi-bin/zms";
 
@@ -284,7 +284,10 @@ in {
 
       phpfpm = lib.mkIf useNginx {
         pools.zoneminder = {
-          listen = socket;
+          socketName = "zoneminder";
+          phpPackage = pkgs.php;
+          user = "${user}";
+          group = "${group}";
           phpOptions = ''
             date.timezone = "${config.time.timeZone}"
 
@@ -292,9 +295,6 @@ in {
             "extension=${e.pkg}/lib/php/extensions/${e.name}.so") phpExtensions)}
           '';
           extraConfig = ''
-            user = ${user}
-            group = ${group}
-
             listen.owner = ${user}
             listen.group = ${group}
             listen.mode = 0660
diff --git a/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix b/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix
index 910e1d937bf..e83270fda5c 100644
--- a/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix
+++ b/nixos/modules/services/web-apps/icingaweb2/icingaweb2.nix
@@ -1,7 +1,6 @@
 { config, lib, pkgs, ... }: with lib; let
   cfg = config.services.icingaweb2;
   poolName = "icingaweb2";
-  phpfpmSocketName = "/var/run/phpfpm/${poolName}.sock";
 
   defaultConfig = {
     global = {
@@ -162,19 +161,23 @@ in {
   };
 
   config = mkIf cfg.enable {
-    services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") {
-      "${poolName}" = ''
-        listen = "${phpfpmSocketName}"
-        listen.owner = nginx
-        listen.group = nginx
-        listen.mode = 0600
-        user = icingaweb2
-        pm = dynamic
-        pm.max_children = 75
-        pm.start_servers = 2
-        pm.min_spare_servers = 2
-        pm.max_spare_servers = 10
-      '';
+    services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
+      "${poolName}" = {
+        socketName = "${poolName}";
+        phpPackage = pkgs.php;
+        user = "icingaweb2";
+        group = "icingaweb2";
+        extraConfig = ''
+          listen.owner = ${config.services.nginx.user}
+          listen.group = ${config.services.nginx.group}
+          listen.mode = 0600
+          pm = dynamic
+          pm.max_children = 75
+          pm.start_servers = 2
+          pm.min_spare_servers = 2
+          pm.max_spare_servers = 10
+        '';
+      };
     };
 
     services.phpfpm.phpOptions = mkIf (cfg.pool == "${poolName}")
@@ -206,7 +209,7 @@ in {
             include ${config.services.nginx.package}/conf/fastcgi.conf;
             try_files $uri =404;
             fastcgi_split_path_info ^(.+\.php)(/.+)$;
-            fastcgi_pass unix:${phpfpmSocketName};
+            fastcgi_pass unix:/run/phpfpm-${poolName}/${poolName}.sock;
             fastcgi_param SCRIPT_FILENAME ${pkgs.icingaweb2}/public/index.php;
           '';
         };
@@ -239,5 +242,8 @@ in {
       group = "icingaweb2";
       isSystemUser = true;
     };
+    users.users.nginx = {
+      extraGroups = [ "icingaweb2" ];
+    };
   };
 }
diff --git a/nixos/modules/services/web-apps/limesurvey.nix b/nixos/modules/services/web-apps/limesurvey.nix
index f23b3075574..99a33b8371c 100644
--- a/nixos/modules/services/web-apps/limesurvey.nix
+++ b/nixos/modules/services/web-apps/limesurvey.nix
@@ -202,13 +202,13 @@ in
     };
 
     services.phpfpm.pools.limesurvey = {
+      socketName = "limesurvey";
       phpPackage = php;
-      listen = "/run/phpfpm/limesurvey.sock";
+      user = "${user}";
+      group = "${group}";
       extraConfig = ''
         listen.owner = ${config.services.httpd.user};
         listen.group = ${config.services.httpd.group};
-        user = ${user};
-        group = ${group};
 
         env[LIMESURVEY_CONFIG] = ${limesurveyConfig}
 
@@ -241,7 +241,7 @@ in
             <Directory "${pkg}/share/limesurvey">
               <FilesMatch "\.php$">
                 <If "-f %{REQUEST_FILENAME}">
-                  SetHandler "proxy:unix:/run/phpfpm/limesurvey.sock|fcgi://localhost/"
+                  SetHandler "proxy:unix:/run/phpfpm-limesurvey/limesurvey.sock|fcgi://localhost/"
                 </If>
               </FilesMatch>
 
diff --git a/nixos/modules/services/web-apps/matomo.nix b/nixos/modules/services/web-apps/matomo.nix
index 14aca45a342..e058c18ad87 100644
--- a/nixos/modules/services/web-apps/matomo.nix
+++ b/nixos/modules/services/web-apps/matomo.nix
@@ -4,13 +4,14 @@ let
   cfg = config.services.matomo;
 
   user = "matomo";
+  group = "matomo";
   dataDir = "/var/lib/${user}";
   deprecatedDataDir = "/var/lib/piwik";
 
   pool = user;
-  # it's not possible to use /run/phpfpm/${pool}.sock because /run/phpfpm/ is root:root 0770,
+  # it's not possible to use /run/phpfpm-${pool}/${pool}.sock because /run/phpfpm/ is root:root 0770,
   # and therefore is not accessible by the web server.
-  phpSocket = "/run/phpfpm-${pool}.sock";
+  phpSocket = "/run/phpfpm-${pool}/${pool}.sock";
   phpExecutionUnit = "phpfpm-${pool}";
   databaseService = "mysql.service";
 
@@ -137,9 +138,12 @@ in {
       isSystemUser = true;
       createHome = true;
       home = dataDir;
-      group  = user;
+      group  = "${group}";
     };
-    users.groups.${user} = {};
+    users.users.${config.services.nginx.user} = {
+      extraGroups = [ "${group}" ];
+    };
+    users.groups.${group} = {};
 
     systemd.services.matomo-setup-update = {
       # everything needs to set up and up to date before Matomo php files are executed
@@ -169,7 +173,7 @@ in {
           echo "Migrating from ${deprecatedDataDir} to ${dataDir}"
           mv -T ${deprecatedDataDir} ${dataDir}
         fi
-        chown -R ${user}:${user} ${dataDir}
+        chown -R ${user}:${group} ${dataDir}
         chmod -R ug+rwX,o-rwx ${dataDir}
         '';
       script = ''
@@ -225,22 +229,26 @@ in {
       serviceConfig.UMask = "0007";
     };
 
-    services.phpfpm.poolConfigs = let
+    services.phpfpm.pools = let
       # workaround for when both are null and need to generate a string,
       # which is illegal, but as assertions apparently are being triggered *after* config generation,
       # we have to avoid already throwing errors at this previous stage.
       socketOwner = if (cfg.nginx != null) then config.services.nginx.user
       else if (cfg.webServerUser != null) then cfg.webServerUser else "";
     in {
-      ${pool} = ''
-        listen = "${phpSocket}"
-        listen.owner = ${socketOwner}
-        listen.group = root
-        listen.mode = 0600
-        user = ${user}
-        env[PIWIK_USER_PATH] = ${dataDir}
-        ${cfg.phpfpmProcessManagerConfig}
-      '';
+      ${pool} = {
+        socketName = "${pool}";
+        phpPackage = pkgs.php;
+        user = "${user}";
+        group = "${group}";
+        extraConfig = ''
+          listen.owner = ${socketOwner}
+          listen.group = ${group}
+          listen.mode = 0600
+          env[PIWIK_USER_PATH] = ${dataDir}
+          ${cfg.phpfpmProcessManagerConfig}
+        '';
+      };
     };
 
 
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index fa9a36d1189..9475af12fdd 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -394,13 +394,14 @@ in {
                 phpOptions)));
         in {
           phpOptions = phpOptionsExtensions;
+          socketName = "nextcloud";
           phpPackage = phpPackage;
-          listen = "/run/phpfpm/nextcloud";
+          user = "nextcloud";
+          group = "${config.services.nginx.group}";
           extraConfig = ''
-            listen.owner = nginx
-            listen.group = nginx
-            user = nextcloud
-            group = nginx
+            listen.owner = ${config.services.nginx.user}
+            listen.group = ${config.services.nginx.group}
+            listen.mode = 0600
             ${cfg.poolConfig}
             env[NEXTCLOUD_CONFIG_DIR] = ${cfg.home}/config
             env[PATH] = /run/wrappers/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/usr/bin:/bin
@@ -466,7 +467,7 @@ in {
                   fastcgi_param HTTPS ${if cfg.https then "on" else "off"};
                   fastcgi_param modHeadersAvailable true;
                   fastcgi_param front_controller_active true;
-                  fastcgi_pass unix:/run/phpfpm/nextcloud;
+                  fastcgi_pass unix:/run/phpfpm-nextcloud/nextcloud.sock;
                   fastcgi_intercept_errors on;
                   fastcgi_request_buffering off;
                   fastcgi_read_timeout 120s;
diff --git a/nixos/modules/services/web-apps/restya-board.nix b/nixos/modules/services/web-apps/restya-board.nix
index 2e5e0ea6622..d4c99d6c44b 100644
--- a/nixos/modules/services/web-apps/restya-board.nix
+++ b/nixos/modules/services/web-apps/restya-board.nix
@@ -13,7 +13,7 @@ let
   runDir = "/run/restya-board";
 
   poolName = "restya-board";
-  phpfpmSocketName = "/run/phpfpm/${poolName}.sock";
+  phpfpmSocketName = "/run/phpfpm-${poolName}/${poolName}.sock";
 
 in
 
@@ -178,9 +178,12 @@ in
 
   config = mkIf cfg.enable {
 
-    services.phpfpm.poolConfigs = {
+    services.phpfpm.pools = {
       "${poolName}" = {
-        listen = phpfpmSocketName;
+        socketName = "${poolName}";
+        phpPackage = pkgs.php;
+        user = "${cfg.user}";
+        group = "${cfg.group}";
         phpOptions = ''
           date.timezone = "CET"
 
@@ -192,11 +195,9 @@ in
           ''}
         '';
         extraConfig = ''
-          listen.owner = nginx
-          listen.group = nginx
+          listen.owner = ${config.services.nginx.user}
+          listen.group = ${config.services.nginx.group}
           listen.mode = 0600
-          user = ${cfg.user}
-          group = ${cfg.group}
           pm = dynamic
           pm.max_children = 75
           pm.start_servers = 10
@@ -365,6 +366,9 @@ in
       home = runDir;
       group  = "restya-board";
     };
+    users.users.nginx = {
+      extraGroups = [ "restya-board" ];
+     };
     users.groups.restya-board = {};
 
     services.postgresql.enable = mkIf (cfg.database.host == null) true;
diff --git a/nixos/modules/services/web-apps/selfoss.nix b/nixos/modules/services/web-apps/selfoss.nix
index cd0f743a5fb..6c5942d1e17 100644
--- a/nixos/modules/services/web-apps/selfoss.nix
+++ b/nixos/modules/services/web-apps/selfoss.nix
@@ -3,9 +3,9 @@ with lib;
 let
   cfg = config.services.selfoss;
 
-  poolName = "selfoss_pool";
-  phpfpmSocketName = "/run/phpfpm/${poolName}.sock";
-
+  poolName = "selfoss";
+  phpfpmSocketName = "/run/phpfpm-${poolName}/${poolName}.sock";
+  group = "${cfg.user}";
   dataDir = "/var/lib/selfoss";
 
   selfoss-config =
@@ -116,21 +116,25 @@ in
 
   config = mkIf cfg.enable {
 
-    services.phpfpm.poolConfigs = mkIf (cfg.pool == "${poolName}") {
-      "${poolName}" = ''
-        listen = "${phpfpmSocketName}";
-        listen.owner = nginx
-        listen.group = nginx
-        listen.mode = 0600
-        user = nginx
-        pm = dynamic
-        pm.max_children = 75
-        pm.start_servers = 10
-        pm.min_spare_servers = 5
-        pm.max_spare_servers = 20
-        pm.max_requests = 500
-        catch_workers_output = 1
-      '';
+    services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
+      "${poolName}" = {
+        socketName = "${poolName}";
+        phpPackage = pkgs.php;
+        user = "${cfg.user}";
+        group = "${group}";
+        extraConfig = ''
+          listen.owner = ${config.services.nginx.user}
+          listen.group = ${config.services.nginx.group}
+          listen.mode = 0600
+          pm = dynamic
+          pm.max_children = 75
+          pm.start_servers = 10
+          pm.min_spare_servers = 5
+          pm.max_spare_servers = 20
+          pm.max_requests = 500
+          catch_workers_output = 1
+        '';
+      };
     };
 
     systemd.services.selfoss-config = {
@@ -145,7 +149,7 @@ in
         # Create the files
         cp -r "${pkgs.selfoss}/"* "${dataDir}"
         ln -sf "${selfoss-config}" "${dataDir}/config.ini"
-        chown -R "${cfg.user}" "${dataDir}"
+        chown -R "${cfg.user}":"${group}" "${dataDir}"
         chmod -R 755 "${dataDir}"
       '';
       wantedBy = [ "multi-user.target" ];
@@ -162,5 +166,8 @@ in
 
     };
 
+    users.users.nginx = {
+      extraGroups = [ "${group}" ];
+     };
   };
 }
diff --git a/nixos/modules/services/web-apps/tt-rss.nix b/nixos/modules/services/web-apps/tt-rss.nix
index b882f6c2ae7..e59988ef7b2 100644
--- a/nixos/modules/services/web-apps/tt-rss.nix
+++ b/nixos/modules/services/web-apps/tt-rss.nix
@@ -512,12 +512,14 @@ let
 
     services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
       "${poolName}" = {
-        listen = "/var/run/phpfpm/${poolName}.sock";
+        socketName = "${poolName}";
+        phpPackage = pkgs.php;
+        user = "${config.services.nginx.user}";
+        group = "${config.services.nginx.group}";
         extraConfig = ''
-          listen.owner = nginx
-          listen.group = nginx
+          listen.owner = ${config.services.nginx.user}
+          listen.group = ${config.services.nginx.group}
           listen.mode = 0600
-          user = ${cfg.user}
           pm = dynamic
           pm.max_children = 75
           pm.start_servers = 10
@@ -543,7 +545,7 @@ let
           locations."~ \.php$" = {
             extraConfig = ''
               fastcgi_split_path_info ^(.+\.php)(/.+)$;
-              fastcgi_pass unix:${config.services.phpfpm.pools.${cfg.pool}.listen};
+              fastcgi_pass unix:/run/phpfpm-${poolName}/${poolName}.sock;
               fastcgi_index index.php;
             '';
           };
diff --git a/nixos/modules/services/web-servers/phpfpm/default.nix b/nixos/modules/services/web-servers/phpfpm/default.nix
index ffafbc5e92f..e424080ab1f 100644
--- a/nixos/modules/services/web-servers/phpfpm/default.nix
+++ b/nixos/modules/services/web-servers/phpfpm/default.nix
@@ -4,37 +4,26 @@ with lib;
 
 let
   cfg = config.services.phpfpm;
-  enabled = cfg.poolConfigs != {} || cfg.pools != {};
+  enabled = cfg.pools != {};
 
-  stateDir = "/run/phpfpm";
-
-  poolConfigs =
-    (mapAttrs mapPoolConfig cfg.poolConfigs) //
-    (mapAttrs mapPool cfg.pools);
-
-  mapPoolConfig = n: p: {
-    phpPackage = cfg.phpPackage;
-    phpOptions = cfg.phpOptions;
-    config = p;
-  };
+  poolConfigs = (mapAttrs mapPool cfg.pools);
 
   mapPool = n: p: {
     phpPackage = p.phpPackage;
     phpOptions = p.phpOptions;
-    config = ''
-      listen = ${p.listen}
-      ${p.extraConfig}
-    '';
+    userPool = p.user;
+    groupPool = p.group;
   };
 
   fpmCfgFile = pool: conf: pkgs.writeText "phpfpm-${pool}.conf" ''
     [global]
     error_log = syslog
     daemonize = no
-    ${cfg.extraConfig}
+    ${cfg.globalExtraConfig}
 
     [${pool}]
-    ${conf}
+    listen = /run/phpfpm-${pool}/${cfg.pools.${pool}.socketName}.sock
+    ${cfg.pools.${pool}.extraConfig}
   '';
 
   phpIni = pool: pkgs.runCommand "php.ini" {
@@ -49,87 +38,100 @@ let
   '';
 
 in {
-
   options = {
     services.phpfpm = {
-      extraConfig = mkOption {
+      globalExtraConfig = mkOption {
         type = types.lines;
         default = "";
         description = ''
-          Extra configuration that should be put in the global section of
+          Global extra configuration that should be put in the global section of
           the PHP-FPM configuration file. Do not specify the options
           <literal>error_log</literal> or
-          <literal>daemonize</literal> here, since they are generated by
-          NixOS.
-        '';
-      };
-
-      phpPackage = mkOption {
-        type = types.package;
-        default = pkgs.php;
-        defaultText = "pkgs.php";
-        description = ''
-          The PHP package to use for running the PHP-FPM service.
+          <literal>daemonize</literal> here, since they are generated by NixOS.
         '';
       };
 
-      phpOptions = mkOption {
-        type = types.lines;
-        default = "";
-        example =
-          ''
-            date.timezone = "CET"
-          '';
-        description =
-          "Options appended to the PHP configuration file <filename>php.ini</filename>.";
-      };
-
-      poolConfigs = mkOption {
+      pools = mkOption {
         default = {};
-        type = types.attrsOf types.lines;
+        type = types.attrsOf (types.submodule {
+          options = {
+            socketName = mkOption {
+              type = types.str;
+              example = "php-fpm";
+              description = ''
+                The address on which to accept FastCGI requests.
+              '';
+            };
+
+            phpPackage = mkOption {
+              type = types.package;
+              default = fpmCfg.phpPackage;
+              defaultText = "config.services.phpfpm.phpPackage";
+              description = ''
+                The PHP package to use for running this PHP-FPM pool.
+              '';
+            };
+
+            phpOptions = mkOption {
+              type = types.lines;
+              default = fpmCfg.phpOptions;
+              defaultText = "config.services.phpfpm.phpOptions";
+              description = ''
+                "Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool."
+              '';
+            };
+
+            user = mkOption {
+              type = types.string;
+              default = "phpfpm";
+              description = "User account under which phpfpm runs.";
+            };
+
+            group = mkOption {
+              type = types.string;
+              default = "phpfpm";
+              description = "Group account under which phpfpm runs.";
+            };
+
+            extraConfig = mkOption {
+              type = types.lines;
+              example = ''
+                pm = dynamic
+                pm.max_children = 75
+                pm.start_servers = 10
+                pm.min_spare_servers = 5
+                pm.max_spare_servers = 20
+                pm.max_requests = 500
+              '';
+
+              description = ''
+                Extra lines that go into the pool configuration.
+                See the documentation on <literal>php-fpm.conf</literal> for
+                details on configuration directives.
+              '';
+            };
+          };
+        });
+
         example = literalExample ''
-          { mypool = '''
-              listen = /run/phpfpm/mypool
-              user = nobody
-              pm = dynamic
-              pm.max_children = 75
-              pm.start_servers = 10
-              pm.min_spare_servers = 5
-              pm.max_spare_servers = 20
-              pm.max_requests = 500
-            ''';
+          {
+            mypool = {
+              socketName = "example";
+              phpPackage = pkgs.php;
+              user = "phpfpm";
+              group = "phpfpm";
+              extraConfig = '''
+                pm = dynamic
+                pm.max_children = 75
+                pm.start_servers = 10
+                pm.min_spare_servers = 5
+                pm.max_spare_servers = 20
+                pm.max_requests = 500
+              ''';
+            }
           }
         '';
         description = ''
-          A mapping between PHP-FPM pool names and their configurations.
-          See the documentation on <literal>php-fpm.conf</literal> for
-          details on configuration directives. If no pools are defined,
-          the phpfpm service is disabled.
-        '';
-      };
-
-      pools = mkOption {
-        type = types.attrsOf (types.submodule (import ./pool-options.nix {
-          inherit lib config;
-        }));
-        default = {};
-        example = literalExample ''
-         {
-           mypool = {
-             listen = "/path/to/unix/socket";
-             phpPackage = pkgs.php;
-             extraConfig = '''
-               user = nobody
-               pm = dynamic
-               pm.max_children = 75
-               pm.start_servers = 10
-               pm.min_spare_servers = 5
-               pm.max_spare_servers = 20
-               pm.max_requests = 500
-             ''';
-           }
-         }'';
-        description = ''
           PHP-FPM pools. If no pools or poolConfigs are defined, the PHP-FPM
           service is disabled.
         '';
@@ -154,9 +156,6 @@ in {
         after = [ "network.target" ];
         wantedBy = [ "phpfpm.target" ];
         partOf = [ "phpfpm.target" ];
-        preStart = ''
-          mkdir -p ${stateDir}
-        '';
         serviceConfig = let
           cfgFile = fpmCfgFile pool poolConfig.config;
           iniFile = phpIni poolConfig;
@@ -166,10 +165,19 @@ in {
           ProtectSystem = "full";
           ProtectHome = true;
           # XXX: We need AF_NETLINK to make the sendmail SUID binary from postfix work
-          RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
+          RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
           Type = "notify";
-          ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y ${cfgFile} -c ${iniFile}";
+          ExecStart = "${poolConfig.phpPackage}/bin/php-fpm -y '${cfgFile}' -c '${iniFile}'";
           ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
+          # User and group
+          User = "${poolConfig.userPool}";
+          Group = "${poolConfig.groupPool}";
+          # Runtime directory and mode
+          RuntimeDirectory = "phpfpm-${pool}";
+          RuntimeDirectoryMode = "0750";
+          # Capabilities
+          AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" "CAP_CHOWN" "CAP_SYS_RESOURCE" ];
+          CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" "CAP_CHOWN" "CAP_SYS_RESOURCE" ];
         };
       }
    );
diff --git a/nixos/modules/services/web-servers/phpfpm/pool-options.nix b/nixos/modules/services/web-servers/phpfpm/pool-options.nix
deleted file mode 100644
index d9ad7eff71f..00000000000
--- a/nixos/modules/services/web-servers/phpfpm/pool-options.nix
+++ /dev/null
@@ -1,57 +0,0 @@
-{ lib, config }:
-
-let
-  fpmCfg = config.services.phpfpm;
-in
-
-with lib; {
-
-  options = {
-
-    listen = mkOption {
-      type = types.str;
-      example = "/path/to/unix/socket";
-      description = ''
-        The address on which to accept FastCGI requests.
-      '';
-    };
-
-    phpPackage = mkOption {
-      type = types.package;
-      default = fpmCfg.phpPackage;
-      defaultText = "config.services.phpfpm.phpPackage";
-      description = ''
-        The PHP package to use for running this PHP-FPM pool.
-      '';
-    };
-
-    phpOptions = mkOption {
-      type = types.lines;
-      default = fpmCfg.phpOptions;
-      defaultText = "config.services.phpfpm.phpOptions";
-      description = ''
-        "Options appended to the PHP configuration file <filename>php.ini</filename> used for this PHP-FPM pool."
-      '';
-    };
-
-    extraConfig = mkOption {
-      type = types.lines;
-      example = ''
-        user = nobody
-        pm = dynamic
-        pm.max_children = 75
-        pm.start_servers = 10
-        pm.min_spare_servers = 5
-        pm.max_spare_servers = 20
-        pm.max_requests = 500
-      '';
-
-      description = ''
-        Extra lines that go into the pool configuration.
-        See the documentation on <literal>php-fpm.conf</literal> for
-        details on configuration directives.
-      '';
-    };
-  };
-}
-