nixos/modules/services/reverseproxy.nix

194 lines
5.2 KiB
Nix

{
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;
};
};
};
}