From a5f3af5ff3a37bdd6b487d2c26899d9d16b3c5ea Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Sat, 21 Mar 2026 11:54:40 -0400 Subject: [PATCH] ports refactor --- configuration.nix | 2 +- flake.nix | 45 ++++-- service-configs.nix | 175 +++++++++++++++++----- services/arr/arr-search.nix | 4 +- services/arr/bazarr.nix | 4 +- services/arr/init.nix | 24 +-- services/arr/jellyseerr.nix | 4 +- services/arr/prowlarr.nix | 6 +- services/arr/radarr.nix | 4 +- services/arr/recyclarr.nix | 4 +- services/arr/sonarr.nix | 4 +- services/bitmagnet.nix | 6 +- services/bitwarden.nix | 2 +- services/caddy.nix | 6 +- services/coturn.nix | 12 +- services/firefox-syncserver.nix | 4 +- services/gitea.nix | 2 +- services/immich.nix | 2 +- services/jellyfin-qbittorrent-monitor.nix | 4 +- services/jellyfin.nix | 2 +- services/livekit.nix | 10 +- services/matrix.nix | 12 +- services/minecraft.nix | 2 +- services/monero.nix | 10 +- services/ntfy.nix | 4 +- services/p2pool.nix | 8 +- services/qbittorrent.nix | 2 +- services/soulseek.nix | 6 +- services/syncthing.nix | 10 +- services/xmrig.nix | 2 +- tests/fail2ban-gitea.nix | 5 +- tests/fail2ban-immich.nix | 5 +- 32 files changed, 264 insertions(+), 128 deletions(-) diff --git a/configuration.nix b/configuration.nix index 066cf4f..5b5ea80 100644 --- a/configuration.nix +++ b/configuration.nix @@ -285,7 +285,7 @@ openFirewall = true; welcometext = "meow meow meow meow meow :3 xd"; password = builtins.readFile ./secrets/murmur_password; - port = service_configs.ports.murmur; + port = service_configs.ports.public.murmur.port; }; # services.botamusique = { diff --git a/flake.nix b/flake.nix index e62b269..e8c4ba9 100644 --- a/flake.nix +++ b/flake.nix @@ -142,19 +142,46 @@ ; }; modules = [ - # SAFETY! make sure no ports collide + # SAFETY! port sanity checks ( - { lib, ... }: + { config, lib, ... }: + let + publicPorts = lib.attrValues service_configs.ports.public; + privatePorts = lib.attrValues service_configs.ports.private; + allPortNumbers = map (p: p.port) (publicPorts ++ privatePorts); + uniquePortNumbers = lib.unique allPortNumbers; + + # Which public ports must be in each firewall list + publicTcp = map (p: p.port) (lib.filter (p: p.proto == "tcp" || p.proto == "both") publicPorts); + publicUdp = map (p: p.port) (lib.filter (p: p.proto == "udp" || p.proto == "both") publicPorts); + + privatePortNumbers = map (p: p.port) privatePorts; + + fwTcp = config.networking.firewall.allowedTCPPorts; + fwUdp = config.networking.firewall.allowedUDPPorts; + + missingTcp = lib.filter (p: !(builtins.elem p fwTcp)) publicTcp; + missingUdp = lib.filter (p: !(builtins.elem p fwUdp)) publicUdp; + leakedTcp = lib.filter (p: builtins.elem p fwTcp) privatePortNumbers; + leakedUdp = lib.filter (p: builtins.elem p fwUdp) privatePortNumbers; + in { config.assertions = [ { - assertion = - let - ports = lib.attrValues service_configs.ports; - uniquePorts = lib.unique ports; - in - (lib.length ports) == (lib.length uniquePorts); - message = "Duplicate ports detected in 'ports' configuration"; + assertion = (lib.length allPortNumbers) == (lib.length uniquePortNumbers); + message = "Duplicate port numbers detected in ports.public / ports.private"; + } + { + assertion = missingTcp == [ ]; + message = "Public ports missing from allowedTCPPorts: ${builtins.toString missingTcp}"; + } + { + assertion = missingUdp == [ ]; + message = "Public ports missing from allowedUDPPorts: ${builtins.toString missingUdp}"; + } + { + assertion = leakedTcp == [ ] && leakedUdp == [ ]; + message = "Private ports leaked into firewall allow-lists — TCP: ${builtins.toString leakedTcp}, UDP: ${builtins.toString leakedUdp}"; } ]; } diff --git a/service-configs.nix b/service-configs.nix index dcada63..ea35cf5 100644 --- a/service-configs.nix +++ b/service-configs.nix @@ -9,42 +9,147 @@ rec { cpu_arch = "znver3"; ports = { - # public - http = 80; # TCP - https = 443; # TCP+UDP (HTTP/3 QUIC) - minecraft = 25565; # TCP - syncthing_protocol = 22000; # TCP+UDP (QUIC) - syncthing_discovery = 21027; # UDP - matrix_federation = 8448; # TCP+UDP (HTTP/3 QUIC) - coturn = 3478; # TCP+UDP - coturn_tls = 5349; # TCP+UDP - livekit = 7880; # TCP - soulseek_listen = 50300; # TCP - monero = 18080; # TCP - p2pool_p2p = 37889; # TCP - murmur = 64738; # TCP + UDP + # Ports exposed to the internet. The flake asserts every public port + # appears in the corresponding firewall allow-list (TCP, UDP, or both). + public = { + http = { + port = 80; + proto = "tcp"; + }; + https = { + port = 443; + proto = "both"; + }; # HTTP/3 QUIC + minecraft = { + port = 25565; + proto = "tcp"; + }; + syncthing_protocol = { + port = 22000; + proto = "both"; + }; # QUIC + syncthing_discovery = { + port = 21027; + proto = "udp"; + }; + matrix_federation = { + port = 8448; + proto = "both"; + }; # HTTP/3 QUIC + coturn = { + port = 3478; + proto = "both"; + }; + coturn_tls = { + port = 5349; + proto = "both"; + }; + livekit = { + port = 7880; + proto = "tcp"; + }; + soulseek_listen = { + port = 50300; + proto = "tcp"; + }; + monero = { + port = 18080; + proto = "tcp"; + }; + monero_rpc = { + port = 18081; + proto = "tcp"; + }; # restricted public RPC + p2pool_p2p = { + port = 37889; + proto = "tcp"; + }; + murmur = { + port = 64738; + proto = "both"; + }; + }; - # private - jellyfin = 8096; # TCP - no services.jellyfin option for this - torrent = 6011; # TCP - bitmagnet = 3333; # TCP - gitea = 2283; # TCP - immich = 2284; # TCP - soulseek_web = 5030; # TCP - vaultwarden = 8222; # TCP - syncthing_gui = 8384; # TCP - matrix = 6167; # TCP - ntfy = 2586; # TCP - lk_jwt = 8081; # TCP - prowlarr = 9696; # TCP - sonarr = 8989; # TCP - radarr = 7878; # TCP - bazarr = 6767; # TCP - jellyseerr = 5055; # TCP - monero_rpc = 18081; # TCP - monero_zmq = 18083; # TCP - p2pool_stratum = 3334; # TCP - firefox_syncserver = 5000; # TCP + # Ports bound to localhost / VPN only. The flake asserts none of + # these appear in the firewall allow-lists. + private = { + jellyfin = { + port = 8096; + proto = "tcp"; + }; + torrent = { + port = 6011; + proto = "tcp"; + }; + bitmagnet = { + port = 3333; + proto = "tcp"; + }; + gitea = { + port = 2283; + proto = "tcp"; + }; + immich = { + port = 2284; + proto = "tcp"; + }; + soulseek_web = { + port = 5030; + proto = "tcp"; + }; + vaultwarden = { + port = 8222; + proto = "tcp"; + }; + syncthing_gui = { + port = 8384; + proto = "tcp"; + }; + matrix = { + port = 6167; + proto = "tcp"; + }; + ntfy = { + port = 2586; + proto = "tcp"; + }; + lk_jwt = { + port = 8081; + proto = "tcp"; + }; + prowlarr = { + port = 9696; + proto = "tcp"; + }; + sonarr = { + port = 8989; + proto = "tcp"; + }; + radarr = { + port = 7878; + proto = "tcp"; + }; + bazarr = { + port = 6767; + proto = "tcp"; + }; + jellyseerr = { + port = 5055; + proto = "tcp"; + }; + monero_zmq = { + port = 18083; + proto = "tcp"; + }; + p2pool_stratum = { + port = 3334; + proto = "tcp"; + }; + firefox_syncserver = { + port = 5000; + proto = "tcp"; + }; + }; }; https = { diff --git a/services/arr/arr-search.nix b/services/arr/arr-search.nix index e2ee7ca..e9af616 100644 --- a/services/arr/arr-search.nix +++ b/services/arr/arr-search.nix @@ -7,8 +7,8 @@ let radarrConfig = "${service_configs.radarr.dataDir}/config.xml"; sonarrConfig = "${service_configs.sonarr.dataDir}/config.xml"; - radarrUrl = "http://localhost:${builtins.toString service_configs.ports.radarr}"; - sonarrUrl = "http://localhost:${builtins.toString service_configs.ports.sonarr}"; + radarrUrl = "http://localhost:${builtins.toString service_configs.ports.private.radarr.port}"; + sonarrUrl = "http://localhost:${builtins.toString service_configs.ports.private.sonarr.port}"; curl = "${pkgs.curl}/bin/curl"; jq = "${pkgs.jq}/bin/jq"; diff --git a/services/arr/bazarr.nix b/services/arr/bazarr.nix index c857ad6..1c7e0ad 100644 --- a/services/arr/bazarr.nix +++ b/services/arr/bazarr.nix @@ -20,12 +20,12 @@ services.bazarr = { enable = true; - listenPort = service_configs.ports.bazarr; + listenPort = service_configs.ports.private.bazarr.port; }; services.caddy.virtualHosts."bazarr.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} - reverse_proxy :${builtins.toString service_configs.ports.bazarr} + reverse_proxy :${builtins.toString service_configs.ports.private.bazarr.port} ''; users.users.${config.services.bazarr.user}.extraGroups = [ diff --git a/services/arr/init.nix b/services/arr/init.nix index d929c7f..d52a989 100644 --- a/services/arr/init.nix +++ b/services/arr/init.nix @@ -4,7 +4,7 @@ prowlarr = { enable = true; serviceName = "prowlarr"; - port = service_configs.ports.prowlarr; + port = service_configs.ports.private.prowlarr.port; dataDir = service_configs.prowlarr.dataDir; apiVersion = "v1"; networkNamespacePath = "/run/netns/wg"; @@ -14,8 +14,8 @@ name = "Sonarr"; implementation = "Sonarr"; configContract = "SonarrSettings"; - prowlarrUrl = "http://localhost:${builtins.toString service_configs.ports.prowlarr}"; - baseUrl = "http://${config.vpnNamespaces.wg.bridgeAddress}:${builtins.toString service_configs.ports.sonarr}"; + prowlarrUrl = "http://localhost:${builtins.toString service_configs.ports.private.prowlarr.port}"; + baseUrl = "http://${config.vpnNamespaces.wg.bridgeAddress}:${builtins.toString service_configs.ports.private.sonarr.port}"; apiKeyFrom = "${service_configs.sonarr.dataDir}/config.xml"; syncCategories = [ 5000 @@ -33,8 +33,8 @@ name = "Radarr"; implementation = "Radarr"; configContract = "RadarrSettings"; - prowlarrUrl = "http://localhost:${builtins.toString service_configs.ports.prowlarr}"; - baseUrl = "http://${config.vpnNamespaces.wg.bridgeAddress}:${builtins.toString service_configs.ports.radarr}"; + prowlarrUrl = "http://localhost:${builtins.toString service_configs.ports.private.prowlarr.port}"; + baseUrl = "http://${config.vpnNamespaces.wg.bridgeAddress}:${builtins.toString service_configs.ports.private.radarr.port}"; apiKeyFrom = "${service_configs.radarr.dataDir}/config.xml"; syncCategories = [ 2000 @@ -56,7 +56,7 @@ sonarr = { enable = true; serviceName = "sonarr"; - port = service_configs.ports.sonarr; + port = service_configs.ports.private.sonarr.port; dataDir = service_configs.sonarr.dataDir; healthChecks = true; rootFolders = [ service_configs.media.tvDir ]; @@ -68,7 +68,7 @@ serviceName = "qbittorrent"; fields = { host = config.vpnNamespaces.wg.namespaceAddress; - port = service_configs.ports.torrent; + port = service_configs.ports.private.torrent.port; useSsl = false; tvCategory = "tvshows"; }; @@ -79,7 +79,7 @@ radarr = { enable = true; serviceName = "radarr"; - port = service_configs.ports.radarr; + port = service_configs.ports.private.radarr.port; dataDir = service_configs.radarr.dataDir; healthChecks = true; rootFolders = [ service_configs.media.moviesDir ]; @@ -91,7 +91,7 @@ serviceName = "qbittorrent"; fields = { host = config.vpnNamespaces.wg.namespaceAddress; - port = service_configs.ports.torrent; + port = service_configs.ports.private.torrent.port; useSsl = false; movieCategory = "movies"; }; @@ -103,17 +103,17 @@ services.bazarrInit = { enable = true; dataDir = "/var/lib/bazarr"; - port = service_configs.ports.bazarr; + port = service_configs.ports.private.bazarr.port; sonarr = { enable = true; dataDir = service_configs.sonarr.dataDir; - port = service_configs.ports.sonarr; + port = service_configs.ports.private.sonarr.port; serviceName = "sonarr"; }; radarr = { enable = true; dataDir = service_configs.radarr.dataDir; - port = service_configs.ports.radarr; + port = service_configs.ports.private.radarr.port; serviceName = "radarr"; }; }; diff --git a/services/arr/jellyseerr.nix b/services/arr/jellyseerr.nix index 6433d04..ea0223b 100644 --- a/services/arr/jellyseerr.nix +++ b/services/arr/jellyseerr.nix @@ -17,7 +17,7 @@ services.jellyseerr = { enable = true; - port = service_configs.ports.jellyseerr; + port = service_configs.ports.private.jellyseerr.port; configDir = service_configs.jellyseerr.configDir; }; @@ -38,6 +38,6 @@ services.caddy.virtualHosts."jellyseerr.${service_configs.https.domain}".extraConfig = '' # import ${config.age.secrets.caddy_auth.path} - reverse_proxy :${builtins.toString service_configs.ports.jellyseerr} + reverse_proxy :${builtins.toString service_configs.ports.private.jellyseerr.port} ''; } diff --git a/services/arr/prowlarr.nix b/services/arr/prowlarr.nix index c5e9c69..7561c87 100644 --- a/services/arr/prowlarr.nix +++ b/services/arr/prowlarr.nix @@ -10,17 +10,17 @@ (lib.serviceMountWithZpool "prowlarr" service_configs.zpool_ssds [ service_configs.prowlarr.dataDir ]) - (lib.vpnNamespaceOpenPort service_configs.ports.prowlarr "prowlarr") + (lib.vpnNamespaceOpenPort service_configs.ports.private.prowlarr.port "prowlarr") ]; services.prowlarr = { enable = true; dataDir = service_configs.prowlarr.dataDir; - settings.server.port = service_configs.ports.prowlarr; + settings.server.port = service_configs.ports.private.prowlarr.port; }; services.caddy.virtualHosts."prowlarr.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} - reverse_proxy ${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.prowlarr} + reverse_proxy ${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.private.prowlarr.port} ''; } diff --git a/services/arr/radarr.nix b/services/arr/radarr.nix index fbd20e6..7a62e52 100644 --- a/services/arr/radarr.nix +++ b/services/arr/radarr.nix @@ -21,13 +21,13 @@ services.radarr = { enable = true; dataDir = service_configs.radarr.dataDir; - settings.server.port = service_configs.ports.radarr; + settings.server.port = service_configs.ports.private.radarr.port; settings.update.mechanism = "external"; }; services.caddy.virtualHosts."radarr.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} - reverse_proxy :${builtins.toString service_configs.ports.radarr} + reverse_proxy :${builtins.toString service_configs.ports.private.radarr.port} ''; users.users.${config.services.radarr.user}.extraGroups = [ diff --git a/services/arr/recyclarr.nix b/services/arr/recyclarr.nix index 4d2d61a..6fd6697 100644 --- a/services/arr/recyclarr.nix +++ b/services/arr/recyclarr.nix @@ -44,7 +44,7 @@ in configuration = { radarr.movies = { - base_url = "http://localhost:${builtins.toString service_configs.ports.radarr}"; + base_url = "http://localhost:${builtins.toString service_configs.ports.private.radarr.port}"; include = [ { template = "radarr-quality-definition-movie"; } @@ -123,7 +123,7 @@ in }; sonarr.series = { - base_url = "http://localhost:${builtins.toString service_configs.ports.sonarr}"; + base_url = "http://localhost:${builtins.toString service_configs.ports.private.sonarr.port}"; include = [ { template = "sonarr-quality-definition-series"; } diff --git a/services/arr/sonarr.nix b/services/arr/sonarr.nix index ac3da89..44dc196 100644 --- a/services/arr/sonarr.nix +++ b/services/arr/sonarr.nix @@ -27,13 +27,13 @@ services.sonarr = { enable = true; dataDir = service_configs.sonarr.dataDir; - settings.server.port = service_configs.ports.sonarr; + settings.server.port = service_configs.ports.private.sonarr.port; settings.update.mechanism = "external"; }; services.caddy.virtualHosts."sonarr.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} - reverse_proxy :${builtins.toString service_configs.ports.sonarr} + reverse_proxy :${builtins.toString service_configs.ports.private.sonarr.port} ''; users.users.${config.services.sonarr.user}.extraGroups = [ diff --git a/services/bitmagnet.nix b/services/bitmagnet.nix index d537315..9d27503 100644 --- a/services/bitmagnet.nix +++ b/services/bitmagnet.nix @@ -7,7 +7,7 @@ }: { imports = [ - (lib.vpnNamespaceOpenPort service_configs.ports.bitmagnet "bitmagnet") + (lib.vpnNamespaceOpenPort service_configs.ports.private.bitmagnet.port "bitmagnet") ]; services.bitmagnet = { @@ -19,13 +19,13 @@ }; http_server = { # TODO! make issue about this being a string and not a `port` type - port = ":" + (builtins.toString service_configs.ports.bitmagnet); + port = ":" + (builtins.toString service_configs.ports.private.bitmagnet.port); }; }; }; services.caddy.virtualHosts."bitmagnet.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} - reverse_proxy ${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.bitmagnet} + reverse_proxy ${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.private.bitmagnet.port} ''; } diff --git a/services/bitwarden.nix b/services/bitwarden.nix index a600db9..5068db8 100644 --- a/services/bitwarden.nix +++ b/services/bitwarden.nix @@ -30,7 +30,7 @@ SIGNUPS_ALLOWED = false; ROCKET_ADDRESS = "127.0.0.1"; - ROCKET_PORT = service_configs.ports.vaultwarden; + ROCKET_PORT = service_configs.ports.private.vaultwarden.port; ROCKET_LOG = "critical"; }; }; diff --git a/services/caddy.nix b/services/caddy.nix index c6adaf2..f77644f 100644 --- a/services/caddy.nix +++ b/services/caddy.nix @@ -113,14 +113,14 @@ in systemd.packages = with pkgs; [ nssTools ]; networking.firewall.allowedTCPPorts = [ - service_configs.ports.https + service_configs.ports.public.https.port # http (but really acmeCA challenges) - service_configs.ports.http + service_configs.ports.public.http.port ]; networking.firewall.allowedUDPPorts = [ - service_configs.ports.https + service_configs.ports.public.https.port ]; # Protect Caddy basic auth endpoints from brute force attacks diff --git a/services/coturn.nix b/services/coturn.nix index 78cc40d..9f11ff7 100644 --- a/services/coturn.nix +++ b/services/coturn.nix @@ -10,8 +10,8 @@ realm = service_configs.https.domain; use-auth-secret = true; static-auth-secret = lib.strings.trim (builtins.readFile ../secrets/coturn_static_auth_secret); - listening-port = service_configs.ports.coturn; - tls-listening-port = service_configs.ports.coturn_tls; + listening-port = service_configs.ports.public.coturn.port; + tls-listening-port = service_configs.ports.public.coturn_tls.port; no-cli = true; # recommended security settings from Synapse's coturn docs @@ -41,12 +41,12 @@ # coturn needs these ports open networking.firewall = { allowedTCPPorts = [ - service_configs.ports.coturn - service_configs.ports.coturn_tls + service_configs.ports.public.coturn.port + service_configs.ports.public.coturn_tls.port ]; allowedUDPPorts = [ - service_configs.ports.coturn - service_configs.ports.coturn_tls + service_configs.ports.public.coturn.port + service_configs.ports.public.coturn_tls.port ]; # relay port range allowedUDPPortRanges = [ diff --git a/services/firefox-syncserver.nix b/services/firefox-syncserver.nix index 8e783bc..5c077c5 100644 --- a/services/firefox-syncserver.nix +++ b/services/firefox-syncserver.nix @@ -14,7 +14,7 @@ user = "firefox_syncserver"; }; secrets = config.age.secrets.firefox-syncserver-env.path; - settings.port = service_configs.ports.firefox_syncserver; + settings.port = service_configs.ports.private.firefox_syncserver.port; singleNode = { enable = true; hostname = service_configs.firefox_syncserver.domain; @@ -34,6 +34,6 @@ }; services.caddy.virtualHosts."${service_configs.firefox_syncserver.domain}".extraConfig = '' - reverse_proxy :${builtins.toString service_configs.ports.firefox_syncserver} + reverse_proxy :${builtins.toString service_configs.ports.private.firefox_syncserver.port} ''; } diff --git a/services/gitea.nix b/services/gitea.nix index 77a1a43..dff1abe 100644 --- a/services/gitea.nix +++ b/services/gitea.nix @@ -27,7 +27,7 @@ SSH_USER = "gitea"; DOMAIN = service_configs.gitea.domain; ROOT_URL = "https://" + config.services.gitea.settings.server.DOMAIN; - HTTP_PORT = service_configs.ports.gitea; + HTTP_PORT = service_configs.ports.private.gitea.port; LANDING_PAGE = "/explore/repos"; DISABLE_HTTP_GIT = true; }; diff --git a/services/immich.nix b/services/immich.nix index 363d09e..c01dafe 100644 --- a/services/immich.nix +++ b/services/immich.nix @@ -21,7 +21,7 @@ services.immich = { enable = true; mediaLocation = service_configs.immich.dir; - port = service_configs.ports.immich; + port = service_configs.ports.private.immich.port; # openFirewall = true; host = "0.0.0.0"; database = { diff --git a/services/jellyfin-qbittorrent-monitor.nix b/services/jellyfin-qbittorrent-monitor.nix index 307e07b..9d73adc 100644 --- a/services/jellyfin-qbittorrent-monitor.nix +++ b/services/jellyfin-qbittorrent-monitor.nix @@ -43,8 +43,8 @@ }; environment = { - JELLYFIN_URL = "http://localhost:${builtins.toString service_configs.ports.jellyfin}"; - QBITTORRENT_URL = "http://${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.torrent}"; + JELLYFIN_URL = "http://localhost:${builtins.toString service_configs.ports.private.jellyfin.port}"; + QBITTORRENT_URL = "http://${config.vpnNamespaces.wg.namespaceAddress}:${builtins.toString service_configs.ports.private.torrent.port}"; CHECK_INTERVAL = "30"; # Bandwidth budget configuration TOTAL_BANDWIDTH_BUDGET = "30000000"; # 30 Mbps in bits per second diff --git a/services/jellyfin.nix b/services/jellyfin.nix index 2ab9b12..b80e842 100644 --- a/services/jellyfin.nix +++ b/services/jellyfin.nix @@ -25,7 +25,7 @@ }; services.caddy.virtualHosts."jellyfin.${service_configs.https.domain}".extraConfig = '' - reverse_proxy :${builtins.toString service_configs.ports.jellyfin} { + reverse_proxy :${builtins.toString service_configs.ports.private.jellyfin.port} { header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} diff --git a/services/livekit.nix b/services/livekit.nix index c1579d7..4573780 100644 --- a/services/livekit.nix +++ b/services/livekit.nix @@ -4,8 +4,6 @@ }: let keyFile = ../secrets/livekit_keys; - - ports = service_configs.ports; in { services.livekit = { @@ -14,7 +12,7 @@ in openFirewall = true; settings = { - port = ports.livekit; + port = service_configs.ports.public.livekit.port; bind_addresses = [ "127.0.0.1" ]; rtc = { @@ -38,16 +36,16 @@ in enable = true; inherit keyFile; livekitUrl = "wss://${service_configs.livekit.domain}"; - port = ports.lk_jwt; + port = service_configs.ports.private.lk_jwt.port; }; services.caddy.virtualHosts."${service_configs.livekit.domain}".extraConfig = '' @jwt path /sfu/get /healthz handle @jwt { - reverse_proxy :${builtins.toString ports.lk_jwt} + reverse_proxy :${builtins.toString service_configs.ports.private.lk_jwt.port} } handle { - reverse_proxy :${builtins.toString ports.livekit} + reverse_proxy :${builtins.toString service_configs.ports.public.livekit.port} } ''; } diff --git a/services/matrix.nix b/services/matrix.nix index e1d3b17..3aaee5b 100644 --- a/services/matrix.nix +++ b/services/matrix.nix @@ -18,7 +18,7 @@ enable = true; settings.global = { - port = [ service_configs.ports.matrix ]; + port = [ service_configs.ports.private.matrix.port ]; server_name = service_configs.https.domain; allow_registration = true; registration_token = lib.strings.trim (builtins.readFile ../secrets/matrix_reg_token); @@ -49,25 +49,25 @@ services.caddy.virtualHosts.${service_configs.https.domain}.extraConfig = lib.mkBefore '' header /.well-known/matrix/* Content-Type application/json header /.well-known/matrix/* Access-Control-Allow-Origin * - respond /.well-known/matrix/server `{"m.server": "${service_configs.matrix.domain}:${builtins.toString service_configs.ports.https}"}` + respond /.well-known/matrix/server `{"m.server": "${service_configs.matrix.domain}:${builtins.toString service_configs.ports.public.https.port}"}` respond /.well-known/matrix/client `{"m.server":{"base_url":"https://${service_configs.matrix.domain}"},"m.homeserver":{"base_url":"https://${service_configs.matrix.domain}"},"org.matrix.msc3575.proxy":{"base_url":"https://${config.services.matrix-continuwuity.settings.global.server_name}"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://${service_configs.livekit.domain}"}]}` ''; services.caddy.virtualHosts."${service_configs.matrix.domain}".extraConfig = '' - reverse_proxy :${builtins.toString service_configs.ports.matrix} + reverse_proxy :${builtins.toString service_configs.ports.private.matrix.port} ''; # Exact duplicate for federation port - services.caddy.virtualHosts."${service_configs.matrix.domain}:${builtins.toString service_configs.ports.matrix_federation}".extraConfig = + services.caddy.virtualHosts."${service_configs.matrix.domain}:${builtins.toString service_configs.ports.public.matrix_federation.port}".extraConfig = config.services.caddy.virtualHosts."${service_configs.matrix.domain}".extraConfig; # for federation networking.firewall.allowedTCPPorts = [ - service_configs.ports.matrix_federation + service_configs.ports.public.matrix_federation.port ]; # for federation networking.firewall.allowedUDPPorts = [ - service_configs.ports.matrix_federation + service_configs.ports.public.matrix_federation.port ]; } diff --git a/services/minecraft.nix b/services/minecraft.nix index e08919f..adfd500 100644 --- a/services/minecraft.nix +++ b/services/minecraft.nix @@ -73,7 +73,7 @@ ]; serverProperties = { - server-port = service_configs.ports.minecraft; + server-port = service_configs.ports.public.minecraft.port; enforce-whitelist = true; gamemode = "survival"; white-list = true; diff --git a/services/monero.nix b/services/monero.nix index 6556ce5..7025c3d 100644 --- a/services/monero.nix +++ b/services/monero.nix @@ -18,12 +18,12 @@ dataDir = service_configs.monero.dataDir; rpc = { address = "0.0.0.0"; - port = service_configs.ports.monero_rpc; + port = service_configs.ports.public.monero_rpc.port; restricted = true; }; extraConfig = '' - p2p-bind-port=${builtins.toString service_configs.ports.monero} - zmq-pub=tcp://127.0.0.1:${builtins.toString service_configs.ports.monero_zmq} + p2p-bind-port=${builtins.toString service_configs.ports.public.monero.port} + zmq-pub=tcp://127.0.0.1:${builtins.toString service_configs.ports.private.monero_zmq.port} db-sync-mode=fast:async:1000000000bytes public-node=1 confirm-external-bind=1 @@ -31,7 +31,7 @@ }; networking.firewall.allowedTCPPorts = [ - service_configs.ports.monero - service_configs.ports.monero_rpc + service_configs.ports.public.monero.port + service_configs.ports.public.monero_rpc.port ]; } diff --git a/services/ntfy.nix b/services/ntfy.nix index 3b7dd1b..ef26330 100644 --- a/services/ntfy.nix +++ b/services/ntfy.nix @@ -19,7 +19,7 @@ settings = { base-url = "https://${service_configs.ntfy.domain}"; - listen-http = "127.0.0.1:${builtins.toString service_configs.ports.ntfy}"; + listen-http = "127.0.0.1:${builtins.toString service_configs.ports.private.ntfy.port}"; behind-proxy = true; auth-default-access = "deny-all"; enable-login = true; @@ -28,7 +28,7 @@ }; services.caddy.virtualHosts."${service_configs.ntfy.domain}".extraConfig = '' - reverse_proxy :${builtins.toString service_configs.ports.ntfy} + reverse_proxy :${builtins.toString service_configs.ports.private.ntfy.port} ''; } diff --git a/services/p2pool.nix b/services/p2pool.nix index 3cc07b8..99101ab 100644 --- a/services/p2pool.nix +++ b/services/p2pool.nix @@ -23,10 +23,10 @@ in walletAddress = walletAddress; sidechain = "nano"; host = "127.0.0.1"; - rpcPort = service_configs.ports.monero_rpc; - zmqPort = service_configs.ports.monero_zmq; + rpcPort = service_configs.ports.public.monero_rpc.port; + zmqPort = service_configs.ports.private.monero_zmq.port; extraArgs = [ - " --stratum 0.0.0.0:${builtins.toString service_configs.ports.p2pool_stratum}" + " --stratum 0.0.0.0:${builtins.toString service_configs.ports.private.p2pool_stratum.port}" ]; }; @@ -43,6 +43,6 @@ in }; networking.firewall.allowedTCPPorts = [ - service_configs.ports.p2pool_p2p + service_configs.ports.public.p2pool_p2p.port ]; } diff --git a/services/qbittorrent.nix b/services/qbittorrent.nix index e8c00a7..606eefe 100644 --- a/services/qbittorrent.nix +++ b/services/qbittorrent.nix @@ -26,7 +26,7 @@ services.qbittorrent = { enable = true; - webuiPort = service_configs.ports.torrent; + webuiPort = service_configs.ports.private.torrent.port; profileDir = "/var/lib/qBittorrent"; # Set the service group to 'media' so the systemd unit runs with media as # the primary GID. Linux assigns new file ownership from the process's GID diff --git a/services/soulseek.nix b/services/soulseek.nix index 21e9bff..f8c4f62 100644 --- a/services/soulseek.nix +++ b/services/soulseek.nix @@ -30,11 +30,11 @@ settings = { web = { - port = service_configs.ports.soulseek_web; + port = service_configs.ports.private.soulseek_web.port; }; soulseek = { # description = "smth idk"; - listen_port = service_configs.ports.soulseek_listen; + listen_port = service_configs.ports.public.soulseek_listen.port; }; shares = { @@ -64,6 +64,6 @@ ''; networking.firewall.allowedTCPPorts = [ - service_configs.ports.soulseek_listen + service_configs.ports.public.soulseek_listen.port ]; } diff --git a/services/syncthing.nix b/services/syncthing.nix index a7cf2bf..6200737 100644 --- a/services/syncthing.nix +++ b/services/syncthing.nix @@ -24,7 +24,7 @@ dataDir = service_configs.syncthing.dataDir; - guiAddress = "127.0.0.1:${toString service_configs.ports.syncthing_gui}"; + guiAddress = "127.0.0.1:${toString service_configs.ports.private.syncthing_gui.port}"; overrideDevices = false; overrideFolders = false; @@ -42,16 +42,16 @@ # Open firewall ports for syncthing protocol networking.firewall = { - allowedTCPPorts = [ service_configs.ports.syncthing_protocol ]; + allowedTCPPorts = [ service_configs.ports.public.syncthing_protocol.port ]; allowedUDPPorts = [ - service_configs.ports.syncthing_discovery - service_configs.ports.syncthing_protocol + service_configs.ports.public.syncthing_discovery.port + service_configs.ports.public.syncthing_protocol.port ]; }; services.caddy.virtualHosts."syncthing.${service_configs.https.domain}".extraConfig = '' import ${config.age.secrets.caddy_auth.path} - reverse_proxy :${toString service_configs.ports.syncthing_gui} + reverse_proxy :${toString service_configs.ports.private.syncthing_gui.port} ''; } diff --git a/services/xmrig.nix b/services/xmrig.nix index 2d4dc04..6793f1d 100644 --- a/services/xmrig.nix +++ b/services/xmrig.nix @@ -32,7 +32,7 @@ in pools = [ { - url = "127.0.0.1:${builtins.toString service_configs.ports.p2pool_stratum}"; + url = "127.0.0.1:${builtins.toString service_configs.ports.private.p2pool_stratum.port}"; tls = false; } ]; diff --git a/tests/fail2ban-gitea.nix b/tests/fail2ban-gitea.nix index 0022c06..b9fe355 100644 --- a/tests/fail2ban-gitea.nix +++ b/tests/fail2ban-gitea.nix @@ -12,7 +12,10 @@ let dir = "/var/lib/gitea"; domain = "git.test.local"; }; - ports.gitea = 3000; + ports.private.gitea = { + port = 3000; + proto = "tcp"; + }; }; testLib = lib.extend ( diff --git a/tests/fail2ban-immich.nix b/tests/fail2ban-immich.nix index 2fefa0a..04a8530 100644 --- a/tests/fail2ban-immich.nix +++ b/tests/fail2ban-immich.nix @@ -9,7 +9,10 @@ let testServiceConfigs = lib.recursiveUpdate baseServiceConfigs { zpool_ssds = ""; https.domain = "test.local"; - ports.immich = 2283; + ports.private.immich = { + port = 2283; + proto = "tcp"; + }; immich.dir = "/var/lib/immich"; };