diff --git a/domain-proxies-module.nix b/domain-proxies-module.nix new file mode 100644 index 0000000..9ecc85a --- /dev/null +++ b/domain-proxies-module.nix @@ -0,0 +1,229 @@ +{ lib, config, ... }: +with lib; +let + vm-module = { + options = { + ip = mkOption { type = types.str; }; + ssh = mkOption { + type = types.nullOr types.ints.unsigned; + default = null; + }; + aliases = mkOption { + type = types.listOf types.str; + default = [ ]; + }; + port-forward = mkOption { + type = types.listOf types.ints.unsigned; + default = [ ]; + }; + }; + }; + hypervisor-module = + { config, name, ... }: + { + options = { + ip = mkOption { type = types.str; }; + host = mkOption { type = types.str; }; + vms = mkOption { type = types.attrsOf (types.submodule vm-module); }; + + domain-list = mkOption { + type = types.listOf types.str; + internal = true; + readOnly = true; + }; + ports = mkOption { + type = types.listOf types.ints.unsigned; + internal = true; + readOnly = true; + }; + redirects = mkOption { + type = types.unspecified; + internal = true; + readOnly = true; + }; + }; + config = rec { + domain-list = flatten ( + mapAttrsToList (main: vm: [ + main + vm.aliases + ]) config.vms + ); + ports = flatten ( + mapAttrsToList (_: vm: vm.port-forward ++ optional (!isNull vm.ssh) vm.ssh) config.vms + ); + redirects = { + stream = flatten ( + mapAttrsToList ( + _: vm: + optional (!isNull vm.ssh) { + input = vm.ssh; + out = 22; + ip = vm.ip; + } + ++ map (port: { + input = port; + out = port; + ip = vm.ip; + }) vm.port-forward + ) config.vms + ); + http = mapAttrs (_: vm: { inherit (vm) ip aliases; }) config.vms; + domain-list = domain-list; + }; + }; + }; + entry-module = + { config, name, ... }: + { + options = { + host = mkOption { type = types.str; }; + hypervisors = mkOption { type = types.attrsOf (types.submodule hypervisor-module); }; + + redirects = mkOption { + type = types.unspecified; + internal = true; + readOnly = true; + }; + hosts-redirects = mkOption { + type = types.unspecified; + internal = true; + readOnly = true; + }; + }; + config = rec { + redirects = { + stream = flatten ( + mapAttrsToList ( + _: hyp: + map (port: { + input = port; + out = port; + ip = hyp.ip; + }) hyp.ports + ) config.hypervisors + ); + http = mapAttrs (_: hyp: { + ip = hyp.ip; + aliases = hyp.domain-list; + }) config.hypervisors; + domain-list = flatten ( + mapAttrsToList (fqdn: hyp: [ fqdn ] ++ hyp.redirects.domain-list) config.hypervisors + ); + }; + hosts-redirects = + mergeAttrs + (listToAttrs ( + mapAttrsToList (main: hyp: { + name = hyp.host; + value = { + fqdn = main; + inherit (hyp.redirects) stream http domain-list; + }; + }) config.hypervisors + )) + { + ${config.host} = { + fqdn = name; + inherit (redirects) stream http domain-list; + }; + }; + }; + }; + + cfg = config.kat-proxies; + + hosts-redirects = zipAttrsWith (_: vals: mergeAttrsList vals) ( + mapAttrsToList (_: entry: entry.hosts-redirects) cfg.entries + ); + hostname = config.networking.hostName; + redirects = hosts-redirects.${hostname}; +in +{ + options.kat-proxies = { + enable = mkEnableOption "nginx configuration of proxies"; + entries = mkOption { type = types.attrsOf (types.submodule entry-module); }; + internal-webroot = mkOption { type = types.package; }; + }; + + config = mkIf cfg.enable { + security.acme.certs.${redirects.fqdn}.extraDomainNames = redirects.domain-list; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ] ++ map ({ input, ... }: input) redirects.stream; + services.nginx = { + enable = true; + virtualHosts = + mapAttrs ( + _: + { aliases, ip }: + { + useACMEHost = redirects.fqdn; + forceSSL = true; + acmeFallbackHost = ip; + acmeFallbackRecommendedProxySettings = true; + serverAliases = aliases; + locations = { + "/.${hostname}" = { + extraConfig = '' + internal; + error_page 404 =418 /.${hostname}/error/418.html; + ''; + root = cfg.internal-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}/error/599.html"; + ''; + }; + }; + } + ) redirects.http + // { + ${redirects.fqdn} = { + default = true; + enableACME = true; + addSSL = true; + locations = { + "/.${hostname}" = { + extraConfig = '' + internal; + error_page 404 =418 /.${hostname}/error/418.html; + ''; + root = cfg.internal-webroot; + }; + "/" = { + extraConfig = '' + return 418; + error_page 418 =418 /.${hostname}/error/418.html; + ''; + }; + }; + }; + }; + streamConfig = concatStringsSep "\n" ( + map ( + { + input, + ip, + out, + }: + '' + server { + listen ${toString input}; + proxy_pass ${ip}:${toString out}; + } + '' + ) redirects.stream + ); + }; + }; +} diff --git a/domain-proxies.nix b/domain-proxies.nix new file mode 100644 index 0000000..b49bb28 --- /dev/null +++ b/domain-proxies.nix @@ -0,0 +1,46 @@ +{ + kat-proxies.entries = { + "watcher.katvayor.net" = { + host = "kat-watcher"; + hypervisors."manah.katvayor.net" = { + host = "kat-manah"; + ip = "100.102.49.84"; + vms = { + "degette.katvayor.net" = { + ssh = 22000; + ip = "192.168.122.2"; + aliases = [ ]; + }; + "betamail.katvayor.net" = { + ssh = 22002; + ip = "192.168.122.3"; + aliases = [ "catvayor.sh" ]; + port-forward = [ + 25 + 465 + 993 + ]; + }; + "traque.katvayor.net" = { + ssh = 22001; + ip = "192.168.122.4"; + aliases = [ + "traque.dgnum.eu" + "test.traque.katvayor.net" + ]; + }; + "son.katvayor.net" = { + ssh = null; + ip = "192.168.122.5"; + aliases = [ ]; + }; + "orchid.katvayor.net" = { + ssh = 22042; + ip = "192.168.122.6"; + aliases = [ ]; + }; + }; + }; + }; + }; +} diff --git a/hive.nix b/hive.nix index 33a44db..3a4ca01 100644 --- a/hive.nix +++ b/hive.nix @@ -33,6 +33,8 @@ in "${sources.home-manager}/nixos" "${sources.agenix}/modules/age.nix" "${sources.disko}/module.nix" + ./domain-proxies-module.nix + ./domain-proxies.nix ]; options.system.build.anywhere = lib.mkOption { type = lib.types.package; diff --git a/machines/kat-manah/default.nix b/machines/kat-manah/default.nix index e224662..080e595 100644 --- a/machines/kat-manah/default.nix +++ b/machines/kat-manah/default.nix @@ -59,150 +59,16 @@ acceptTerms = true; defaults.email = "root@katvayor.net"; }; - services.nginx = - let - vhosts = { - "degette.katvayor.net" = { - vm = "192.168.122.2"; - sshport = 22000; - }; - "betamail.katvayor.net" = { - vm = "192.168.122.3"; - sshport = 22002; - }; - "catvayor.sh" = { - vm = "192.168.122.3"; - sshport = null; - }; - "traque.dgnum.eu" = { - vm = "192.168.122.4"; - sshport = null; - }; - "traque.katvayor.net" = { - vm = "192.168.122.4"; - sshport = 22001; - }; - "test.traque.katvayor.net" = { - vm = "192.168.122.4"; - sshport = null; - }; - "son.katvayor.net" = { - vm = "192.168.122.5"; - sshport = null; - }; - "orchid.katvayor.net" = { - vm = "192.168.122.6"; - sshport = 22042; - }; - }; - in - { - enable = true; - virtualHosts = - let - manah-webroot = pkgs.runCommand "manah" { } '' - mkdir -p $out/.kat-manah/ - ln -nsf ${./error} $out/.kat-manah/error - ''; - in - { - "manah.katvayor.net" = { - default = true; - enableACME = true; - addSSL = true; - locations = { - "/.kat-manah" = { - extraConfig = '' - internal; - error_page 404 =418 /.kat-manah/error/418.html; - ''; - root = manah-webroot; - }; - "/" = { - extraConfig = '' - return 418; - error_page 418 =418 /.kat-manah/error/418.html; - ''; - }; - }; - }; - } - // builtins.mapAttrs ( - _: - { vm, ... }: - { - enableACME = true; - addSSL = true; - acmeFallbackHost = vm; - acmeFallbackRecommendedProxySettings = true; - locations = { - "/.kat-manah" = { - extraConfig = '' - internal; - error_page 404 =418 /.kat-manah/error/418.html; - ''; - root = manah-webroot; - }; - "/" = { - recommendedProxySettings = true; - proxyPass = "https://${vm}/"; - extraConfig = '' - proxy_set_header Connection '''; - proxy_http_version 1.1; - chunked_transfer_encoding off; - proxy_buffering off; - proxy_cache off; - error_page 502 =599 "/.kat-manah/error/599.html"; - ''; - }; - }; - } - ) vhosts; - streamConfig = - builtins.concatStringsSep "\n" ( - lib.mapAttrsToList ( - vhost: - { vm, sshport }: - lib.optionalString (!isNull sshport) '' - server { - listen ${toString sshport}; - proxy_pass ${vm}:22; - } - '' - ) vhosts - ) - + '' - server { - listen 993; - proxy_pass 192.168.122.3:993; - } - server { - listen 465; - proxy_pass 192.168.122.3:465; - } - server { - listen 25; - proxy_pass 192.168.122.3:25; - } - ''; - }; + kat-proxies = { + enable = true; + internal-webroot = pkgs.runCommand "manah" { } '' + mkdir -p $out/.kat-manah/ + ln -nsf ${./error} $out/.kat-manah/error + ''; + }; networking.firewall = { - allowedTCPPorts = [ - 22 - 25 - 53 - 80 - 443 - 465 - 993 - ]; - allowedTCPPortRanges = [ - { - from = 22000; - to = 22100; - } - ]; + allowedTCPPorts = [ 22 ]; allowedUDPPorts = [ 67 ]; }; system.stateVersion = "23.11"; diff --git a/machines/kat-watcher/default.nix b/machines/kat-watcher/default.nix index ee8ccdc..0112b52 100644 --- a/machines/kat-watcher/default.nix +++ b/machines/kat-watcher/default.nix @@ -58,106 +58,13 @@ acceptTerms = true; defaults.email = "root@katvayor.net"; }; - services.nginx = - let - kat-r86s = "100.102.49.84"; - vhosts = { - "manah.katvayor.net" = null; - "degette.katvayor.net" = 22000; - "traque.katvayor.net" = 22001; - "traque.dgnum.eu" = null; - "betamail.katvayor.net" = 22002; - "catvayor.sh" = null; - "test.traque.katvayor.net" = null; - "son.katvayor.net" = null; - "orchid.katvayor.net" = 22042; - }; - in - { - enable = true; - virtualHosts = - let - watcher-webroot = pkgs.runCommand "watcher" { } '' - mkdir -p $out/.kat-watcher/ - ln -nsf ${./error} $out/.kat-watcher/error - ''; - in - { - "watcher.katvayor.net" = { - default = true; - enableACME = true; - addSSL = true; - locations = { - "/.kat-watcher" = { - extraConfig = '' - internal; - error_page 404 =418 /.kat-watcher/error/418.html; - ''; - root = watcher-webroot; - }; - "/" = { - extraConfig = '' - return 418; - error_page 418 =418 /.kat-watcher/error/418.html; - ''; - }; - }; - }; - } - // builtins.mapAttrs (_: _: { - enableACME = true; - forceSSL = true; - acmeFallbackHost = kat-r86s; - acmeFallbackRecommendedProxySettings = true; - locations = { - "/.kat-watcher" = { - extraConfig = '' - internal; - error_page 404 =418 /.kat-watcher/error/418.html; - ''; - root = watcher-webroot; - }; - "/" = { - recommendedProxySettings = true; - proxyPass = "https://${kat-r86s}/"; - extraConfig = '' - proxy_set_header Connection '''; - proxy_http_version 1.1; - chunked_transfer_encoding off; - proxy_buffering off; - proxy_cache off; - error_page 502 =599 "/.kat-watcher/error/599.html"; - ''; - }; - }; - }) vhosts; - streamConfig = - builtins.concatStringsSep "\n" ( - lib.mapAttrsToList ( - vhost: sshport: - lib.optionalString (!isNull sshport) '' - server { - listen ${toString sshport}; - proxy_pass ${kat-r86s}:${toString sshport}; - } - '' - ) vhosts - ) - + '' - server { - listen 993; - proxy_pass ${kat-r86s}:993; - } - server { - listen 465; - proxy_pass ${kat-r86s}:465; - } - server { - listen 25; - proxy_pass ${kat-r86s}:25; - } - ''; - }; + kat-proxies = { + enable = true; + internal-webroot = pkgs.runCommand "watcher" { } '' + mkdir -p $out/.kat-watcher/ + ln -nsf ${./error} $out/.kat-watcher/error + ''; + }; services.dbus.packages = with pkgs; [ dconf ]; @@ -182,22 +89,7 @@ services.netbird.enable = true; networking = { nftables.enable = true; - firewall = { - allowedTCPPorts = [ - 22 - 25 - 80 - 443 - 993 - 465 - ]; - allowedTCPPortRanges = [ - { - from = 22000; - to = 22100; - } - ]; - }; + firewall.allowedTCPPorts = [ 22 ]; }; system.stateVersion = "23.11";