From edf2d6041047339ba5dbc617aea352e4b533e777 Mon Sep 17 00:00:00 2001 From: arcnmx Date: Fri, 17 May 2024 20:33:12 -0700 Subject: [PATCH] fix(access): deluge --- modules/nixos/nginx/local.nix | 21 +++++++- modules/nixos/nginx/upstream.nix | 6 ++- modules/system/exports/deluge.nix | 46 ++++++++++++++++ nixos/access/deluge.nix | 88 +++++++++++++++++++++++++++++++ nixos/deluge.nix | 7 +++ systems/hakurei/nixos.nix | 10 ++++ systems/mediabox/cloudflared.nix | 41 +++++++++----- systems/mediabox/default.nix | 6 ++- systems/mediabox/nixos.nix | 9 ++++ tf/cloudflare_records.tf | 1 + 10 files changed, 217 insertions(+), 18 deletions(-) create mode 100644 modules/system/exports/deluge.nix create mode 100644 nixos/access/deluge.nix diff --git a/modules/nixos/nginx/local.nix b/modules/nixos/nginx/local.nix index ea0f0c74..50827973 100644 --- a/modules/nixos/nginx/local.nix +++ b/modules/nixos/nginx/local.nix @@ -142,6 +142,17 @@ }; }; + config.local = { + enable = mkOptionDefault false; + denyGlobal = mkOptionDefault cfg.enable; + trusted = mkOptionDefault cfg.denyGlobal; + }; + }; + serverModule = {config, ...}: let + cfg = config.local; + in { + imports = [localModule]; + config.local = { enable = mkOptionDefault false; denyGlobal = mkOptionDefault cfg.enable; @@ -149,9 +160,15 @@ }; }; in { - options = with lib.types; { - services.nginx.virtualHosts = mkOption { + options.services.nginx = with lib.types; { + virtualHosts = mkOption { type = attrsOf (submodule [hostModule]); }; + stream.servers = mkOption { + type = attrsOf (submoduleWith { + modules = [serverModule]; + shorthandOnlyDefinesConfig = false; + }); + }; }; } diff --git a/modules/nixos/nginx/upstream.nix b/modules/nixos/nginx/upstream.nix index be6450e0..3fecea5d 100644 --- a/modules/nixos/nginx/upstream.nix +++ b/modules/nixos/nginx/upstream.nix @@ -40,6 +40,10 @@ let type = str; default = "default"; }; + getAddressFor = mkOption { + type = str; + default = "getAddressFor"; + }; network = mkOption { type = str; default = "lan"; @@ -61,7 +65,7 @@ let enable = lib.warnIf (!port.enable) "${cfg.system}.exports.services.${cfg.name}.ports.${cfg.port} isn't enabled" ( mkAlmostOptionDefault port.enable ); - addr = mkAlmostOptionDefault (access.getAddressFor system.name cfg.network); + addr = mkAlmostOptionDefault (access.${cfg.getAddressFor} system.name cfg.network); port = mkOptionDefault port.port; ssl.enable = mkIf port.ssl (mkAlmostOptionDefault true); }; diff --git a/modules/system/exports/deluge.nix b/modules/system/exports/deluge.nix new file mode 100644 index 00000000..8c20b812 --- /dev/null +++ b/modules/system/exports/deluge.nix @@ -0,0 +1,46 @@ +{ + lib, + gensokyo-zone, + ... +}: let + inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault; + inherit (lib.modules) mkIf; + inherit (lib.attrsets) mapAttrs; +in { + config.exports.services.deluge = {config, ...}: { + nixos = { + serviceAttr = "deluge"; + assertions = let + mkAssertion = f: nixosConfig: let + cfg = nixosConfig.services.deluge; + in + f nixosConfig cfg; + in + mkIf config.enable [ + (mkAssertion (nixosConfig: cfg: { + assertion = config.ports.default.port == cfg.config.daemon_port; + message = "config.daemon_port mismatch"; + })) + (mkAssertion (nixosConfig: cfg: { + assertion = config.ports.web.port == cfg.web.port; + message = "web.port mismatch"; + })) + (mkAssertion (nixosConfig: cfg: { + assertion = config.ports.web.enable == cfg.web.enable; + message = "web.enable mismatch"; + })) + ]; + }; + defaults.port.listen = mkAlmostOptionDefault "lan"; + ports = mapAttrs (_: mapAlmostOptionDefaults) { + default = { + port = 58846; + transport = "tcp"; + }; + web = { + port = 8112; + protocol = "http"; + }; + }; + }; +} diff --git a/nixos/access/deluge.nix b/nixos/access/deluge.nix new file mode 100644 index 00000000..40e03d12 --- /dev/null +++ b/nixos/access/deluge.nix @@ -0,0 +1,88 @@ +{ + config, + lib, + ... +}: let + inherit (lib.modules) mkIf mkDefault mkOptionDefault; + inherit (config.services) nginx; + cfg = config.services.deluge; + upstreamName = "deluge'access"; + upstreamName'daemon = "deluge'daemon'access"; + locations."/".proxy.enable = true; + name.shortServer = mkDefault "deluge"; + copyFromVhost = mkDefault "deluge"; +in { + config.services.nginx = { + upstreams'.${upstreamName}.servers = { + local = mkIf (cfg.enable && cfg.web.enable) { + enable = mkDefault true; + addr = mkDefault "127.0.0.1"; + port = mkDefault cfg.web.port; + }; + access = {upstream, ...}: { + enable = mkDefault (!upstream.servers.local.enable or false); + accessService = { + name = "deluge"; + port = "web"; + getAddressFor = mkDefault "getAddress4For"; + }; + }; + }; + virtualHosts = { + deluge = { + inherit name locations; + ssl.force = mkDefault true; + proxy.upstream = mkDefault upstreamName; + vouch.enable = mkDefault true; + }; + deluge'local = { + inherit name locations; + ssl = { + force = mkDefault true; + cert = { + inherit copyFromVhost; + }; + }; + local.enable = true; + proxy = { + inherit copyFromVhost; + }; + }; + }; + stream = { + upstreams.${upstreamName'daemon} = { + enable = mkDefault (!cfg.enable); + servers = { + local = mkIf cfg.enable { + enable = mkDefault true; + addr = mkDefault "127.0.0.1"; + port = mkDefault cfg.config.daemon_port; + }; + access = {upstream, ...}: { + enable = mkDefault (!upstream.servers.local.enable or false); + accessService = { + name = "deluge"; + getAddressFor = mkDefault "getAddress4For"; + }; + }; + }; + }; + servers.deluge'local = {config, ...}: let + upstream = nginx.stream.upstreams.${config.proxy.upstream}; + in { + enable = mkDefault upstream.enable; + listen.daemon.port = mkOptionDefault upstream.servers.${upstream.defaultServerName}.port; + local.enable = true; + proxy.upstream = mkDefault upstreamName'daemon; + }; + }; + }; + config.networking.firewall = let + daemonServer = nginx.stream.servers.deluge'local; + in + mkIf daemonServer.enable { + interfaces.local.allowedTCPPorts = [ + daemonServer.listen.daemon.port + ]; + }; +} diff --git a/nixos/deluge.nix b/nixos/deluge.nix index 21b32ddc..58c6c4ce 100644 --- a/nixos/deluge.nix +++ b/nixos/deluge.nix @@ -70,4 +70,11 @@ in { ${mediatomb.user}.extraGroups = [cfg.group]; }) ]); + + networking.firewall = mkIf cfg.enable { + interfaces.lan.allowedTCPPorts = [ + cfg.config.daemon_port + (mkIf cfg.web.enable cfg.web.port) + ]; + }; } diff --git a/systems/hakurei/nixos.nix b/systems/hakurei/nixos.nix index c1f24c41..cdb6e29a 100644 --- a/systems/hakurei/nixos.nix +++ b/systems/hakurei/nixos.nix @@ -39,6 +39,7 @@ in { nixos.access.unifi nixos.access.kitchencam nixos.access.openwebrx + nixos.access.deluge nixos.access.home-assistant nixos.access.zigbee2mqtt nixos.access.grocy @@ -219,6 +220,14 @@ in { virtualHosts.openwebrx'local.allServerNames ]; }; + deluge = { + inherit (nginx) group; + domain = virtualHosts.deluge.serverName; + extraDomainNames = mkMerge [ + virtualHosts.deluge.otherServerNames + virtualHosts.deluge'local.allServerNames + ]; + }; yt = { inherit (nginx) group; domain = virtualHosts.invidious.serverName; @@ -308,6 +317,7 @@ in { }; kitchencam.ssl.cert.enable = true; openwebrx.ssl.cert.enable = true; + deluge.ssl.cert.enable = true; invidious = { ssl.cert.enable = true; }; diff --git a/systems/mediabox/cloudflared.nix b/systems/mediabox/cloudflared.nix index 8b91fb8f..a774f543 100644 --- a/systems/mediabox/cloudflared.nix +++ b/systems/mediabox/cloudflared.nix @@ -1,5 +1,11 @@ -{config, ...}: let - inherit (config.services) deluge tautulli ombi sonarr radarr bazarr lidarr readarr prowlarr cloudflared; +{ + config, + lib, + ... +}: let + inherit (config.services) nginx tautulli ombi sonarr radarr bazarr lidarr readarr prowlarr cloudflared; + inherit (lib.modules) mkMerge; + inherit (lib.attrsets) mapAttrs' nameValuePair; in { sops.secrets.cloudflare_mediabox_tunnel = { owner = cloudflared.user; @@ -7,22 +13,29 @@ in { services.cloudflared = let tunnelId = "6a3c1863-d879-462f-b5d5-7c6ddf476d0e"; - inherit (config.networking) domain; + ingressPorts = { + tautulli = tautulli.port; + ombi = ombi.port; + sonarr = sonarr.port; + radarr = radarr.port; + bazarr = bazarr.listenPort; + lidarr = lidarr.port; + readarr = readarr.port; + prowlarr = prowlarr.port; + }; + ingress = mapAttrs' (name: port: + nameValuePair "${name}.${config.networking.domain}" { + service = "http://localhost:${toString port}"; + }) + ingressPorts; in { tunnels.${tunnelId} = { default = "http_status:404"; credentialsFile = config.sops.secrets.cloudflare_mediabox_tunnel.path; - ingress = { - "tautulli.${domain}".service = "http://localhost:${toString tautulli.port}"; - "ombi.${domain}".service = "http://localhost:${toString ombi.port}"; - "sonarr.${domain}".service = "http://localhost:${toString sonarr.port}"; - "radarr.${domain}".service = "http://localhost:${toString radarr.port}"; - "bazarr.${domain}".service = "http://localhost:${toString bazarr.listenPort}"; - "lidarr.${domain}".service = "http://localhost:${toString lidarr.port}"; - "readarr.${domain}".service = "http://localhost:${toString readarr.port}"; - "prowlarr.${domain}".service = "http://localhost:${toString prowlarr.port}"; - "deluge.${domain}".service = "http://localhost:${toString deluge.web.port}"; - }; + ingress = mkMerge [ + ingress + (nginx.virtualHosts.deluge.proxied.cloudflared.getIngress {}) + ]; }; }; } diff --git a/systems/mediabox/default.nix b/systems/mediabox/default.nix index ca7a5a85..b1cb3cab 100644 --- a/systems/mediabox/default.nix +++ b/systems/mediabox/default.nix @@ -10,9 +10,13 @@ _: { exports = { services = { sshd.enable = true; - nginx.enable = true; + nginx = { + enable = true; + ports.proxied.enable = true; + }; plex.enable = true; invidious.enable = true; + deluge.enable = true; }; }; } diff --git a/systems/mediabox/nixos.nix b/systems/mediabox/nixos.nix index 510bf507..41f67702 100644 --- a/systems/mediabox/nixos.nix +++ b/systems/mediabox/nixos.nix @@ -24,6 +24,7 @@ in { nixos.sops nixos.nginx nixos.access.plex + nixos.access.deluge nixos.cloudflared ./cloudflared.nix @@ -45,6 +46,14 @@ in { nixos.prowlarr ]; + services.nginx = { + proxied.enable = true; + vouch.enable = true; + virtualHosts = { + deluge.proxied.enable = "cloudflared"; + }; + }; + services.mediatomb = { serverName = "tewi"; mediaDirectories = let diff --git a/tf/cloudflare_records.tf b/tf/cloudflare_records.tf index 61f1f6e8..419231e7 100644 --- a/tf/cloudflare_records.tf +++ b/tf/cloudflare_records.tf @@ -24,6 +24,7 @@ module "hakurei_system_records" { "mqtt", "kitchen", "webrx", + "deluge", "home", "z2m", "grocy",