192 lines
5.4 KiB
Nix
192 lines
5.4 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
with lib;
|
|
|
|
let
|
|
forEachInstance =
|
|
f:
|
|
flip mapAttrs' config.services.fcgiwrap.instances (
|
|
name: cfg: nameValuePair "fcgiwrap-${name}" (f cfg)
|
|
);
|
|
|
|
in
|
|
{
|
|
imports =
|
|
forEach
|
|
[
|
|
"enable"
|
|
"user"
|
|
"group"
|
|
"socketType"
|
|
"socketAddress"
|
|
"preforkProcesses"
|
|
]
|
|
(
|
|
attr:
|
|
mkRemovedOptionModule [ "services" "fcgiwrap" attr ] ''
|
|
The global shared fcgiwrap instance is no longer supported due to
|
|
security issues.
|
|
Isolated instances should instead be configured through
|
|
`services.fcgiwrap.instances.*'.
|
|
''
|
|
);
|
|
|
|
options.services.fcgiwrap.instances = mkOption {
|
|
description = "Configuration for fcgiwrap instances.";
|
|
default = { };
|
|
type = types.attrsOf (
|
|
types.submodule (
|
|
{ config, ... }:
|
|
{
|
|
options = {
|
|
process.prefork = mkOption {
|
|
type = types.ints.positive;
|
|
default = 1;
|
|
description = "Number of processes to prefork.";
|
|
};
|
|
|
|
process.user = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
User as which this instance of fcgiwrap will be run.
|
|
Set to `null` (the default) to use a dynamically allocated user.
|
|
'';
|
|
};
|
|
|
|
process.group = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = "Group as which this instance of fcgiwrap will be run.";
|
|
};
|
|
|
|
socket.type = mkOption {
|
|
type = types.enum [
|
|
"unix"
|
|
"tcp"
|
|
"tcp6"
|
|
];
|
|
default = "unix";
|
|
description = "Socket type: 'unix', 'tcp' or 'tcp6'.";
|
|
};
|
|
|
|
socket.address = mkOption {
|
|
type = types.str;
|
|
default = "/run/fcgiwrap-${config._module.args.name}.sock";
|
|
example = "1.2.3.4:5678";
|
|
description = ''
|
|
Socket address.
|
|
In case of a UNIX socket, this should be its filesystem path.
|
|
'';
|
|
};
|
|
|
|
socket.user = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
User to be set as owner of the UNIX socket.
|
|
'';
|
|
};
|
|
|
|
socket.group = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
Group to be set as owner of the UNIX socket.
|
|
'';
|
|
};
|
|
|
|
socket.mode = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = if config.socket.type == "unix" then "0600" else null;
|
|
defaultText = literalExpression ''
|
|
if config.socket.type == "unix" then "0600" else null
|
|
'';
|
|
description = ''
|
|
Mode to be set on the UNIX socket.
|
|
Defaults to private to the socket's owner.
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
)
|
|
);
|
|
};
|
|
|
|
config = {
|
|
assertions = concatLists (
|
|
mapAttrsToList (name: cfg: [
|
|
{
|
|
assertion = cfg.socket.type == "unix" -> cfg.socket.user != null;
|
|
message = "Socket owner is required for the UNIX socket type.";
|
|
}
|
|
{
|
|
assertion = cfg.socket.type == "unix" -> cfg.socket.group != null;
|
|
message = "Socket owner is required for the UNIX socket type.";
|
|
}
|
|
{
|
|
assertion = cfg.socket.user != null -> cfg.socket.type == "unix";
|
|
message = "Socket owner can only be set for the UNIX socket type.";
|
|
}
|
|
{
|
|
assertion = cfg.socket.group != null -> cfg.socket.type == "unix";
|
|
message = "Socket owner can only be set for the UNIX socket type.";
|
|
}
|
|
{
|
|
assertion = cfg.socket.mode != null -> cfg.socket.type == "unix";
|
|
message = "Socket mode can only be set for the UNIX socket type.";
|
|
}
|
|
]) config.services.fcgiwrap.instances
|
|
);
|
|
|
|
systemd.services = forEachInstance (cfg: {
|
|
after = [ "nss-user-lookup.target" ];
|
|
wantedBy = optional (cfg.socket.type != "unix") "multi-user.target";
|
|
|
|
serviceConfig =
|
|
{
|
|
ExecStart = ''
|
|
${pkgs.fcgiwrap}/sbin/fcgiwrap ${
|
|
cli.toGNUCommandLineShell { } (
|
|
{
|
|
c = cfg.process.prefork;
|
|
}
|
|
// (optionalAttrs (cfg.socket.type != "unix") {
|
|
s = "${cfg.socket.type}:${cfg.socket.address}";
|
|
})
|
|
)
|
|
}
|
|
'';
|
|
}
|
|
// (
|
|
if cfg.process.user != null then
|
|
{
|
|
User = cfg.process.user;
|
|
Group = cfg.process.group;
|
|
}
|
|
else
|
|
{
|
|
DynamicUser = true;
|
|
}
|
|
);
|
|
});
|
|
|
|
systemd.sockets = forEachInstance (
|
|
cfg:
|
|
mkIf (cfg.socket.type == "unix") {
|
|
wantedBy = [ "sockets.target" ];
|
|
socketConfig = {
|
|
ListenStream = cfg.socket.address;
|
|
SocketUser = cfg.socket.user;
|
|
SocketGroup = cfg.socket.group;
|
|
SocketMode = cfg.socket.mode;
|
|
};
|
|
}
|
|
);
|
|
};
|
|
}
|