|
|
@ -4,21 +4,21 @@ with lib;
|
|
|
|
|
|
|
|
|
|
|
|
let
|
|
|
|
let
|
|
|
|
|
|
|
|
|
|
|
|
mainCfg = config.services.httpd;
|
|
|
|
cfg = config.services.httpd;
|
|
|
|
|
|
|
|
|
|
|
|
runtimeDir = "/run/httpd";
|
|
|
|
runtimeDir = "/run/httpd";
|
|
|
|
|
|
|
|
|
|
|
|
httpd = mainCfg.package.out;
|
|
|
|
pkg = cfg.package.out;
|
|
|
|
|
|
|
|
|
|
|
|
httpdConf = mainCfg.configFile;
|
|
|
|
httpdConf = cfg.configFile;
|
|
|
|
|
|
|
|
|
|
|
|
php = mainCfg.phpPackage.override { apacheHttpd = httpd.dev; /* otherwise it only gets .out */ };
|
|
|
|
php = cfg.phpPackage.override { apacheHttpd = pkg.dev; /* otherwise it only gets .out */ };
|
|
|
|
|
|
|
|
|
|
|
|
phpMajorVersion = lib.versions.major (lib.getVersion php);
|
|
|
|
phpMajorVersion = lib.versions.major (lib.getVersion php);
|
|
|
|
|
|
|
|
|
|
|
|
mod_perl = pkgs.apacheHttpdPackages.mod_perl.override { apacheHttpd = httpd; };
|
|
|
|
mod_perl = pkgs.apacheHttpdPackages.mod_perl.override { apacheHttpd = pkg; };
|
|
|
|
|
|
|
|
|
|
|
|
vhosts = attrValues mainCfg.virtualHosts;
|
|
|
|
vhosts = attrValues cfg.virtualHosts;
|
|
|
|
|
|
|
|
|
|
|
|
mkListenInfo = hostOpts:
|
|
|
|
mkListenInfo = hostOpts:
|
|
|
|
if hostOpts.listen != [] then hostOpts.listen
|
|
|
|
if hostOpts.listen != [] then hostOpts.listen
|
|
|
@ -41,23 +41,18 @@ let
|
|
|
|
"mime" "autoindex" "negotiation" "dir"
|
|
|
|
"mime" "autoindex" "negotiation" "dir"
|
|
|
|
"alias" "rewrite"
|
|
|
|
"alias" "rewrite"
|
|
|
|
"unixd" "slotmem_shm" "socache_shmcb"
|
|
|
|
"unixd" "slotmem_shm" "socache_shmcb"
|
|
|
|
"mpm_${mainCfg.multiProcessingModule}"
|
|
|
|
"mpm_${cfg.multiProcessingModule}"
|
|
|
|
]
|
|
|
|
]
|
|
|
|
++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
|
|
|
|
++ (if cfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
|
|
|
|
++ optional enableSSL "ssl"
|
|
|
|
++ optional enableSSL "ssl"
|
|
|
|
++ optional enableUserDir "userdir"
|
|
|
|
++ optional enableUserDir "userdir"
|
|
|
|
++ optional mainCfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; }
|
|
|
|
++ optional cfg.enableMellon { name = "auth_mellon"; path = "${pkgs.apacheHttpdPackages.mod_auth_mellon}/modules/mod_auth_mellon.so"; }
|
|
|
|
++ optional mainCfg.enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; }
|
|
|
|
++ optional cfg.enablePHP { name = "php${phpMajorVersion}"; path = "${php}/modules/libphp${phpMajorVersion}.so"; }
|
|
|
|
++ optional mainCfg.enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; }
|
|
|
|
++ optional cfg.enablePerl { name = "perl"; path = "${mod_perl}/modules/mod_perl.so"; }
|
|
|
|
++ mainCfg.extraModules;
|
|
|
|
++ cfg.extraModules;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loggingConf = (if cfg.logFormat != "none" then ''
|
|
|
|
allDenied = "Require all denied";
|
|
|
|
ErrorLog ${cfg.logDir}/error.log
|
|
|
|
allGranted = "Require all granted";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loggingConf = (if mainCfg.logFormat != "none" then ''
|
|
|
|
|
|
|
|
ErrorLog ${mainCfg.logDir}/error.log
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LogLevel notice
|
|
|
|
LogLevel notice
|
|
|
|
|
|
|
|
|
|
|
@ -66,7 +61,7 @@ let
|
|
|
|
LogFormat "%{Referer}i -> %U" referer
|
|
|
|
LogFormat "%{Referer}i -> %U" referer
|
|
|
|
LogFormat "%{User-agent}i" agent
|
|
|
|
LogFormat "%{User-agent}i" agent
|
|
|
|
|
|
|
|
|
|
|
|
CustomLog ${mainCfg.logDir}/access.log ${mainCfg.logFormat}
|
|
|
|
CustomLog ${cfg.logDir}/access.log ${cfg.logFormat}
|
|
|
|
'' else ''
|
|
|
|
'' else ''
|
|
|
|
ErrorLog /dev/null
|
|
|
|
ErrorLog /dev/null
|
|
|
|
'');
|
|
|
|
'');
|
|
|
@ -88,6 +83,7 @@ let
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sslConf = ''
|
|
|
|
sslConf = ''
|
|
|
|
|
|
|
|
<IfModule mod_ssl.c>
|
|
|
|
SSLSessionCache shmcb:${runtimeDir}/ssl_scache(512000)
|
|
|
|
SSLSessionCache shmcb:${runtimeDir}/ssl_scache(512000)
|
|
|
|
|
|
|
|
|
|
|
|
Mutex posixsem
|
|
|
|
Mutex posixsem
|
|
|
@ -95,27 +91,28 @@ let
|
|
|
|
SSLRandomSeed startup builtin
|
|
|
|
SSLRandomSeed startup builtin
|
|
|
|
SSLRandomSeed connect builtin
|
|
|
|
SSLRandomSeed connect builtin
|
|
|
|
|
|
|
|
|
|
|
|
SSLProtocol ${mainCfg.sslProtocols}
|
|
|
|
SSLProtocol ${cfg.sslProtocols}
|
|
|
|
SSLCipherSuite ${mainCfg.sslCiphers}
|
|
|
|
SSLCipherSuite ${cfg.sslCiphers}
|
|
|
|
SSLHonorCipherOrder on
|
|
|
|
SSLHonorCipherOrder on
|
|
|
|
|
|
|
|
</IfModule>
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mimeConf = ''
|
|
|
|
mimeConf = ''
|
|
|
|
TypesConfig ${httpd}/conf/mime.types
|
|
|
|
TypesConfig ${pkg}/conf/mime.types
|
|
|
|
|
|
|
|
|
|
|
|
AddType application/x-x509-ca-cert .crt
|
|
|
|
AddType application/x-x509-ca-cert .crt
|
|
|
|
AddType application/x-pkcs7-crl .crl
|
|
|
|
AddType application/x-pkcs7-crl .crl
|
|
|
|
AddType application/x-httpd-php .php .phtml
|
|
|
|
AddType application/x-httpd-php .php .phtml
|
|
|
|
|
|
|
|
|
|
|
|
<IfModule mod_mime_magic.c>
|
|
|
|
<IfModule mod_mime_magic.c>
|
|
|
|
MIMEMagicFile ${httpd}/conf/magic
|
|
|
|
MIMEMagicFile ${pkg}/conf/magic
|
|
|
|
</IfModule>
|
|
|
|
</IfModule>
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
|
mkVHostConf = hostOpts:
|
|
|
|
mkVHostConf = hostOpts:
|
|
|
|
let
|
|
|
|
let
|
|
|
|
adminAddr = if hostOpts.adminAddr != null then hostOpts.adminAddr else mainCfg.adminAddr;
|
|
|
|
adminAddr = if hostOpts.adminAddr != null then hostOpts.adminAddr else cfg.adminAddr;
|
|
|
|
listen = filter (listen: !listen.ssl) (mkListenInfo hostOpts);
|
|
|
|
listen = filter (listen: !listen.ssl) (mkListenInfo hostOpts);
|
|
|
|
listenSSL = filter (listen: listen.ssl) (mkListenInfo hostOpts);
|
|
|
|
listenSSL = filter (listen: listen.ssl) (mkListenInfo hostOpts);
|
|
|
|
|
|
|
|
|
|
|
@ -203,9 +200,9 @@ let
|
|
|
|
'') (sortProperties (mapAttrsToList (k: v: v // { location = k; }) locations)));
|
|
|
|
'') (sortProperties (mapAttrsToList (k: v: v // { location = k; }) locations)));
|
|
|
|
in
|
|
|
|
in
|
|
|
|
''
|
|
|
|
''
|
|
|
|
${optionalString mainCfg.logPerVirtualHost ''
|
|
|
|
${optionalString cfg.logPerVirtualHost ''
|
|
|
|
ErrorLog ${mainCfg.logDir}/error-${hostOpts.hostName}.log
|
|
|
|
ErrorLog ${cfg.logDir}/error-${hostOpts.hostName}.log
|
|
|
|
CustomLog ${mainCfg.logDir}/access-${hostOpts.hostName}.log ${hostOpts.logFormat}
|
|
|
|
CustomLog ${cfg.logDir}/access-${hostOpts.hostName}.log ${hostOpts.logFormat}
|
|
|
|
''}
|
|
|
|
''}
|
|
|
|
|
|
|
|
|
|
|
|
${optionalString (hostOpts.robotsEntries != "") ''
|
|
|
|
${optionalString (hostOpts.robotsEntries != "") ''
|
|
|
@ -217,7 +214,7 @@ let
|
|
|
|
<Directory "${documentRoot}">
|
|
|
|
<Directory "${documentRoot}">
|
|
|
|
Options Indexes FollowSymLinks
|
|
|
|
Options Indexes FollowSymLinks
|
|
|
|
AllowOverride None
|
|
|
|
AllowOverride None
|
|
|
|
${allGranted}
|
|
|
|
Require all granted
|
|
|
|
</Directory>
|
|
|
|
</Directory>
|
|
|
|
|
|
|
|
|
|
|
|
${optionalString hostOpts.enableUserDir ''
|
|
|
|
${optionalString hostOpts.enableUserDir ''
|
|
|
@ -244,7 +241,7 @@ let
|
|
|
|
Alias ${elem.urlPath} ${elem.dir}/
|
|
|
|
Alias ${elem.urlPath} ${elem.dir}/
|
|
|
|
<Directory ${elem.dir}>
|
|
|
|
<Directory ${elem.dir}>
|
|
|
|
Options +Indexes
|
|
|
|
Options +Indexes
|
|
|
|
${allGranted}
|
|
|
|
Require all granted
|
|
|
|
AllowOverride All
|
|
|
|
AllowOverride All
|
|
|
|
</Directory>
|
|
|
|
</Directory>
|
|
|
|
'';
|
|
|
|
'';
|
|
|
@ -259,20 +256,20 @@ let
|
|
|
|
|
|
|
|
|
|
|
|
confFile = pkgs.writeText "httpd.conf" ''
|
|
|
|
confFile = pkgs.writeText "httpd.conf" ''
|
|
|
|
|
|
|
|
|
|
|
|
ServerRoot ${httpd}
|
|
|
|
ServerRoot ${pkg}
|
|
|
|
ServerName ${config.networking.hostName}
|
|
|
|
ServerName ${config.networking.hostName}
|
|
|
|
DefaultRuntimeDir ${runtimeDir}/runtime
|
|
|
|
DefaultRuntimeDir ${runtimeDir}/runtime
|
|
|
|
|
|
|
|
|
|
|
|
PidFile ${runtimeDir}/httpd.pid
|
|
|
|
PidFile ${runtimeDir}/httpd.pid
|
|
|
|
|
|
|
|
|
|
|
|
${optionalString (mainCfg.multiProcessingModule != "prefork") ''
|
|
|
|
${optionalString (cfg.multiProcessingModule != "prefork") ''
|
|
|
|
# mod_cgid requires this.
|
|
|
|
# mod_cgid requires this.
|
|
|
|
ScriptSock ${runtimeDir}/cgisock
|
|
|
|
ScriptSock ${runtimeDir}/cgisock
|
|
|
|
''}
|
|
|
|
''}
|
|
|
|
|
|
|
|
|
|
|
|
<IfModule prefork.c>
|
|
|
|
<IfModule prefork.c>
|
|
|
|
MaxClients ${toString mainCfg.maxClients}
|
|
|
|
MaxClients ${toString cfg.maxClients}
|
|
|
|
MaxRequestsPerChild ${toString mainCfg.maxRequestsPerChild}
|
|
|
|
MaxRequestsPerChild ${toString cfg.maxRequestsPerChild}
|
|
|
|
</IfModule>
|
|
|
|
</IfModule>
|
|
|
|
|
|
|
|
|
|
|
|
${let
|
|
|
|
${let
|
|
|
@ -281,12 +278,12 @@ let
|
|
|
|
in concatStringsSep "\n" uniqueListen
|
|
|
|
in concatStringsSep "\n" uniqueListen
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
User ${mainCfg.user}
|
|
|
|
User ${cfg.user}
|
|
|
|
Group ${mainCfg.group}
|
|
|
|
Group ${cfg.group}
|
|
|
|
|
|
|
|
|
|
|
|
${let
|
|
|
|
${let
|
|
|
|
mkModule = module:
|
|
|
|
mkModule = module:
|
|
|
|
if isString module then { name = module; path = "${httpd}/modules/mod_${module}.so"; }
|
|
|
|
if isString module then { name = module; path = "${pkg}/modules/mod_${module}.so"; }
|
|
|
|
else if isAttrs module then { inherit (module) name path; }
|
|
|
|
else if isAttrs module then { inherit (module) name path; }
|
|
|
|
else throw "Expecting either a string or attribute set including a name and path.";
|
|
|
|
else throw "Expecting either a string or attribute set including a name and path.";
|
|
|
|
in
|
|
|
|
in
|
|
|
@ -296,37 +293,37 @@ let
|
|
|
|
AddHandler type-map var
|
|
|
|
AddHandler type-map var
|
|
|
|
|
|
|
|
|
|
|
|
<Files ~ "^\.ht">
|
|
|
|
<Files ~ "^\.ht">
|
|
|
|
${allDenied}
|
|
|
|
Require all denied
|
|
|
|
</Files>
|
|
|
|
</Files>
|
|
|
|
|
|
|
|
|
|
|
|
${mimeConf}
|
|
|
|
${mimeConf}
|
|
|
|
${loggingConf}
|
|
|
|
${loggingConf}
|
|
|
|
${browserHacks}
|
|
|
|
${browserHacks}
|
|
|
|
|
|
|
|
|
|
|
|
Include ${httpd}/conf/extra/httpd-default.conf
|
|
|
|
Include ${pkg}/conf/extra/httpd-default.conf
|
|
|
|
Include ${httpd}/conf/extra/httpd-autoindex.conf
|
|
|
|
Include ${pkg}/conf/extra/httpd-autoindex.conf
|
|
|
|
Include ${httpd}/conf/extra/httpd-multilang-errordoc.conf
|
|
|
|
Include ${pkg}/conf/extra/httpd-multilang-errordoc.conf
|
|
|
|
Include ${httpd}/conf/extra/httpd-languages.conf
|
|
|
|
Include ${pkg}/conf/extra/httpd-languages.conf
|
|
|
|
|
|
|
|
|
|
|
|
TraceEnable off
|
|
|
|
TraceEnable off
|
|
|
|
|
|
|
|
|
|
|
|
${if enableSSL then sslConf else ""}
|
|
|
|
${sslConf}
|
|
|
|
|
|
|
|
|
|
|
|
# Fascist default - deny access to everything.
|
|
|
|
# Fascist default - deny access to everything.
|
|
|
|
<Directory />
|
|
|
|
<Directory />
|
|
|
|
Options FollowSymLinks
|
|
|
|
Options FollowSymLinks
|
|
|
|
AllowOverride None
|
|
|
|
AllowOverride None
|
|
|
|
${allDenied}
|
|
|
|
Require all denied
|
|
|
|
</Directory>
|
|
|
|
</Directory>
|
|
|
|
|
|
|
|
|
|
|
|
# But do allow access to files in the store so that we don't have
|
|
|
|
# But do allow access to files in the store so that we don't have
|
|
|
|
# to generate <Directory> clauses for every generated file that we
|
|
|
|
# to generate <Directory> clauses for every generated file that we
|
|
|
|
# want to serve.
|
|
|
|
# want to serve.
|
|
|
|
<Directory /nix/store>
|
|
|
|
<Directory /nix/store>
|
|
|
|
${allGranted}
|
|
|
|
Require all granted
|
|
|
|
</Directory>
|
|
|
|
</Directory>
|
|
|
|
|
|
|
|
|
|
|
|
${mainCfg.extraConfig}
|
|
|
|
${cfg.extraConfig}
|
|
|
|
|
|
|
|
|
|
|
|
${concatMapStringsSep "\n" mkVHostConf vhosts}
|
|
|
|
${concatMapStringsSep "\n" mkVHostConf vhosts}
|
|
|
|
'';
|
|
|
|
'';
|
|
|
@ -334,7 +331,7 @@ let
|
|
|
|
# Generate the PHP configuration file. Should probably be factored
|
|
|
|
# Generate the PHP configuration file. Should probably be factored
|
|
|
|
# out into a separate module.
|
|
|
|
# out into a separate module.
|
|
|
|
phpIni = pkgs.runCommand "php.ini"
|
|
|
|
phpIni = pkgs.runCommand "php.ini"
|
|
|
|
{ options = mainCfg.phpOptions;
|
|
|
|
{ options = cfg.phpOptions;
|
|
|
|
preferLocalBuild = true;
|
|
|
|
preferLocalBuild = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
''
|
|
|
|
''
|
|
|
@ -367,17 +364,13 @@ in
|
|
|
|
(mkRemovedOptionModule [ "services" "httpd" "sslServerKey" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
|
|
|
|
(mkRemovedOptionModule [ "services" "httpd" "sslServerKey" ] "Please define a virtual host using `services.httpd.virtualHosts`.")
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
###### interface
|
|
|
|
# interface
|
|
|
|
|
|
|
|
|
|
|
|
options = {
|
|
|
|
options = {
|
|
|
|
|
|
|
|
|
|
|
|
services.httpd = {
|
|
|
|
services.httpd = {
|
|
|
|
|
|
|
|
|
|
|
|
enable = mkOption {
|
|
|
|
enable = mkEnableOption "the Apache HTTP Server";
|
|
|
|
type = types.bool;
|
|
|
|
|
|
|
|
default = false;
|
|
|
|
|
|
|
|
description = "Whether to enable the Apache HTTP Server.";
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package = mkOption {
|
|
|
|
package = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
type = types.package;
|
|
|
@ -404,7 +397,7 @@ in
|
|
|
|
default = "";
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
description = ''
|
|
|
|
Configuration lines appended to the generated Apache
|
|
|
|
Configuration lines appended to the generated Apache
|
|
|
|
configuration file. Note that this mechanism may not work
|
|
|
|
configuration file. Note that this mechanism will not work
|
|
|
|
when <option>configFile</option> is overridden.
|
|
|
|
when <option>configFile</option> is overridden.
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -458,8 +451,7 @@ in
|
|
|
|
type = types.str;
|
|
|
|
type = types.str;
|
|
|
|
default = "wwwrun";
|
|
|
|
default = "wwwrun";
|
|
|
|
description = ''
|
|
|
|
description = ''
|
|
|
|
User account under which httpd runs. The account is created
|
|
|
|
User account under which httpd runs.
|
|
|
|
automatically if it doesn't exist.
|
|
|
|
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -467,8 +459,7 @@ in
|
|
|
|
type = types.str;
|
|
|
|
type = types.str;
|
|
|
|
default = "wwwrun";
|
|
|
|
default = "wwwrun";
|
|
|
|
description = ''
|
|
|
|
description = ''
|
|
|
|
Group under which httpd runs. The account is created
|
|
|
|
Group under which httpd runs.
|
|
|
|
automatically if it doesn't exist.
|
|
|
|
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -481,10 +472,10 @@ in
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
virtualHosts = mkOption {
|
|
|
|
virtualHosts = mkOption {
|
|
|
|
type = with types; attrsOf (submodule (import ./per-server-options.nix));
|
|
|
|
type = with types; attrsOf (submodule (import ./vhost-options.nix));
|
|
|
|
default = {
|
|
|
|
default = {
|
|
|
|
localhost = {
|
|
|
|
localhost = {
|
|
|
|
documentRoot = "${httpd}/htdocs";
|
|
|
|
documentRoot = "${pkg}/htdocs";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
example = literalExample ''
|
|
|
|
example = literalExample ''
|
|
|
@ -540,12 +531,13 @@ in
|
|
|
|
''
|
|
|
|
''
|
|
|
|
date.timezone = "CET"
|
|
|
|
date.timezone = "CET"
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
description =
|
|
|
|
description = ''
|
|
|
|
"Options appended to the PHP configuration file <filename>php.ini</filename>.";
|
|
|
|
Options appended to the PHP configuration file <filename>php.ini</filename>.
|
|
|
|
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
multiProcessingModule = mkOption {
|
|
|
|
multiProcessingModule = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
type = types.enum [ "event" "prefork" "worker" ];
|
|
|
|
default = "prefork";
|
|
|
|
default = "prefork";
|
|
|
|
example = "worker";
|
|
|
|
example = "worker";
|
|
|
|
description =
|
|
|
|
description =
|
|
|
@ -572,8 +564,9 @@ in
|
|
|
|
type = types.int;
|
|
|
|
type = types.int;
|
|
|
|
default = 0;
|
|
|
|
default = 0;
|
|
|
|
example = 500;
|
|
|
|
example = 500;
|
|
|
|
description =
|
|
|
|
description = ''
|
|
|
|
"Maximum number of httpd requests answered per httpd child (prefork), 0 means unlimited";
|
|
|
|
Maximum number of httpd requests answered per httpd child (prefork), 0 means unlimited.
|
|
|
|
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
sslCiphers = mkOption {
|
|
|
|
sslCiphers = mkOption {
|
|
|
@ -592,10 +585,9 @@ in
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# implementation
|
|
|
|
|
|
|
|
|
|
|
|
###### implementation
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
|
|
|
|
|
|
|
|
config = mkIf config.services.httpd.enable {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertions = [
|
|
|
|
assertions = [
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -626,30 +618,30 @@ in
|
|
|
|
warnings =
|
|
|
|
warnings =
|
|
|
|
mapAttrsToList (name: hostOpts: ''
|
|
|
|
mapAttrsToList (name: hostOpts: ''
|
|
|
|
Using config.services.httpd.virtualHosts."${name}".servedFiles is deprecated and will become unsupported in a future release. Your configuration will continue to work as is but please migrate your configuration to config.services.httpd.virtualHosts."${name}".locations before the 20.09 release of NixOS.
|
|
|
|
Using config.services.httpd.virtualHosts."${name}".servedFiles is deprecated and will become unsupported in a future release. Your configuration will continue to work as is but please migrate your configuration to config.services.httpd.virtualHosts."${name}".locations before the 20.09 release of NixOS.
|
|
|
|
'') (filterAttrs (name: hostOpts: hostOpts.servedFiles != []) mainCfg.virtualHosts);
|
|
|
|
'') (filterAttrs (name: hostOpts: hostOpts.servedFiles != []) cfg.virtualHosts);
|
|
|
|
|
|
|
|
|
|
|
|
users.users = optionalAttrs (mainCfg.user == "wwwrun") {
|
|
|
|
users.users = optionalAttrs (cfg.user == "wwwrun") {
|
|
|
|
wwwrun = {
|
|
|
|
wwwrun = {
|
|
|
|
group = mainCfg.group;
|
|
|
|
group = cfg.group;
|
|
|
|
description = "Apache httpd user";
|
|
|
|
description = "Apache httpd user";
|
|
|
|
uid = config.ids.uids.wwwrun;
|
|
|
|
uid = config.ids.uids.wwwrun;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
users.groups = optionalAttrs (mainCfg.group == "wwwrun") {
|
|
|
|
users.groups = optionalAttrs (cfg.group == "wwwrun") {
|
|
|
|
wwwrun.gid = config.ids.gids.wwwrun;
|
|
|
|
wwwrun.gid = config.ids.gids.wwwrun;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
security.acme.certs = mapAttrs (name: hostOpts: {
|
|
|
|
security.acme.certs = mapAttrs (name: hostOpts: {
|
|
|
|
user = mainCfg.user;
|
|
|
|
user = cfg.user;
|
|
|
|
group = mkDefault mainCfg.group;
|
|
|
|
group = mkDefault cfg.group;
|
|
|
|
email = if hostOpts.adminAddr != null then hostOpts.adminAddr else mainCfg.adminAddr;
|
|
|
|
email = if hostOpts.adminAddr != null then hostOpts.adminAddr else cfg.adminAddr;
|
|
|
|
webroot = hostOpts.acmeRoot;
|
|
|
|
webroot = hostOpts.acmeRoot;
|
|
|
|
extraDomains = genAttrs hostOpts.serverAliases (alias: null);
|
|
|
|
extraDomains = genAttrs hostOpts.serverAliases (alias: null);
|
|
|
|
postRun = "systemctl reload httpd.service";
|
|
|
|
postRun = "systemctl reload httpd.service";
|
|
|
|
}) (filterAttrs (name: hostOpts: hostOpts.enableACME) mainCfg.virtualHosts);
|
|
|
|
}) (filterAttrs (name: hostOpts: hostOpts.enableACME) cfg.virtualHosts);
|
|
|
|
|
|
|
|
|
|
|
|
environment.systemPackages = [httpd];
|
|
|
|
environment.systemPackages = [ pkg ];
|
|
|
|
|
|
|
|
|
|
|
|
# required for "apachectl configtest"
|
|
|
|
# required for "apachectl configtest"
|
|
|
|
environment.etc."httpd/httpd.conf".source = httpdConf;
|
|
|
|
environment.etc."httpd/httpd.conf".source = httpdConf;
|
|
|
@ -689,6 +681,15 @@ in
|
|
|
|
"access_compat"
|
|
|
|
"access_compat"
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
systemd.tmpfiles.rules =
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
svc = config.systemd.services.httpd.serviceConfig;
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
[
|
|
|
|
|
|
|
|
"d '${cfg.logDir}' 0700 ${svc.User} ${svc.Group}"
|
|
|
|
|
|
|
|
"Z '${cfg.logDir}' - ${svc.User} ${svc.Group}"
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
systemd.services.httpd =
|
|
|
|
systemd.services.httpd =
|
|
|
|
let
|
|
|
|
let
|
|
|
|
vhostsACME = filter (hostOpts: hostOpts.enableACME) vhosts;
|
|
|
|
vhostsACME = filter (hostOpts: hostOpts.enableACME) vhosts;
|
|
|
@ -700,35 +701,36 @@ in
|
|
|
|
after = [ "network.target" "fs.target" ] ++ map (hostOpts: "acme-selfsigned-${hostOpts.hostName}.service") vhostsACME;
|
|
|
|
after = [ "network.target" "fs.target" ] ++ map (hostOpts: "acme-selfsigned-${hostOpts.hostName}.service") vhostsACME;
|
|
|
|
|
|
|
|
|
|
|
|
path =
|
|
|
|
path =
|
|
|
|
[ httpd pkgs.coreutils pkgs.gnugrep ]
|
|
|
|
[ pkg pkgs.coreutils pkgs.gnugrep ]
|
|
|
|
++ optional mainCfg.enablePHP pkgs.system-sendmail; # Needed for PHP's mail() function.
|
|
|
|
++ optional cfg.enablePHP pkgs.system-sendmail; # Needed for PHP's mail() function.
|
|
|
|
|
|
|
|
|
|
|
|
environment =
|
|
|
|
environment =
|
|
|
|
optionalAttrs mainCfg.enablePHP { PHPRC = phpIni; }
|
|
|
|
optionalAttrs cfg.enablePHP { PHPRC = phpIni; }
|
|
|
|
// optionalAttrs mainCfg.enableMellon { LD_LIBRARY_PATH = "${pkgs.xmlsec}/lib"; };
|
|
|
|
// optionalAttrs cfg.enableMellon { LD_LIBRARY_PATH = "${pkgs.xmlsec}/lib"; };
|
|
|
|
|
|
|
|
|
|
|
|
preStart =
|
|
|
|
preStart =
|
|
|
|
''
|
|
|
|
''
|
|
|
|
mkdir -m 0700 -p ${mainCfg.logDir}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Get rid of old semaphores. These tend to accumulate across
|
|
|
|
# Get rid of old semaphores. These tend to accumulate across
|
|
|
|
# server restarts, eventually preventing it from restarting
|
|
|
|
# server restarts, eventually preventing it from restarting
|
|
|
|
# successfully.
|
|
|
|
# successfully.
|
|
|
|
for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' ${mainCfg.user} ' | cut -f2 -d ' '); do
|
|
|
|
for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' ${cfg.user} ' | cut -f2 -d ' '); do
|
|
|
|
${pkgs.utillinux}/bin/ipcrm -s $i
|
|
|
|
${pkgs.utillinux}/bin/ipcrm -s $i
|
|
|
|
done
|
|
|
|
done
|
|
|
|
'';
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
|
serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}";
|
|
|
|
serviceConfig = {
|
|
|
|
serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop";
|
|
|
|
ExecStart = "@${pkg}/bin/httpd httpd -f ${httpdConf}";
|
|
|
|
serviceConfig.ExecReload = "${httpd}/bin/httpd -f ${httpdConf} -k graceful";
|
|
|
|
ExecStop = "${pkg}/bin/httpd -f ${httpdConf} -k graceful-stop";
|
|
|
|
serviceConfig.Group = mainCfg.group;
|
|
|
|
ExecReload = "${pkg}/bin/httpd -f ${httpdConf} -k graceful";
|
|
|
|
serviceConfig.Type = "forking";
|
|
|
|
User = "root";
|
|
|
|
serviceConfig.PIDFile = "${runtimeDir}/httpd.pid";
|
|
|
|
Group = cfg.group;
|
|
|
|
serviceConfig.Restart = "always";
|
|
|
|
Type = "forking";
|
|
|
|
serviceConfig.RestartSec = "5s";
|
|
|
|
PIDFile = "${runtimeDir}/httpd.pid";
|
|
|
|
serviceConfig.RuntimeDirectory = "httpd httpd/runtime";
|
|
|
|
Restart = "always";
|
|
|
|
serviceConfig.RuntimeDirectoryMode = "0750";
|
|
|
|
RestartSec = "5s";
|
|
|
|
|
|
|
|
RuntimeDirectory = "httpd httpd/runtime";
|
|
|
|
|
|
|
|
RuntimeDirectoryMode = "0750";
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|