{ pkgs, lib, config, ... }: let cfg = config.crans.reverseProxy; allowAll = pkgs.writeText "allow_all.json" '' { "bots": [ { "name": "allow_all", "path_regex": ".*", "action": "ALLOW" } ] } ''; inherit (lib) cartesianProduct literalExpression mapAttrs mapAttrs' mkEnableOption mkIf mkOption nameValuePair substring types ; in { options.crans.reverseProxy = { enable = mkEnableOption "Configuration du reverseproxy."; virtualHosts = mkOption { type = types.attrsOf ( types.submodule { options = { serverAliases = mkOption { type = types.listOf types.str; default = [ ]; example = [ "everything" "voyager" ]; description = '' Déclaration des alias. ''; }; target = mkOption { type = types.str; default = ""; description = '' Indique la destination. Il peut s'agir du chemin vers des fichiers statiques. ''; example = "172.16.10.128:8000"; }; anubisConfig = mkOption { type = types.str; default = ""; description = '' Chemin du fichier de configuration ''; example = "/var/www/anubis.conf"; }; httpOnly = mkOption { type = types.bool; default = false; description = '' Interdit les connexions en ssh ''; example = "true"; }; }; } ); default = {}; example = literalExpression '' { "framadate" = { host = "176.16.10.128:8000"; serverAliases = [ "everything" "voyager" ] }; }; ''; description = "Déclaration des machines."; }; }; config = { systemd.services = mapAttrs ( vhostName: vhostConfig: { wantedBy = [ "multi-user.target" ]; } ) cfg.virtualHosts; services = mkIf cfg.enable { anubis = { defaultOptions.group = "nginx"; instances = mapAttrs ( vhostName: vhostConfig: { enable = true; settings = { BIND = "/run/anubis/anubis-${vhostName}.sock"; BIND_NETWORK = "unix"; TARGET = "unix:///run/nginx/nginx-${vhostName}.sock"; COOKIE_DOMAIN = "crans.org"; REDIRECT_DOMAINS = "${vhostName}.crans.org"; SOCKET_MODE = "0660"; POLICY_FNAME = if (vhostConfig.anubisConfig == "") then allowAll else vhostConfig.anubisConfig; }; } ) cfg.virtualHosts; }; nginx = let domaines = [ "crans.org" "crans.fr" "crans.eu" ]; redirectConfig = mapAttrs ( vhostName: vhostConfig: { locations = mkIf ((substring 0 1 vhostConfig.target) != "/") { "/favicon.ico".root = "/var/www/logo/"; "/".proxyPass = "http://${vhostConfig.target}"; }; root = mkIf ((substring 0 1 vhostConfig.target) == "/") vhostConfig.target; listen = [ { addr = "unix:/run/nginx/nginx-${vhostName}.sock"; } ]; } ) cfg.virtualHosts; aliasConfig = mapAttrs' ( vhostName: vhostConfig: nameValuePair (vhostName + "-alias") { enableACME = !vhostConfig.httpOnly; forceSSL = !vhostConfig.httpOnly; rejectSSL = vhostConfig.httpOnly; serverName = "${vhostName}.crans.fr"; serverAliases = let aliases = cartesianProduct { name = vhostConfig.serverAliases; domaine = domaines; }; in [ "${vhostName}.crans.eu" ] ++ map (value: value.name + "." + value.domaine) aliases; globalRedirect = "${vhostName}.crans.org"; } ) cfg.virtualHosts; anubisConfig = mapAttrs' ( vhostName: vhostConfig: nameValuePair (vhostName + "-anubis") { enableACME = !vhostConfig.httpOnly; forceSSL = !vhostConfig.httpOnly; rejectSSL = vhostConfig.httpOnly; locations."/".proxyPass = "http://unix:/run/anubis/anubis-${vhostName}.sock"; serverName = "${vhostName}.crans.org"; } ) cfg.virtualHosts; in { enable = true; virtualHosts = redirectConfig // aliasConfig // anubisConfig; }; }; }; }