X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=modules%2Fwebsites%2Fdefault.nix;h=d5a0f635b0354db0ae775c7a5b877dded3db133d;hb=e7b890d0999fe54a99f84fe92d625d9d488358dc;hp=ef79cb3cbf77b52f604746607e878f03890b604c;hpb=29f8cb850d74b456d6481a456311bbf5361d328c;p=perso%2FImmae%2FConfig%2FNix.git diff --git a/modules/websites/default.nix b/modules/websites/default.nix index ef79cb3..d5a0f63 100644 --- a/modules/websites/default.nix +++ b/modules/websites/default.nix @@ -23,14 +23,6 @@ in Name of the webapp dir to create in /run/current-system ''; }; - webappDirsPath = mkOption { - type = str; - readOnly = true; - description = '' - Full path of the webapp dir - ''; - default = "/run/current-system/${cfg.webappDirsName}"; - }; env = mkOption { default = {}; description = "Each type of website to enable will target a distinct httpd server"; @@ -46,7 +38,7 @@ in description = "Name of the httpd instance to assign this type to"; }; ips = mkOption { - type = listOf string; + type = listOf str; default = []; description = "ips to listen to"; }; @@ -67,7 +59,7 @@ in options = { enable = mkEnableOption "Add default no-ssl vhost for this instance"; host = mkOption { - type = string; + type = str; description = "The hostname to use for this vhost"; }; root = mkOption { @@ -76,7 +68,7 @@ in description = "The root folder to serve"; }; indexFile = mkOption { - type = string; + type = str; default = "index.html"; description = "The index file to show."; }; @@ -87,37 +79,64 @@ in description = "The fallback vhost that will be defined as first vhost in Apache"; type = submodule { options = { - certName = mkOption { type = string; }; - hosts = mkOption { type = listOf string; }; + 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 = []; }; }; }; }; + vhostNoSSLConfs = mkOption { + default = {}; + description = "List of no ssl vhosts to define for Apache"; + type = attrsOf (submodule { + options = { + hosts = mkOption { type = listOf str; }; + root = mkOption { type = nullOr path; }; + extraConfig = mkOption { type = listOf lines; default = []; }; + }; + }); + }; vhostConfs = mkOption { default = {}; description = "List of vhosts to define for Apache"; type = attrsOf (submodule { options = { - certName = mkOption { type = string; }; + certName = mkOption { type = str; }; addToCerts = mkOption { type = bool; default = false; description = "Use these to certificates. Is ignored (considered true) if certMainHost is not null"; }; certMainHost = mkOption { - type = nullOr string; + type = nullOr str; description = "Use that host as 'main host' for acme certs"; default = null; }; - hosts = mkOption { type = listOf string; }; + 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 = []; }; }; }); }; watchPaths = mkOption { - type = listOf string; + type = listOf str; default = []; description = '' Paths to watch that should trigger a reload of httpd @@ -126,29 +145,23 @@ in }; }); }; + # Readonly variables + webappDirsPaths = mkOption { + type = attrsOf path; + readOnly = true; + description = '' + Full paths of the webapp dir + ''; + default = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair + name "/run/current-system/${cfg.webappDirsName}/${name}" + ) cfg.webappDirs; + }; }; 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 = "${config.security.acme.directory}/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 = '' @@ -163,12 +176,20 @@ in ''; }; toVhost = ips: vhostConf: { - enableSSL = true; - sslServerCert = "${config.security.acme.directory}/${vhostConf.certName}/cert.pem"; - sslServerKey = "${config.security.acme.directory}/${vhostConf.certName}/key.pem"; - sslServerChain = "${config.security.acme.directory}/${vhostConf.certName}/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: { + logFormat = "combinedVhost"; + listen = map (ip: { inherit ip; port = 80; }) ips; hostName = builtins.head vhostConf.hosts; serverAliases = builtins.tail vhostConf.hosts or []; documentRoot = vhostConf.root; @@ -177,18 +198,27 @@ in 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 + sslProtocols = "all -SSLv3 -TLSv1 -TLSv1.1"; + sslCiphers = builtins.concatStringsSep ":" [ + "ECDHE-ECDSA-AES128-GCM-SHA256" "ECDHE-RSA-AES128-GCM-SHA256" + "ECDHE-ECDSA-AES256-GCM-SHA384" "ECDHE-RSA-AES256-GCM-SHA384" + "ECDHE-ECDSA-CHACHA20-POLY1305" "ECDHE-RSA-CHACHA20-POLY1305" + "DHE-RSA-AES128-GCM-SHA256" "DHE-RSA-AES256-GCM-SHA384" + ]; inherit (icfg) adminAddr; 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: 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;