diff --git a/flake.nix b/flake.nix index 353369c..4db3fd1 100644 --- a/flake.nix +++ b/flake.nix @@ -33,6 +33,7 @@ kmonad.nixosModules.default agenix.nixosModule home-manager.nixosModules.home-manager + self.nixosModules.flood { nixpkgs.overlays = [ nur.overlay agenix.overlay ]; } ]; }; @@ -64,6 +65,8 @@ }; }; + nixosModules.flood = import ./modules/flood.nix; + packages.x86_64-linux = { install-iso = nixos-generators.nixosGenerate { system = "x86_64-linux"; diff --git a/hosts/servers/alexandria/default.nix b/hosts/servers/alexandria/default.nix index ac9cfa5..ca67997 100644 --- a/hosts/servers/alexandria/default.nix +++ b/hosts/servers/alexandria/default.nix @@ -3,7 +3,6 @@ { imports = [ ./hardware-configuration.nix - ./hosted-services.nix ./security.nix ./users.nix ./services diff --git a/hosts/servers/alexandria/security.nix b/hosts/servers/alexandria/security.nix index 9235215..1add949 100644 --- a/hosts/servers/alexandria/security.nix +++ b/hosts/servers/alexandria/security.nix @@ -1,10 +1,10 @@ -{ config, pkgs, libs, ... }: +{ specialArgs, inputs, config, pkgs, lib, ... }: { age.secrets.cloudflare-creds = { - file = ../../../secrets/cloudflare-creds.age; - owner = "nginx"; - group = "hosted"; + file = ../../../secrets/cloudflare-creds.age; + owner = "nginx"; + group = "hosted"; }; security.acme = { diff --git a/hosts/servers/alexandria/services/arr.nix b/hosts/servers/alexandria/services/arr.nix new file mode 100644 index 0000000..d307ccd --- /dev/null +++ b/hosts/servers/alexandria/services/arr.nix @@ -0,0 +1,60 @@ +{ specialArgs, inputs, config, pkgs, lib, ... }: + +{ + services = { + transmission = { + enable = true; + group = "hosted"; + settings = { + download-dir = "/data/torrent_storage/completed"; + incomplete-dir = "/data/torrent_storage/incomplete"; + incomplete-dir-enabled = true; + rpc-authentication-required = false; + rpc-host-whitelist-enabled = true; + rpc-whitelist-enabled = true; + peer-port = 57298; + speed-limit-down = 5000; + speed-limit-down-enabled = true; + speed-limit-up = 500; + speed-limit-up-enabled = true; + alt-speed-down = 5000; + alt-speed-enabled = false; + alt-speed-time-begin = 240; + alt-speed-time-day = 127; + alt-speed-time-enabled = true; + alt-speed-time-end = 480; + alt-speed-up = 1500; + utp-enabled = false; + }; + }; + + flood = { + enable = true; + user = "transmission"; + group = "hosted"; + port = "${config.ports.flood}"; + }; + + jellyfin = { + enable = true; + group = "hosted"; + }; + + radarr = { + enable = true; + group = "hosted"; + }; + + sonarr = { + enable = true; + group = "hosted"; + }; + + bazarr = { + enable = true; + group = "hosted"; + }; + + prowlarr.enable = true; + }; +} diff --git a/hosts/servers/alexandria/services/containerised.nix b/hosts/servers/alexandria/services/containerised.nix index 4e7e4c5..56f1585 100644 --- a/hosts/servers/alexandria/services/containerised.nix +++ b/hosts/servers/alexandria/services/containerised.nix @@ -1,4 +1,4 @@ -{ inputs, config, pkgs, libs, ... }: +{ specialArgs, inputs, config, pkgs, lib, ... }: { virtualisation = { @@ -9,7 +9,7 @@ "cinny" = { image = "ghcr.io/cinnyapp/cinny:latest"; ports = [ - "8002:80" + "${config.ports.cinny}:80" ]; extraOptions = [ "--pull=always" @@ -21,7 +21,7 @@ TZ = "Europe/Berlin"; }; ports = [ - "8003:80" + "${config.ports.librespeed}:80" ]; extraOptions = [ "--pull=always" @@ -41,7 +41,7 @@ "/data/syncthing/notes:/sync/notes" ]; ports = [ - "8006:8384" + "${config.ports.syncthing}:8384" "22000:22000" "21027:21027/udp" ]; @@ -60,7 +60,7 @@ WHOOGLE_CONFIG_GET_ONLY = "1"; }; ports = [ - "8007:5000" + "${config.ports.whoogle}:5000" ]; extraOptions = [ "--pull=always" diff --git a/hosts/servers/alexandria/services/default.nix b/hosts/servers/alexandria/services/default.nix index aa9b96c..e674e9e 100644 --- a/hosts/servers/alexandria/services/default.nix +++ b/hosts/servers/alexandria/services/default.nix @@ -1,13 +1,11 @@ { ... }: -let - N8N_PORT = "5678"; - BAZAAR_PORT = "6767"; -in - { imports = [ - ./nginx.nix ./containerised.nix + ./variables.nix + ./utility.nix + ./nginx.nix + ./arr.nix ]; } diff --git a/hosts/servers/alexandria/services/gaming.nix b/hosts/servers/alexandria/services/gaming.nix new file mode 100644 index 0000000..35cd7d7 --- /dev/null +++ b/hosts/servers/alexandria/services/gaming.nix @@ -0,0 +1,17 @@ +{ specialArgs, inputs, config, pkgs, lib, ... }: + +{ + services.minecraft-server = { + enable = true; + eula = true; + declarative = true; + openFirewall = true; + package = pkgs.papermc; + serverProperties = { + motd = "Bem-vindo a Alexandria"; + difficulty = "hard"; + gamemode = "survival"; + }; + dataDir = "/data/minecraft"; + }; +} diff --git a/hosts/servers/alexandria/services/nginx.nix b/hosts/servers/alexandria/services/nginx.nix index b8b308a..6051304 100644 --- a/hosts/servers/alexandria/services/nginx.nix +++ b/hosts/servers/alexandria/services/nginx.nix @@ -1,4 +1,4 @@ -{ inputs, config, pkgs, libs, ... }: +{ specialArgs, inputs, config, pkgs, lib, ... }: { services.nginx = { @@ -8,26 +8,23 @@ recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; - virtualHosts = let - useACMEHost = "baduhai.me"; - forceSSL = true; - kTLS = true; - in { - "baduhai.me".root = inputs.homepage; - "bazarr.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:6767"; - "bitwarden.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}"; - "cinny.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:8002"; - "detect.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:${toString config.services.changedetection-io.port}"; - "jellyfin.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:8096"; - "librespeed.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:8003"; - "n8n.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:${N8N_PORT}"; - "paperless.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:${toString config.services.paperless.port}"; - "prowlarr.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:9696"; - "radarr.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:7878"; - "shiori.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:${toString config.services.shiori.port}"; - "sonarr.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:8989"; - "sync.baduhai.me"locations."/".proxyPass = "http://127.0.0.1:8006"; - "whoogle.baduhai.me".locations."/".proxyPass = "http://127.0.0.1:8007"; + virtualHosts = { + "baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; root = inputs.homepage; }; + "bazarr.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.bazaar}"; }; + "bitwarden.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.vaultwarden}"; }; + "cinny.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.cinny}"; }; + "detect.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.changedetection-io}"; }; + "flood.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.flood}"; }; + "jellyfin.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.jellyfin}"; }; + "librespeed.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.librespeed}"; }; + "n8n.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.n8n}"; }; + "paperless.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.paperless}"; }; + "prowlarr.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.prowlarr}"; }; + "radarr.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.radarr}"; }; + "shiori.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.shiori}"; }; + "sonarr.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.sonarr}"; }; + "sync.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.syncthing}"; }; + "whoogle.baduhai.me" = { useACMEHost = "baduhai.me"; forceSSL = true; kTLS = true; locations."/".proxyPass = "http://127.0.0.1:${config.ports.whoogle}"; }; }; }; } diff --git a/hosts/servers/alexandria/hosted-services.nix b/hosts/servers/alexandria/services/utility.nix similarity index 55% rename from hosts/servers/alexandria/hosted-services.nix rename to hosts/servers/alexandria/services/utility.nix index 0bdfc18..a8df073 100644 --- a/hosts/servers/alexandria/hosted-services.nix +++ b/hosts/servers/alexandria/services/utility.nix @@ -1,4 +1,4 @@ -{ inputs, config, pkgs, libs, ... }: +{ specialArgs, inputs, config, pkgs, lib, ... }: { age.secrets = { @@ -16,7 +16,7 @@ DOMAIN = "https://bitwarden.baduhai.me"; SIGNUPS_ALLOWED = false; ROCKET_ADDRESS = "127.0.0.1"; - ROCKET_PORT = 8000; + ROCKET_PORT = "${config.ports.vaultwarden}"; }; }; @@ -25,21 +25,16 @@ group = "hosted"; behindProxy = true; datastorePath = "/data/changedetection"; - port = 8001; + port = "${config.ports.changedetection-io}"; baseURL = "https://detect.baduhai.me"; }; - jellyfin = { - enable = true; - group = "hosted"; - }; - paperless = { enable = true; dataDir = "/data/paperless/data"; mediaDir = "/data/paperless/media"; passwordFile = config.age.secrets.paperless-pass.path; - port = 8004; + port = "${config.ports.paperless}"; consumptionDirIsPublic = true; extraConfig = { PAPERLESS_OCR_LANGUAGE = "eng+por+deu"; @@ -48,40 +43,9 @@ shiori = { enable = true; - port = 8005; + port = "${config.ports.shiori}"; }; - radarr = { - enable = true; - group = "hosted"; - }; - - sonarr = { - enable = true; - group = "hosted"; - }; - - bazarr = { - enable = true; - group = "hosted"; - }; - - prowlarr.enable = true; - n8n.enable = true; - - minecraft-server = { - enable = true; - eula = true; - declarative = true; - openFirewall = true; - package = pkgs.papermc; - serverProperties = { - motd = "Bem-vindo a Alexandria"; - difficulty = "hard"; - gamemode = "survival"; - }; - dataDir = "/data/minecraft"; - }; }; } diff --git a/hosts/servers/alexandria/services/variables.nix b/hosts/servers/alexandria/services/variables.nix new file mode 100644 index 0000000..637294d --- /dev/null +++ b/hosts/servers/alexandria/services/variables.nix @@ -0,0 +1,28 @@ +{ specialArgs, inputs, config, pkgs, lib, ... }: + +let + mkStringOption = default: lib.mkOption { + inherit default; + type = lib.types.str; + }; +in + +{ + options.ports = { + n8n = mkStringOption "5678"; + bazaar = mkStringOption "6767"; + radarr = mkStringOption "7878"; + vaultwarden = mkStringOption "8000"; + changedetection-io = mkStringOption "8001"; + cinny = mkStringOption "8002"; + librespeed = mkStringOption "8003"; + paperless = mkStringOption "8004"; + shiori = mkStringOption "8005"; + syncthing = mkStringOption "8006"; + jellyfin = mkStringOption "8096"; + whoogle = mkStringOption "8007"; + flood = mkStringOption "8008"; + sonarr = mkStringOption "8989"; + prowlarr = mkStringOption "9696"; + }; +} diff --git a/hosts/servers/alexandria/users.nix b/hosts/servers/alexandria/users.nix index 971d114..9be4033 100644 --- a/hosts/servers/alexandria/users.nix +++ b/hosts/servers/alexandria/users.nix @@ -1,4 +1,4 @@ -{ inputs, config, pkgs, libs, ... }: +{ specialArgs, inputs, config, pkgs, lib, ... }: { users = { diff --git a/modules/flood.nix b/modules/flood.nix new file mode 100644 index 0000000..7505aed --- /dev/null +++ b/modules/flood.nix @@ -0,0 +1,91 @@ +{ config, pkgs, lib, ... }: +with lib; +let cfg = config.services.flood; +in { + options = { + services.flood = { + enable = mkEnableOption (lib.mdDoc "Flood"); + + runDir = mkOption { + type = types.str; + default = "/var/lib/flood"; + }; + + port = mkOption { + type = types.port; + default = 3030; + description = '' + The port for the Flood web interface + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Open ports in the firewall for the Flood web interface + ''; + }; + + user = mkOption { + type = types.str; + default = "flood"; + description = lib.mdDoc "User account under which Flood runs."; + }; + + group = mkOption { + type = types.str; + default = "flood"; + description = lib.mdDoc "Group under which Flood runs."; + }; + + package = mkOption { + type = types.package; + default = pkgs.flood; + defaultText = literalExpression "pkgs.flood"; + description = lib.mdDoc '' + Flood package to use. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.tmpfiles.rules = + [ "d '${cfg.runDir}' 0700 ${cfg.user} ${cfg.group} - -" ]; + + systemd.services.flood = { + enable = true; + description = "Flood torrent UI"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "simple"; + ExecStart = lib.concatStringsSep " " [ + "${pkgs.flood}/bin/flood" + "--port ${toString cfg.port}" + "--host 0.0.0.0" + "--rundir ${cfg.runDir}" + ]; + User = cfg.user; + Group = cfg.group; + Restart = "on-failure"; + }; + }; + + networking.firewall = + mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + + users.users = mkIf (cfg.user == "flood") { + flood = { + group = cfg.group; + home = cfg.runDir; + uid = config.ids.uids.flood; + }; + }; + + users.groups = + mkIf (cfg.group == "flood") { flood.gid = config.ids.gids.flood; }; + }; +}