238 lines
5.5 KiB
Nix
238 lines
5.5 KiB
Nix
{
|
|
pkgs,
|
|
lib,
|
|
config,
|
|
nodes ? { },
|
|
...
|
|
}:
|
|
let
|
|
inherit (lib)
|
|
mkOption
|
|
mkEnableOption
|
|
mkIf
|
|
mapAttrs
|
|
concatStringsSep
|
|
fold
|
|
;
|
|
inherit (lib.types)
|
|
port
|
|
listOf
|
|
submodule
|
|
coercedTo
|
|
str
|
|
raw
|
|
;
|
|
redirected-ports-mod.options = {
|
|
external = mkOption {
|
|
type = port;
|
|
};
|
|
internal = mkOption {
|
|
type = port;
|
|
};
|
|
};
|
|
|
|
redirection-port-type = coercedTo port (port: {
|
|
external = port;
|
|
internal = port;
|
|
}) (submodule redirected-ports-mod);
|
|
|
|
inherit (config.kat) fqdn;
|
|
hostname = config.networking.hostName;
|
|
cfg = config.kat.proxies;
|
|
|
|
error-webroot = pkgs.runCommand "${hostname}-error-webroot" { } ''
|
|
mkdir $out
|
|
cp ${./418.html} $out/418.html
|
|
cp ${./599.html} $out/599.html
|
|
substituteInPlace $out/* \
|
|
--replace-fail 'config.hostname' "${hostname}"
|
|
'';
|
|
|
|
redirections =
|
|
fold
|
|
(a: b: {
|
|
domains = a.domains ++ b.domains;
|
|
tcp = a.tcp ++ b.tcp;
|
|
udp = a.udp ++ b.udp;
|
|
vhosts = a.vhosts // b.vhosts;
|
|
})
|
|
{
|
|
domains = [ ];
|
|
tcp = [ ];
|
|
udp = [ ];
|
|
vhosts = { };
|
|
}
|
|
(
|
|
map (
|
|
host:
|
|
let
|
|
inherit (nodes.${host}.config.kat) fqdn;
|
|
host-cfg = nodes.${host}.config.kat.proxies;
|
|
in
|
|
{
|
|
domains = [ fqdn ] ++ host-cfg.aliases;
|
|
tcp = map (
|
|
{ external, internal }:
|
|
{
|
|
input = external;
|
|
inherit (host-cfg) ip;
|
|
out = internal;
|
|
}
|
|
) host-cfg.open-tcp;
|
|
udp = map (
|
|
{ external, internal }:
|
|
{
|
|
input = external;
|
|
inherit (host-cfg) ip;
|
|
out = internal;
|
|
}
|
|
) host-cfg.open-udp;
|
|
vhosts.${fqdn} = {
|
|
inherit (host-cfg) ip aliases;
|
|
};
|
|
}
|
|
) cfg.redirects
|
|
);
|
|
in
|
|
{
|
|
options.kat.proxies = {
|
|
enable = mkEnableOption "kat-proxies autoconfiguration" // {
|
|
default = cfg.redirects != [ ];
|
|
defaultText = ''config.kat.proxies.redirects != [ ]'';
|
|
};
|
|
|
|
ip = mkOption {
|
|
type = str;
|
|
};
|
|
|
|
aliases = mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
};
|
|
open-tcp = mkOption {
|
|
type = listOf redirection-port-type;
|
|
default = [ ];
|
|
};
|
|
open-udp = mkOption {
|
|
type = listOf redirection-port-type;
|
|
default = [ ];
|
|
};
|
|
|
|
redirects = mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
};
|
|
|
|
test = mkOption {
|
|
type = raw;
|
|
};
|
|
};
|
|
config = mkIf cfg.enable {
|
|
kat.proxies = {
|
|
test = redirections;
|
|
aliases = redirections.domains;
|
|
open-tcp = map ({ input, ... }: input) redirections.tcp;
|
|
open-udp = map ({ input, ... }: input) redirections.udp;
|
|
};
|
|
|
|
networking.firewall = {
|
|
allowedTCPPorts = [
|
|
80
|
|
443
|
|
] ++ map ({ internal, ... }: internal) cfg.open-tcp;
|
|
allowedUDPPorts = map ({ internal, ... }: internal) cfg.open-udp;
|
|
};
|
|
|
|
security.acme.certs.${fqdn}.extraDomainNames = cfg.aliases;
|
|
|
|
services.nginx = {
|
|
enable = true;
|
|
virtualHosts =
|
|
mapAttrs (
|
|
_:
|
|
{ aliases, ip }:
|
|
{
|
|
useACMEHost = fqdn;
|
|
forceSSL = true;
|
|
acmeFallbackHost = ip;
|
|
acmeFallbackRecommendedProxySettings = true;
|
|
serverAliases = aliases;
|
|
locations = {
|
|
"/.${hostname}/" = {
|
|
extraConfig = ''
|
|
internal;
|
|
error_page 404 =418 /.${hostname}/418.html;
|
|
'';
|
|
alias = "${error-webroot}/";
|
|
};
|
|
"/" = {
|
|
recommendedProxySettings = true;
|
|
proxyPass = "https://${ip}/";
|
|
extraConfig = ''
|
|
proxy_set_header Connection ''';
|
|
proxy_http_version 1.1;
|
|
chunked_transfer_encoding off;
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
error_page 502 =599 "/.${hostname}/599.html";
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
) redirections.vhosts
|
|
// {
|
|
${fqdn} = {
|
|
default = true;
|
|
enableACME = true;
|
|
addSSL = true;
|
|
locations = {
|
|
"/.${hostname}/" = {
|
|
extraConfig = ''
|
|
internal;
|
|
error_page 404 =418 /.${hostname}/418.html;
|
|
'';
|
|
alias = "${error-webroot}/";
|
|
};
|
|
"/" = {
|
|
extraConfig = ''
|
|
return 418;
|
|
error_page 418 =418 /.${hostname}/418.html;
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
streamConfig = concatStringsSep "\n" (
|
|
map (
|
|
{
|
|
input,
|
|
ip,
|
|
out,
|
|
}:
|
|
''
|
|
server {
|
|
listen ${toString input};
|
|
listen [::]:${toString input};
|
|
proxy_pass ${ip}:${toString out};
|
|
}
|
|
''
|
|
) redirections.tcp
|
|
++ map (
|
|
{
|
|
input,
|
|
ip,
|
|
out,
|
|
}:
|
|
''
|
|
server {
|
|
listen ${toString input} udp;
|
|
listen [::]:${toString input} udp;
|
|
proxy_pass ${ip}:${toString out};
|
|
}
|
|
''
|
|
) redirections.udp
|
|
);
|
|
};
|
|
};
|
|
}
|