nixos/modules/services/reverseproxy.nix

155 lines
4.0 KiB
Nix

{ 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";
};
};
}
);
default = {};
example = literalExpression ''
{
"framadate" = {
host = "176.16.10.128:8000";
serverAliases = [
"everything"
"voyager"
]
};
};
'';
description = "Déclaration des machines.";
};
};
config.services = mkIf cfg.enable {
anubis.instances = mapAttrs (
vhostName: vhostConfig: {
enable = true;
settings = {
BIND_NETWORK = "unix";
TARGET = "unix:/run/nginx/nginx-${vhostName}.sock";
COOKIE_DOMAIN = "crans.org";
REDIRECT_DOMAINS = "${vhostName}.crans.org";
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) != "/") {
"/".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 = true;
forceSSL = true;
serverName = "${vhostName}.crans.fr";
serverAliases = let
aliases = cartesianProduct {
name = vhostConfig.serverAliases;
domaine = domaines;
};
in [
"${vhostName}.crans.eu"
] ++ map (value: value.name + "." + value.domaine) aliases;
extraConfig = ''
return 301 https://${vhostName}.crans.org$request_uri;
'';
}
) cfg.virtualHosts;
anubisConfig = mapAttrs' (
vhostName: vhostConfig: nameValuePair (vhostName + "-anubis") {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "unix:/run/anubis/anubis-${vhostName}.sock";
serverName = "${vhostName}.crans.org";
}
) cfg.virtualHosts;
in {
enable = true;
virtualHosts = redirectConfig // aliasConfig // anubisConfig;
};
};
}