225 lines
5.4 KiB
Nix
225 lines
5.4 KiB
Nix
|
{
|
||
|
pkgs,
|
||
|
lib,
|
||
|
config,
|
||
|
nodes ? { },
|
||
|
...
|
||
|
}:
|
||
|
with lib;
|
||
|
let
|
||
|
redirected-ports-mod.options = {
|
||
|
external = mkOption {
|
||
|
type = types.port;
|
||
|
};
|
||
|
internal = mkOption {
|
||
|
type = types.port;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
redirection-port-type = types.coercedTo types.port (port: {
|
||
|
external = port;
|
||
|
internal = port;
|
||
|
}) (types.submodule redirected-ports-mod);
|
||
|
|
||
|
fqdn = 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 =
|
||
|
lib.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
|
||
|
fqdn = nodes.${host}.config.kat.fqdn;
|
||
|
host-cfg = nodes.${host}.config.kat.proxies;
|
||
|
in
|
||
|
{
|
||
|
domains = [ fqdn ] ++ host-cfg.aliases;
|
||
|
tcp = map (
|
||
|
{ external, internal }:
|
||
|
{
|
||
|
input = external;
|
||
|
ip = host-cfg.ip;
|
||
|
out = internal;
|
||
|
}
|
||
|
) host-cfg.open-tcp;
|
||
|
udp = map (
|
||
|
{ external, internal }:
|
||
|
{
|
||
|
input = external;
|
||
|
ip = host-cfg.ip;
|
||
|
out = internal;
|
||
|
}
|
||
|
) host-cfg.open-udp;
|
||
|
vhosts.${fqdn} = {
|
||
|
ip = host-cfg.ip;
|
||
|
aliases = host-cfg.aliases;
|
||
|
};
|
||
|
}
|
||
|
) cfg.redirects
|
||
|
);
|
||
|
in
|
||
|
{
|
||
|
options.kat.proxies = {
|
||
|
enable = mkEnableOption "kat-proxies autoconfiguration" // {
|
||
|
default = cfg.redirects != [ ];
|
||
|
defaultText = ''config.kat.proxies.redirects != [ ]'';
|
||
|
};
|
||
|
|
||
|
ip = mkOption {
|
||
|
type = types.str;
|
||
|
};
|
||
|
|
||
|
aliases = mkOption {
|
||
|
type = types.listOf types.str;
|
||
|
default = [ ];
|
||
|
};
|
||
|
open-tcp = mkOption {
|
||
|
type = types.listOf redirection-port-type;
|
||
|
default = [ ];
|
||
|
};
|
||
|
open-udp = mkOption {
|
||
|
type = types.listOf redirection-port-type;
|
||
|
default = [ ];
|
||
|
};
|
||
|
|
||
|
redirects = mkOption {
|
||
|
type = types.listOf types.str;
|
||
|
default = [ ];
|
||
|
};
|
||
|
|
||
|
test = mkOption {
|
||
|
type = types.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
|
||
|
);
|
||
|
};
|
||
|
};
|
||
|
}
|