diff --git a/hosts/vm/reverseproxy/reverseproxy.nix b/hosts/vm/reverseproxy/reverseproxy.nix index 7d82111..e154c2c 100644 --- a/hosts/vm/reverseproxy/reverseproxy.nix +++ b/hosts/vm/reverseproxy/reverseproxy.nix @@ -135,21 +135,21 @@ in enable = true; virtualHosts = { "collabora" = { - target = "172.16.10.149"; + proxyPass = "172.16.10.149"; proxyWebsockets = true; }; "eclat" = { anubisConfig = "${anubisMirrors}"; httpOnly = true; - target = "172.16.10.104"; + proxyPass = "172.16.10.104"; }; "eclats" = { anubisConfig = "${anubisMirrors}"; - target = "172.16.10.104"; + proxyPass = "172.16.10.104"; }; "install-party" = { anubisConfig = "${anubisChallenge}"; - target = "/var/www/install-party.crans.org"; + serveLocalFiles = "/var/www/install-party.crans.org"; serverAliases = [ "i-p" "adopteunmanchot" @@ -158,42 +158,42 @@ in }; "lists" = { anubisConfig = "${anubisChallenge}"; - target = "172.16.10.110"; + proxyPass = "172.16.10.110"; }; "mediawiki" = { anubisConfig = "${anubisChallenge}"; - target = "172.16.10.144"; + proxyPass = "172.16.10.144"; serverAliases = [ "mediakiwi" ]; }; "mirrors" = { anubisConfig = "${anubisMirrors}"; - target = "172.16.10.104"; + proxyPass = "172.16.10.104"; }; "mirror" = { anubisConfig = "${anubisMirrors}"; httpOnly = true; - target = "172.16.10.104"; + proxyPass = "172.16.10.104"; }; "nekorale" = { anubisConfig = "${anubisAllowOther}"; - target = "172.16.10.31/club-nekorale"; + globalRedirect = "172.16.10.31/club-nekorale"; }; "perso" = { anubisConfig = "${anubisPerso}"; - target = "172.16.10.31"; + proxyPass = "172.16.10.31"; serverAliases = [ "clubs" ]; }; "snl" = { anubisConfig = "${anubisAllowOther}"; - target = "172.16.10.31/sonetlumens"; + globalRedirect = "172.16.10.31/sonetlumens"; }; "wiki" = { anubisConfig = "${anubisChallenge}"; - target = "172.16.10.161"; + proxyPass = "172.16.10.161"; serverAliases = [ "wikipedia" ]; diff --git a/modules/services/reverseproxy.nix b/modules/services/reverseproxy.nix index 5098771..ed386a7 100644 --- a/modules/services/reverseproxy.nix +++ b/modules/services/reverseproxy.nix @@ -65,18 +65,36 @@ in ''; }; - target = mkOption { + proxyPass = mkOption { type = types.str; default = ""; description = '' - Indique la destination. Il peut s'agir du chemin vers des fichiers statiques. + Indique la destination à proxy. ''; example = "172.16.10.128:8000"; }; + serveLocalFiles = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Chemin vers un dossier à exposer statiquement. + ''; + example = "/var/local/adopter-un-manchot"; + }; + + globalRedirect = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Si définie, toutes les requêtes sont redirigées (via 301) sur cet hôte. + ''; + example = "perso.crans.org/club"; + }; + anubisConfig = mkOption { - type = types.str; - default = ""; + type = types.nullOr types.str; + default = null; description = '' Chemin du fichier de configuration ''; @@ -95,7 +113,7 @@ in type = types.bool; default = false; description = '' - Interdit les connexions en ssh + Interdit les connexions en https ''; example = "true"; }; @@ -137,104 +155,117 @@ in services = mkIf cfg.enable { anubis = { defaultOptions.group = "nginx"; - instances = lib.mapAttrs (vhostName: vhostConfig: { - enable = true; - settings = { - BIND = "/run/anubis/anubis-${vhostName}/socket.sock"; - BIND_NETWORK = "unix"; - METRICS_BIND = "/run/anubis/anubis-${vhostName}/anubis-${vhostName}-metrics.sock"; - TARGET = "unix:///run/nginx/nginx-${vhostName}.sock"; - COOKIE_DOMAIN = "crans.org"; - REDIRECT_DOMAINS = "${vhostName}.crans.org"; - SOCKET_MODE = "0660"; - # OpenGraph config - OG_PASSTHROUGH = vhostConfig.anubisOpenGraph; - OG_EXPIRY_TIME = "24h"; - OG_CACHE_CONSIDER_HOST = true; - # Policy config - POLICY_FNAME = if (vhostConfig.anubisConfig == "") then "${allowAll}" else vhostConfig.anubisConfig; - }; - }) cfg.virtualHosts; + instances = lib.mapAttrs ( + vhostName: vhostConfig: + mkIf (vhostConfig.anubisConfig != null) { + enable = true; + settings = { + BIND = "/run/anubis/anubis-${vhostName}/socket.sock"; + BIND_NETWORK = "unix"; + METRICS_BIND = "/run/anubis/anubis-${vhostName}/anubis-${vhostName}-metrics.sock"; + TARGET = "unix:///run/nginx/nginx-${vhostName}.sock"; + COOKIE_DOMAIN = "crans.org"; + REDIRECT_DOMAINS = "${vhostName}.crans.org"; + SOCKET_MODE = "0660"; + # OpenGraph config + OG_PASSTHROUGH = vhostConfig.anubisOpenGraph; + OG_EXPIRY_TIME = "24h"; + OG_CACHE_CONSIDER_HOST = true; + # Policy config + POLICY_FNAME = vhostConfig.anubisConfig; + }; + } + ) cfg.virtualHosts; }; nginx = let - # Configuration du serveur principal. - mainConfig = lib.mapAttrs' ( + configVhost = vhostName: vhostConfig: - lib.nameValuePair (vhostName + "-anubis") { - enableACME = !vhostConfig.httpOnly; - forceSSL = !vhostConfig.httpOnly; - rejectSSL = vhostConfig.httpOnly; - locations."/" = { - proxyPass = "http://unix:/run/anubis/anubis-${vhostName}/socket.sock"; - proxyWebsockets = vhostConfig.proxyWebsockets; + let + sslConf = { + enableACME = !vhostConfig.httpOnly; + forceSSL = !vhostConfig.httpOnly; + rejectSSL = vhostConfig.httpOnly; }; - serverName = "${vhostName}.crans.${mainTld}"; - extraConfig = " - set_real_ip_from 172.16.0.0/16; - set_real_ip_from fd00::/56; - real_ip_header X-Real-Ip; - "; - } - ) cfg.virtualHosts; - # Redirections - redirectConfig = lib.mapAttrs (vhostName: vhostConfig: { - # Redirection vers d'autres machines - locations = mkIf (!lib.strings.hasPrefix "/" vhostConfig.target) { - "/favicon.ico".root = "/var/www/logo/"; - "/" = { - proxyPass = "http://${vhostConfig.target}"; - proxyWebsockets = vhostConfig.proxyWebsockets; - }; - }; - # Redirection vers des fichiers locaux - root = mkIf (lib.strings.hasPrefix "/" vhostConfig.target) vhostConfig.target; - listen = [ - { addr = "unix:/run/nginx/nginx-${vhostName}.sock"; } - ]; - serverName = "${vhostName}.crans.${mainTld}"; - extraConfig = " - set_real_ip_from unix:; - real_ip_header X-Real-IP; - "; - }) cfg.virtualHosts; - - # Génération des alias - getAliases = name: config: lib.foldr ( - tld: acc: - acc - ++ - (lib.foldr (alias: acc: acc ++ ["${alias}.crans.${tld}"]) ["${name}.crans.${tld}"] config.serverAliases) - ) - (lib.foldr (alias: acc: acc ++ ["${alias}.crans.${mainTld}"]) [] config.serverAliases) - otherTld; - - # Configuration des alias - aliasConfig = lib.foldr ( - vhost: acc: - acc - // - lib.foldr ( - alias: acc: - acc - // - { - "${vhost.name}-alias-${alias}" = rec { - rejectSSL = vhost.value.httpOnly; - forceSSL = !rejectSSL; - enableACME = !rejectSSL; - serverName = alias; - globalRedirect = "${vhost.name}.crans.${mainTld}"; - }; + # Conf pour l’host en entrès + entryExtraConf = { + extraConfig = '' + set_real_ip_from 172.16.0.0/16; + set_real_ip_from fd00::/56; + real_ip_header X-Real-Ip; + ''; } - ) { } (getAliases vhost.name vhost.value) - ) { } (lib.attrsToList cfg.virtualHosts); + // sslConf; + # Conf supplémentaire pour le proxy principal + vhostExtraConf = + if vhostConfig.anubisConfig != null then + # Il reçoit les requêtes d’Anubis + { + listen = [ + { addr = "unix:/run/nginx/nginx-${vhostName}.sock"; } + ]; + extraConfig = '' + set_real_ip_from unix:; + real_ip_header X-Real-IP; + ''; + } + else + # Il est en entrée + entryExtraConf; + + # Les alias : vhostName × otherTld U serverAliases × allTld + aliases = + lib.foldr + ( + tld: acc: + acc + ++ (lib.foldr (alias: acc: acc ++ [ "${alias}.crans.${tld}" ]) [ + "${vhostName}.crans.${tld}" + ] vhostConfig.serverAliases) + ) + (lib.foldr (alias: acc: acc ++ [ "${alias}.crans.${mainTld}" ]) [ ] vhostConfig.serverAliases) + otherTld; + in + { + # Configuration du service à proxy. + "${vhostName}" = vhostExtraConf // { + serverName = "${vhostName}.crans.${mainTld}"; + locations."/" = mkIf (vhostConfig.proxyPass != "") { + proxyPass = "http://${vhostConfig.proxyPass}"; + proxyWebsockets = vhostConfig.proxyWebsockets; + }; + root = vhostConfig.serveLocalFiles; + globalRedirect = vhostConfig.globalRedirect; + }; + + # Entrée d’Anubis + "${vhostName}-anubis" = mkIf (vhostConfig.anubisConfig != null) entryExtraConf // { + locations."/" = { + proxyPass = "http://unix:/run/anubis/anubis-${vhostName}/socket.sock"; + proxyWebsockets = vhostConfig.proxyWebsockets; + extraConfig = entryExtraConf.extraConfig + '' + access_log /var/log/nginx/anubis.access.log; + error_log /var/log/nginx/anubis.error.log; + ''; + }; + serverName = "${vhostName}.crans.${mainTld}"; + }; + } + # Les alias + // lib.mergeAttrsList ( + lib.map (alias: { + "${vhostName}-alias-${alias}" = sslConf // { + serverName = alias; + globalRedirect = vhostConfig.globalRedirect or "${vhostName}.crans.${mainTld}"; + }; + }) aliases + ); in { enable = true; - virtualHosts = redirectConfig // aliasConfig // mainConfig; + virtualHosts = lib.concatMapAttrs configVhost cfg.virtualHosts; }; }; };