diff --git a/hosts/architect/options.nix b/hosts/architect/options.nix index f3091ae..f55d0dc 100644 --- a/hosts/architect/options.nix +++ b/hosts/architect/options.nix @@ -1,148 +1,21 @@ { config, lib, ... }: -with lib; - { + # Legacy compatibility layer options.architect = { - firewall = { - openTCP = mkOption { - type = types.listOf types.int; - default = [ ]; - }; - openUDP = mkOption { - type = types.listOf types.int; - default = [ ]; - }; + firewall = lib.mkOption { + internal = true; + default = config.pepe.core.firewall; }; - networks = mkOption { - type = types.attrsOf (types.submodule { - options = { - interface = mkOption { - type = types.str; - description = "The network interface name."; - }; - - net = mkOption { - type = types.str; - description = "The network address in CIDR format."; - }; - - devices = mkOption { - type = types.attrsOf (types.submodule { - options = { - address = mkOption { - type = types.str; - description = "The IP address of the device."; - }; - - hostname = mkOption { - type = types.str; - description = "The hostname of the device."; - }; - }; - }); - default = { }; - description = "An attribute set of devices with their configurations."; - }; - }; - }); - default = { }; - description = "An attribute set of networks with their configurations."; + networks = lib.mkOption { + internal = true; + default = config.pepe.core.network.interfaces; }; - vhost = mkOption { - type = types.attrsOf (types.submodule { - options = { - dnsInterfaces = mkOption { - type = types.listOf types.str; - default = [ ]; - description = "List of interfaces to add extra DNS hosts for this vhost."; - }; - - locations = mkOption { - type = types.attrsOf (types.submodule { - options = { - extraConfig = mkOption { - type = types.str; - description = "Extra configuration for the location."; - default = ""; - }; - - allowLan = mkOption { - type = types.bool; - default = false; - }; - - proxyWebsockets = mkOption { - type = types.bool; - default = false; - }; - - host = mkOption { - type = types.str; - description = "The host for the location."; - default = "127.0.0.1"; - }; - - port = mkOption { - type = types.int; - description = "The port number for the location."; - }; - - allow = mkOption { - type = types.listOf types.str; - default = [ ]; - description = "IP address or CIDR block to allow."; - }; - - path = mkOption { - type = types.str; - default = ""; - }; - - recommendedProxySettings = mkOption { - type = types.bool; - default = true; - description = "Force the use of recommended proxy configuration."; - }; - - allowWAN = mkOption { - type = types.bool; - default = false; - description = "If set to false, deny all WAN traffic."; - }; - }; - }); - default = { }; - description = "An attribute set of location configurations."; - }; - }; - }); - default = { }; - description = "An attribute set of domain configurations."; + vhost = lib.mkOption { + internal = true; + default = config.pepe.core.vhost.hosts; }; }; - - # TODO: move to nginx - config = { - services.nginx.virtualHosts = mapAttrs - (domain: conf: { - forceSSL = true; - useACMEHost= "giugl.io"; - locations = mapAttrs - (path: location: { - proxyPass = "http://${location.host}:${toString location.port}${location.path}"; - proxyWebsockets = location.proxyWebsockets; - recommendedProxySettings = location.recommendedProxySettings; - extraConfig = '' - ${concatMapStringsSep "\n" (allowCIDR: "allow ${allowCIDR};") location.allow} - ${optionalString location.allowLan ''allow ${config.architect.networks."lan".net};''} - ${optionalString (!location.allowWAN) "deny all;"} - '' + location.extraConfig; - }) - conf.locations; - }) - config.architect.vhost; - }; } diff --git a/modules/core/default.nix b/modules/core/default.nix index f338f34..c557e03 100644 --- a/modules/core/default.nix +++ b/modules/core/default.nix @@ -2,5 +2,8 @@ imports = [ ./media.nix ./graphics.nix + ./network.nix + ./vhost.nix + ./firewall.nix ]; } diff --git a/modules/core/firewall.nix b/modules/core/firewall.nix new file mode 100644 index 0000000..4215a9b --- /dev/null +++ b/modules/core/firewall.nix @@ -0,0 +1,27 @@ +{ config, lib, ... }: + +let + inherit (lib) mkOption types; + cfg = config.pepe.core.firewall; +in +{ + options.pepe.core.firewall = { + openTCP = mkOption { + type = types.listOf types.int; + default = [ ]; + description = "TCP ports to open in the firewall"; + }; + openUDP = mkOption { + type = types.listOf types.int; + default = [ ]; + description = "UDP ports to open in the firewall"; + }; + }; + + config = { + networking.firewall = { + allowedTCPPorts = cfg.openTCP; + allowedUDPPorts = cfg.openUDP; + }; + }; +} diff --git a/modules/core/network.nix b/modules/core/network.nix new file mode 100644 index 0000000..efd3a59 --- /dev/null +++ b/modules/core/network.nix @@ -0,0 +1,45 @@ +{ config, lib, ... }: + +let + inherit (lib) mkOption types; + cfg = config.pepe.core.network; +in +{ + options.pepe.core.network = { + interfaces = mkOption { + type = types.attrsOf (types.submodule { + options = { + interface = mkOption { + type = types.str; + description = "The network interface name."; + }; + + net = mkOption { + type = types.str; + description = "The network address in CIDR format."; + }; + + devices = mkOption { + type = types.attrsOf (types.submodule { + options = { + address = mkOption { + type = types.str; + description = "The IP address of the device."; + }; + + hostname = mkOption { + type = types.str; + description = "The hostname of the device."; + }; + }; + }); + default = { }; + description = "An attribute set of devices with their configurations."; + }; + }; + }); + default = { }; + description = "An attribute set of networks with their configurations."; + }; + }; +} diff --git a/modules/core/vhost.nix b/modules/core/vhost.nix new file mode 100644 index 0000000..cdef45d --- /dev/null +++ b/modules/core/vhost.nix @@ -0,0 +1,102 @@ +{ config, lib, ... }: + +let + inherit (lib) mkOption types mapAttrs concatMapStringsSep optionalString; + cfg = config.pepe.core.vhost; +in +{ + options.pepe.core.vhost = { + hosts = mkOption { + type = types.attrsOf (types.submodule { + options = { + dnsInterfaces = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "List of interfaces to add extra DNS hosts for this vhost."; + }; + + locations = mkOption { + type = types.attrsOf (types.submodule { + options = { + extraConfig = mkOption { + type = types.str; + description = "Extra configuration for the location."; + default = ""; + }; + + allowLan = mkOption { + type = types.bool; + default = false; + }; + + proxyWebsockets = mkOption { + type = types.bool; + default = false; + }; + + host = mkOption { + type = types.str; + description = "The host for the location."; + default = "127.0.0.1"; + }; + + port = mkOption { + type = types.int; + description = "The port number for the location."; + }; + + allow = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "IP address or CIDR block to allow."; + }; + + path = mkOption { + type = types.str; + default = ""; + }; + + recommendedProxySettings = mkOption { + type = types.bool; + default = true; + description = "Force the use of recommended proxy configuration."; + }; + + allowWAN = mkOption { + type = types.bool; + default = false; + description = "If set to false, deny all WAN traffic."; + }; + }; + }); + default = { }; + description = "An attribute set of location configurations."; + }; + }; + }); + default = { }; + description = "An attribute set of domain configurations."; + }; + }; + + config = { + services.nginx.virtualHosts = mapAttrs + (domain: conf: { + forceSSL = true; + useACMEHost= "giugl.io"; + locations = mapAttrs + (path: location: { + proxyPass = "http://${location.host}:${toString location.port}${location.path}"; + proxyWebsockets = location.proxyWebsockets; + recommendedProxySettings = location.recommendedProxySettings; + extraConfig = '' + ${concatMapStringsSep "\n" (allowCIDR: "allow ${allowCIDR};") location.allow} + ${optionalString location.allowLan ''allow ${config.pepe.core.network.interfaces."lan".net};''} + ${optionalString (!location.allowWAN) "deny all;"} + '' + location.extraConfig; + }) + conf.locations; + }) + cfg.hosts; + }; +} diff --git a/modules/services/bazarr/default.nix b/modules/services/bazarr/default.nix index 68a0810..1120487 100644 --- a/modules/services/bazarr/default.nix +++ b/modules/services/bazarr/default.nix @@ -22,7 +22,7 @@ in group = "media"; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "tailscale" ]; locations."/" = { port = 6767; diff --git a/modules/services/gitea/default.nix b/modules/services/gitea/default.nix index f13571f..92441eb 100644 --- a/modules/services/gitea/default.nix +++ b/modules/services/gitea/default.nix @@ -16,9 +16,9 @@ in }; config = mkIf cfg.enable { - architect = { + pepe.core = { firewall.openTCP = [ config.services.gitea.settings.server.SSH_PORT ]; - vhost.${cfg.domain} = { + vhost.hosts.${cfg.domain} = { dnsInterfaces = [ "lan" "tailscale" ]; locations."/" = { port = config.services.gitea.settings.server.HTTP_PORT; diff --git a/modules/services/immich/default.nix b/modules/services/immich/default.nix index a67da22..cf7a719 100644 --- a/modules/services/immich/default.nix +++ b/modules/services/immich/default.nix @@ -22,14 +22,14 @@ in }; }; - architect.vhost.${cfg.domain} = { + pepe.core.vhost.hosts.${cfg.domain} = { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { host = "[::1]"; port = config.services.immich.port; allowLan = true; allowWAN = true; - allow = [ config.architect.networks."tailscale".net ]; + allow = [ config.pepe.core.network.interfaces."tailscale".net ]; proxyWebsockets = true; extraConfig = '' # allow large file uploads diff --git a/modules/services/jellyfin/default.nix b/modules/services/jellyfin/default.nix index 7d81a40..223d579 100644 --- a/modules/services/jellyfin/default.nix +++ b/modules/services/jellyfin/default.nix @@ -24,7 +24,7 @@ in # needed since StateDirectory does not accept symlinks systemd.services.jellyfin.serviceConfig.StateDirectory = mkForce ""; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "lan" "tailscale" ]; locations = { "/" = { diff --git a/modules/services/jellyseer/default.nix b/modules/services/jellyseer/default.nix index 85ff8c6..e614ff5 100644 --- a/modules/services/jellyseer/default.nix +++ b/modules/services/jellyseer/default.nix @@ -21,7 +21,7 @@ in package = cfg.package; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { port = config.services.jellyseerr.port; diff --git a/modules/services/lidarr/default.nix b/modules/services/lidarr/default.nix index c608bff..194866f 100644 --- a/modules/services/lidarr/default.nix +++ b/modules/services/lidarr/default.nix @@ -22,7 +22,7 @@ in group = "media"; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "lan" "tailscale" ]; locations."/" = { port = 8686; diff --git a/modules/services/navidrome/default.nix b/modules/services/navidrome/default.nix index 7ab7309..aa4066b 100644 --- a/modules/services/navidrome/default.nix +++ b/modules/services/navidrome/default.nix @@ -46,7 +46,7 @@ in } // cfg.settings; }; - architect.vhost.${cfg.domain} = { + pepe.core.vhost.hosts.${cfg.domain} = { dnsInterfaces = [ "lan" "tailscale" ]; locations."/" = { port = 4533; diff --git a/modules/services/nzbget/default.nix b/modules/services/nzbget/default.nix index 72d8d96..42d2599 100644 --- a/modules/services/nzbget/default.nix +++ b/modules/services/nzbget/default.nix @@ -22,7 +22,7 @@ in group = "media"; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { port = 6789; diff --git a/modules/services/prowlarr/default.nix b/modules/services/prowlarr/default.nix index 7b53817..848f11a 100644 --- a/modules/services/prowlarr/default.nix +++ b/modules/services/prowlarr/default.nix @@ -21,7 +21,7 @@ in package = cfg.package; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { port = 9696; diff --git a/modules/services/radarr/default.nix b/modules/services/radarr/default.nix index 3c7281e..66f0384 100644 --- a/modules/services/radarr/default.nix +++ b/modules/services/radarr/default.nix @@ -21,7 +21,7 @@ in package = cfg.package; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { port = 7878; diff --git a/modules/services/sonarr/default.nix b/modules/services/sonarr/default.nix index fe9160d..7cc3999 100644 --- a/modules/services/sonarr/default.nix +++ b/modules/services/sonarr/default.nix @@ -21,7 +21,7 @@ in package = cfg.package; }; - architect.vhost.${cfg.domain} = with config.architect.networks; { + pepe.core.vhost.hosts.${cfg.domain} = with config.pepe.core.network.interfaces; { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { port = 8989;