{ pkgs, lib, config, ... }: let cfg = config.crans.reverseProxy; formatJSON = pkgs.formats.json { }; allowAll = formatJSON.generate "allow_all.json" { bots = [ { name = "allow_all"; path_regex = ".*"; action = "ALLOW"; } ]; }; mainTld = "org"; otherTld = [ "fr" "eu" ]; inherit (lib) literalExpression mkEnableOption mkIf mkOption 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"; }; proxyWebsockets = mkOption { type = types.bool; default = false; description = '' Activer les websockets ''; example = "true"; }; }; } ); default = { }; example = literalExpression '' { "framadate" = { host = "176.16.10.128:8000"; serverAliases = [ "everything" "voyager" ] }; }; ''; description = "Déclaration des machines."; }; }; config = { systemd.services = lib.mapAttrs (vhostName: vhostConfig: { wantedBy = [ "multi-user.target" ]; }) cfg.virtualHosts; services = mkIf cfg.enable { anubis = { defaultOptions.group = "nginx"; instances = lib.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 # Configuration du serveur principal. mainConfig = lib.mapAttrs' ( vhostName: vhostConfig: lib.nameValuePair (vhostName + "-anubis") { enableACME = !vhostConfig.httpOnly; forceSSL = !vhostConfig.httpOnly; rejectSSL = vhostConfig.httpOnly; locations."/" = { proxyPass = "http://unix:/run/anubis/anubis-${vhostName}.sock"; proxyWebsockets = vhostConfig.proxyWebsockets; }; serverName = "${vhostName}.crans.${mainTld}"; } ) 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"; } ]; }) cfg.virtualHosts; # Configuration des alias .fr et .eu aliasConfig = lib.fold ( tld: acc: acc // lib.mapAttrs' ( vhostName: vhostConfig: lib.nameValuePair "${vhostName}-alias-${tld}" rec { rejectSSL = vhostConfig.httpOnly; forceSSL = !rejectSSL; enableACME = !rejectSSL; serverName = "${vhostName}.crans.${tld}"; serverAliases = map (name: "${name}.crans.${tld}") vhostConfig.serverAliases; globalRedirect = "${vhostName}.crans.${mainTld}"; } ) cfg.virtualHosts ) { } otherTld; in { enable = true; virtualHosts = redirectConfig // aliasConfig // mainConfig; }; }; }; }