certName = mkOption { type = str; };
hosts = mkOption { type = listOf str; };
root = mkOption { type = nullOr path; };
+ forceSSL = mkOption {
+ type = bool;
+ default = true;
+ description = ''
+ Automatically create a corresponding non-ssl vhost
+ that will only redirect to the ssl version
+ '';
+ };
extraConfig = mkOption { type = listOf lines; default = []; };
};
};
};
hosts = mkOption { type = listOf str; };
root = mkOption { type = nullOr path; };
+ forceSSL = mkOption {
+ type = bool;
+ default = true;
+ description = ''
+ Automatically create a corresponding non-ssl vhost
+ that will only redirect to the ssl version
+ '';
+ };
extraConfig = mkOption { type = listOf lines; default = []; };
};
});
};
config.services.httpd = let
- redirectVhost = ips: { # Should go last, catchall http -> https redirect
- listen = map (ip: { inherit ip; port = 80; }) ips;
- hostName = "redirectSSL";
- serverAliases = [ "*" ];
- enableSSL = false;
- logFormat = "combinedVhost";
- documentRoot = "/var/lib/acme/acme-challenge";
- extraConfig = ''
- RewriteEngine on
- RewriteCond "%{REQUEST_URI}" "!^/\.well-known"
- RewriteRule ^(.+) https://%{HTTP_HOST}$1 [R=301]
- # To redirect in specific "VirtualHost *:80", do
- # RedirectMatch 301 ^/((?!\.well-known.*$).*)$ https://host/$1
- # rather than rewrite
- '';
- };
nosslVhost = ips: cfg: {
listen = map (ip: { inherit ip; port = 80; }) ips;
hostName = cfg.host;
- enableSSL = false;
logFormat = "combinedVhost";
documentRoot = cfg.root;
extraConfig = ''
'';
};
toVhost = ips: vhostConf: {
- enableSSL = true;
- sslServerCert = "${config.security.acme.certs."${vhostConf.certName}".directory}/cert.pem";
- sslServerKey = "${config.security.acme.certs."${vhostConf.certName}".directory}/key.pem";
- sslServerChain = "${config.security.acme.certs."${vhostConf.certName}".directory}/chain.pem";
+ forceSSL = vhostConf.forceSSL or true;
+ useACMEHost = vhostConf.certName;
logFormat = "combinedVhost";
- listen = map (ip: { inherit ip; port = 443; }) ips;
+ listen = if vhostConf.forceSSL
+ then lists.flatten (map (ip: [{ inherit ip; port = 443; ssl = true; } { inherit ip; port = 80; }]) ips)
+ else map (ip: { inherit ip; port = 443; ssl = true; }) ips;
hostName = builtins.head vhostConf.hosts;
serverAliases = builtins.tail vhostConf.hosts or [];
documentRoot = vhostConf.root;
extraConfig = builtins.concatStringsSep "\n" vhostConf.extraConfig;
};
toVhostNoSSL = ips: vhostConf: {
- enableSSL = false;
logFormat = "combinedVhost";
listen = map (ip: { inherit ip; port = 80; }) ips;
hostName = builtins.head vhostConf.hosts;
in attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
icfg.httpdName (mkIf icfg.enable {
enable = true;
- listen = map (ip: { inherit ip; port = 443; }) icfg.ips;
- stateDir = "/run/httpd_${name}";
logPerVirtualHost = true;
multiProcessingModule = "worker";
# https://ssl-config.mozilla.org/#server=apache&version=2.4.41&config=intermediate&openssl=1.0.2t&guideline=5.4
logFormat = "combinedVhost";
extraModules = lists.unique icfg.modules;
extraConfig = builtins.concatStringsSep "\n" icfg.extraConfig;
- virtualHosts = [ (toVhost icfg.ips icfg.fallbackVhost) ]
- ++ optionals (icfg.nosslVhost.enable) [ (nosslVhost icfg.ips icfg.nosslVhost) ]
- ++ (attrsets.mapAttrsToList (n: v: toVhostNoSSL icfg.ips v) icfg.vhostNoSSLConfs)
- ++ (attrsets.mapAttrsToList (n: v: toVhost icfg.ips v) icfg.vhostConfs)
- ++ [ (redirectVhost icfg.ips) ];
+
+ virtualHosts = with attrsets; {
+ ___fallbackVhost = toVhost icfg.ips icfg.fallbackVhost;
+ } // (optionalAttrs icfg.nosslVhost.enable {
+ nosslVhost = nosslVhost icfg.ips icfg.nosslVhost;
+ }) // (mapAttrs' (n: v: nameValuePair ("nossl_" + n) (toVhostNoSSL icfg.ips v)) icfg.vhostNoSSLConfs)
+ // (mapAttrs' (n: v: nameValuePair ("ssl_" + n) (toVhost icfg.ips v)) icfg.vhostConfs);
})
) cfg.env;