diff --git a/nixarr/audiobookshelf/default.nix b/nixarr/audiobookshelf/default.nix index 6c29895..d78ae3e 100644 --- a/nixarr/audiobookshelf/default.nix +++ b/nixarr/audiobookshelf/default.nix @@ -8,10 +8,6 @@ with lib; let cfg = config.nixarr.audiobookshelf; nixarr = config.nixarr; in { - imports = [ - ./shelf-module - ]; - options.nixarr.audiobookshelf = { enable = mkOption { type = types.bool; @@ -162,23 +158,54 @@ in { "d '${cfg.stateDir}' 0700 streamer root - -" # Media Dirs - "d '${nixarr.mediaDir}/library/books' 0775 streamer media - -" - "d '${nixarr.mediaDir}/library/podcasts' 0775 streamer media - -" + "d '${nixarr.mediaDir}/library/books' 0775 streamer media - -" + "d '${nixarr.mediaDir}/library/audio-books' 0775 streamer media - -" + "d '${nixarr.mediaDir}/library/podcasts' 0775 streamer media - -" ]; - # Always prioritise Audiobookshelf IO - systemd.services.audiobookshelf.serviceConfig.IOSchedulingPriority = 0; + systemd.services.audiobookshelf = { + description = "Audiobookshelf is a self-hosted audiobook and podcast server"; - util-nixarr.services.audiobookshelf = { - enable = cfg.enable; - package = cfg.package; - port = cfg.port; - user = "streamer"; - group = "media"; - openFirewall = cfg.openFirewall; - dataDir = cfg.stateDir; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + IOSchedulingPriority = 0; + Type = "simple"; + User = cfg.user; + Group = cfg.group; + StateDirectory = cfg.dataDir; + WorkingDirectory = cfg.dataDir; + ExecStart = "${cfg.package}/bin/audiobookshelf --host ${cfg.host} --port ${toString cfg.port}"; + Restart = "on-failure"; + + # Security + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + NoNewPrivileges = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + ProtectSystem = "strict"; + ReadWritePaths = [cfg.configDir]; + }; }; + users.users.audiobookshelf = { + isSystemUser = true; + group = cfg.group; + home = cfg.stateDir; + }; + users.groups.audiobookshelf = { }; + networking.firewall = mkIf cfg.expose.https.enable { allowedTCPPorts = [80 443]; }; diff --git a/nixarr/audiobookshelf/shelf-module/default.nix b/nixarr/audiobookshelf/shelf-module/default.nix deleted file mode 100644 index d420042..0000000 --- a/nixarr/audiobookshelf/shelf-module/default.nix +++ /dev/null @@ -1,91 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: - -with lib; - -let - cfg = config.util-nixarr.services.audiobookshelf; -in -{ - options.util-nixarr.services.audiobookshelf = { - enable = mkEnableOption "Audiobookshelf, self-hosted audiobook and podcast server"; - - package = mkPackageOption pkgs "audiobookshelf" { }; - - dataDir = mkOption { - description = "Path to Audiobookshelf config and metadata inside of /var/lib."; - default = "audiobookshelf"; - type = types.str; - }; - - host = mkOption { - description = "The host Audiobookshelf binds to."; - default = "127.0.0.1"; - example = "0.0.0.0"; - type = types.str; - }; - - port = mkOption { - description = "The TCP port Audiobookshelf will listen on."; - default = 8000; - type = types.port; - }; - - user = mkOption { - description = "User account under which Audiobookshelf runs."; - default = "audiobookshelf"; - type = types.str; - }; - - group = mkOption { - description = "Group under which Audiobookshelf runs."; - default = "audiobookshelf"; - type = types.str; - }; - - openFirewall = mkOption { - description = "Open ports in the firewall for the Audiobookshelf web interface."; - default = false; - type = types.bool; - }; - }; - - config = mkIf cfg.enable { - systemd.services.audiobookshelf = { - description = "Audiobookshelf is a self-hosted audiobook and podcast server"; - - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - Type = "simple"; - User = cfg.user; - Group = cfg.group; - StateDirectory = cfg.dataDir; - WorkingDirectory = cfg.dataDir; - ExecStart = "${cfg.package}/bin/audiobookshelf --host ${cfg.host} --port ${toString cfg.port}"; - Restart = "on-failure"; - }; - }; - - users.users = mkIf (cfg.user == "audiobookshelf") { - audiobookshelf = { - isSystemUser = true; - group = cfg.group; - home = "/var/lib/${cfg.dataDir}"; - }; - }; - - users.groups = mkIf (cfg.group == "audiobookshelf") { - audiobookshelf = { }; - }; - - networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [ cfg.port ]; - }; - }; -} diff --git a/nixarr/bazarr/bazarr-module/default.nix b/nixarr/bazarr/bazarr-module/default.nix deleted file mode 100644 index 319c62b..0000000 --- a/nixarr/bazarr/bazarr-module/default.nix +++ /dev/null @@ -1,88 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -with lib; let - cfg = config.util-nixarr.services.bazarr; -in { - options = { - util-nixarr.services.bazarr = { - enable = mkEnableOption "bazarr, a subtitle manager for Sonarr and Radarr"; - - package = mkPackageOption pkgs "bazarr" {}; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = "Open ports in the firewall for the bazarr web interface."; - }; - - listenPort = mkOption { - type = types.port; - default = 6767; - description = "Port on which the bazarr web interface should listen"; - }; - - dataDir = mkOption { - type = types.path; - default = "/var/lib/bazarr"; - description = "State directory for bazarr"; - }; - - user = mkOption { - type = types.str; - default = "bazarr"; - description = "User account under which bazarr runs."; - }; - - group = mkOption { - type = types.str; - default = "bazarr"; - description = "Group under which bazarr runs."; - }; - }; - }; - - config = mkIf cfg.enable { - systemd.tmpfiles.rules = [ - "d '${cfg.dataDir}' 0700 bazarr root - -" - ]; - - systemd.services.bazarr = { - description = "bazarr"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - - serviceConfig = { - Type = "simple"; - User = cfg.user; - Group = cfg.group; - SyslogIdentifier = "bazarr"; - ExecStart = pkgs.writeShellScript "start-bazarr" '' - ${pkgs.bazarr}/bin/bazarr \ - --config '${cfg.dataDir}' \ - --port ${toString cfg.listenPort} \ - --no-update True - ''; - Restart = "on-failure"; - }; - }; - - networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [cfg.listenPort]; - }; - - users.users = mkIf (cfg.user == "bazarr") { - bazarr = { - isSystemUser = true; - group = cfg.group; - }; - }; - - users.groups = mkIf (cfg.group == "bazarr") { - bazarr = {}; - }; - }; -} diff --git a/nixarr/bazarr/default.nix b/nixarr/bazarr/default.nix index 308bfd6..2b5adb4 100644 --- a/nixarr/bazarr/default.nix +++ b/nixarr/bazarr/default.nix @@ -6,12 +6,9 @@ }: with lib; let cfg = config.nixarr.bazarr; + port = 6767; nixarr = config.nixarr; in { - imports = [ - ./bazarr-module - ]; - options.nixarr.bazarr = { enable = mkOption { type = types.bool; @@ -24,6 +21,12 @@ in { package = mkPackageOption pkgs "bazarr" {}; + port = mkOption { + type = types.port; + default = port; + description = "Port for Bazarr to use."; + }; + stateDir = mkOption { type = types.path; default = "${nixarr.stateDir}/bazarr"; @@ -74,15 +77,40 @@ in { } ]; - util-nixarr.services.bazarr = { - enable = cfg.enable; - package = cfg.package; - user = "bazarr"; - group = "media"; - openFirewall = cfg.openFirewall; - dataDir = cfg.stateDir; + systemd.tmpfiles.rules = [ + "d '${cfg.dataDir}' 0700 bazarr root - -" + ]; + + systemd.services.bazarr = { + description = "bazarr"; + after = ["network.target"]; + wantedBy = ["multi-user.target"]; + + serviceConfig = { + Type = "simple"; + User = "bazarr"; + Group = "media"; + SyslogIdentifier = "bazarr"; + ExecStart = pkgs.writeShellScript "start-bazarr" '' + ${pkgs.bazarr}/bin/bazarr \ + --config '${cfg.stateDir}' \ + --port ${toString cfg.port} \ + --no-update True + ''; + Restart = "on-failure"; + }; }; + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = [cfg.listenPort]; + }; + + users.users.bazarr = { + isSystemUser = true; + group = "media"; + }; + users.groups.bazarr = {}; + # Enable and specify VPN namespace to confine service in. systemd.services.bazarr.vpnConfinement = mkIf cfg.vpn.enable { enable = true; @@ -90,12 +118,11 @@ in { }; # Port mappings - # TODO: openports vpnNamespaces.wg = mkIf cfg.vpn.enable { portMappings = [ { - from = config.bazarr.listenPort; - to = config.bazarr.listenPort; + from = cfg.port; + to = cfg.port; } ]; }; @@ -107,17 +134,17 @@ in { recommendedOptimisation = true; recommendedGzipSettings = true; - virtualHosts."127.0.0.1:${builtins.toString config.bazarr.listenPort}" = { + virtualHosts."127.0.0.1:${builtins.toString cfg.port}" = { listen = [ { addr = "0.0.0.0"; - port = config.bazarr.listenPort; + port = cfg.port; } ]; locations."/" = { recommendedProxySettings = true; proxyWebsockets = true; - proxyPass = "http://192.168.15.1:${builtins.toString config.bazarr.listenPort}"; + proxyPass = "http://192.168.15.1:${builtins.toString cfg.port}"; }; }; }; diff --git a/nixarr/jellyseerr/default.nix b/nixarr/jellyseerr/default.nix index 24bcf29..73d74f1 100644 --- a/nixarr/jellyseerr/default.nix +++ b/nixarr/jellyseerr/default.nix @@ -7,12 +7,8 @@ with lib; let cfg = config.nixarr.jellyseerr; nixarr = config.nixarr; - defaultPort = 5055; + port = 5055; in { - imports = [ - ./jellyseerr-module - ]; - options.nixarr.jellyseerr = { enable = mkOption { type = types.bool; @@ -46,7 +42,7 @@ in { port = mkOption { type = types.port; - default = defaultPort; + default = port; example = 12345; description = "Jellyseerr web-UI port."; }; @@ -146,12 +142,58 @@ in { } ]; - util-nixarr.services.jellyseerr = { - enable = true; - package = cfg.package; - openFirewall = cfg.openFirewall; - port = cfg.port; - configDir = cfg.stateDir; + systemd.tmpfiles.rules = [ + "d '${cfg.configDir}' 0700 ${cfg.user} ${cfg.group} - -" + ]; + + systemd.services.jellyseerr = { + description = "Jellyseerr, a requests manager for Jellyfin"; + after = ["network.target"]; + wantedBy = ["multi-user.target"]; + environment = { + PORT = toString cfg.port; + CONFIG_DIRECTORY = cfg.configDir; + }; + + serviceConfig = { + Type = "exec"; + StateDirectory = "jellyseerr"; + DynamicUser = false; + User = cfg.user; + Group = cfg.group; + ExecStart = lib.getExe cfg.package; + Restart = "on-failure"; + + # Security + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + NoNewPrivileges = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + ProtectSystem = "strict"; + ReadWritePaths = [cfg.configDir]; + }; + }; + + users.users = mkIf (cfg.user == "jellyseerr") { + jellyseerr = { + group = cfg.group; + home = cfg.configDir; + uid = 294; + }; + }; + + users.groups = mkIf (cfg.group == "jellyseerr") { + jellyseerr = {}; }; networking.firewall = mkIf cfg.expose.https.enable { @@ -178,22 +220,22 @@ in { locations."/" = { recommendedProxySettings = true; proxyWebsockets = true; - proxyPass = "http://127.0.0.1:${builtins.toString defaultPort}"; + proxyPass = "http://127.0.0.1:${builtins.toString cfg.port}"; }; }; }) (mkIf cfg.vpn.enable { - virtualHosts."127.0.0.1:${builtins.toString defaultPort}" = { + virtualHosts."127.0.0.1:${builtins.toString cfg.port}" = { listen = [ { addr = "0.0.0.0"; - port = defaultPort; + port = cfg.port; } ]; locations."/" = { recommendedProxySettings = true; proxyWebsockets = true; - proxyPass = "http://192.168.15.1:${builtins.toString defaultPort}"; + proxyPass = "http://192.168.15.1:${builtins.toString cfg.port}"; }; }; }) @@ -214,8 +256,8 @@ in { vpnNamespaces.wg = mkIf cfg.vpn.enable { portMappings = [ { - from = defaultPort; - to = defaultPort; + from = cfg.port; + to = cfg.port; } ]; }; diff --git a/nixarr/jellyseerr/jellyseerr-module/default.nix b/nixarr/jellyseerr/jellyseerr-module/default.nix deleted file mode 100644 index 80e96aa..0000000 --- a/nixarr/jellyseerr/jellyseerr-module/default.nix +++ /dev/null @@ -1,105 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -with lib; let - cfg = config.util-nixarr.services.jellyseerr; -in { - options = { - util-nixarr.services.jellyseerr = { - enable = mkEnableOption "Jellyseerr"; - - package = mkPackageOption pkgs "jellyseerr" {}; - - user = mkOption { - type = types.str; - default = "jellyseerr"; - description = "User account under which Jellyseerr runs."; - }; - - group = mkOption { - type = types.str; - default = "jellyseerr"; - description = "Group under which Jellyseerr runs."; - }; - - configDir = mkOption { - type = types.str; - default = "/var/lib/jellyseerr"; - description = "The directory where Jellyseerr stores its config data."; - }; - - port = lib.mkOption { - type = lib.types.port; - default = 5055; - description = ''The port which the Jellyseerr web UI should listen to.''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = "Open ports in the firewall for the Jellyseerr web interface."; - }; - }; - }; - - config = mkIf cfg.enable { - systemd.tmpfiles.rules = [ - "d '${cfg.configDir}' 0700 ${cfg.user} ${cfg.group} - -" - ]; - - systemd.services.jellyseerr = { - description = "Jellyseerr, a requests manager for Jellyfin"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - environment = { - PORT = toString cfg.port; - CONFIG_DIRECTORY = cfg.configDir; - }; - - serviceConfig = { - Type = "exec"; - StateDirectory = "jellyseerr"; - DynamicUser = false; - User = cfg.user; - Group = cfg.group; - ExecStart = lib.getExe cfg.package; - Restart = "on-failure"; - ProtectHome = true; - PrivateTmp = true; - PrivateDevices = true; - ProtectHostname = true; - ProtectClock = true; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectKernelLogs = true; - ProtectControlGroups = true; - NoNewPrivileges = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - RemoveIPC = true; - PrivateMounts = true; - ProtectSystem = "strict"; - ReadWritePaths = [cfg.configDir]; - }; - }; - - networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [5055]; - }; - - users.users = mkIf (cfg.user == "jellyseerr") { - jellyseerr = { - group = cfg.group; - home = cfg.configDir; - uid = 294; - }; - }; - - users.groups = mkIf (cfg.group == "jellyseerr") { - jellyseerr = {}; - }; - }; -} diff --git a/nixarr/lidarr/default.nix b/nixarr/lidarr/default.nix index 40377ec..358a47f 100644 --- a/nixarr/lidarr/default.nix +++ b/nixarr/lidarr/default.nix @@ -7,7 +7,7 @@ with lib; let cfg = config.nixarr.lidarr; nixarr = config.nixarr; - defaultPort = 8686; + port = 8686; in { options.nixarr.lidarr = { enable = mkOption { @@ -21,6 +21,12 @@ in { package = mkPackageOption pkgs "lidarr" {}; + port = mkOption { + type = types.port; + default = port; + description = "Port for Lidarr to use."; + }; + stateDir = mkOption { type = types.path; default = "${nixarr.stateDir}/lidarr"; @@ -76,6 +82,7 @@ in { package = cfg.package; user = "lidarr"; group = "media"; + settings.server.port = cfg.port; openFirewall = cfg.openFirewall; dataDir = cfg.stateDir; }; @@ -91,8 +98,8 @@ in { vpnNamespaces.wg = mkIf cfg.vpn.enable { portMappings = [ { - from = defaultPort; - to = defaultPort; + from = cfg.port; + to = cfg.port; } ]; }; @@ -104,17 +111,17 @@ in { recommendedOptimisation = true; recommendedGzipSettings = true; - virtualHosts."127.0.0.1:${builtins.toString defaultPort}" = { + virtualHosts."127.0.0.1:${builtins.toString cfg.port}" = { listen = [ { addr = "0.0.0.0"; - port = defaultPort; + port = cfg.port; } ]; locations."/" = { recommendedProxySettings = true; proxyWebsockets = true; - proxyPass = "http://192.168.15.1:${builtins.toString defaultPort}"; + proxyPass = "http://192.168.15.1:${builtins.toString cfg.port}"; }; }; }; diff --git a/nixarr/radarr/default.nix b/nixarr/radarr/default.nix index 939b116..817a4c5 100644 --- a/nixarr/radarr/default.nix +++ b/nixarr/radarr/default.nix @@ -6,7 +6,7 @@ }: with lib; let cfg = config.nixarr.radarr; - defaultPort = 7878; + port = 7878; nixarr = config.nixarr; in { options.nixarr.radarr = { @@ -21,6 +21,12 @@ in { package = mkPackageOption pkgs "radarr" {}; + port = mkOption { + type = types.port; + default = port; + description = "Port for Radarr to use."; + }; + stateDir = mkOption { type = types.path; default = "${nixarr.stateDir}/radarr"; @@ -76,6 +82,7 @@ in { package = cfg.package; user = "radarr"; group = "media"; + settings.server.port = cfg.port; openFirewall = cfg.openFirewall; dataDir = cfg.stateDir; }; @@ -90,8 +97,8 @@ in { vpnNamespaces.wg = mkIf cfg.vpn.enable { portMappings = [ { - from = defaultPort; - to = defaultPort; + from = cfg.port; + to = cfg.port; } ]; }; @@ -103,17 +110,17 @@ in { recommendedOptimisation = true; recommendedGzipSettings = true; - virtualHosts."127.0.0.1:${builtins.toString defaultPort}" = { + virtualHosts."127.0.0.1:${builtins.toString cfg.port}" = { listen = [ { addr = "0.0.0.0"; - port = defaultPort; + port = cfg.port; } ]; locations."/" = { recommendedProxySettings = true; proxyWebsockets = true; - proxyPass = "http://192.168.15.1:${builtins.toString defaultPort}"; + proxyPass = "http://192.168.15.1:${builtins.toString cfg.port}"; }; }; }; diff --git a/nixarr/readarr/readarr-module/default.nix b/nixarr/readarr/readarr-module/default.nix deleted file mode 100644 index 3933ec0..0000000 --- a/nixarr/readarr/readarr-module/default.nix +++ /dev/null @@ -1,93 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -let - cfg = config.services.readarr; - servarr = import ./settings-options.nix { inherit lib pkgs; }; -in -{ - options = { - services.readarr = { - enable = lib.mkEnableOption "Readarr, a Usenet/BitTorrent ebook downloader"; - - dataDir = lib.mkOption { - type = lib.types.str; - default = "/var/lib/readarr/"; - description = "The directory where Readarr stores its data files."; - }; - - package = lib.mkPackageOption pkgs "readarr" { }; - - openFirewall = lib.mkOption { - type = lib.types.bool; - default = false; - description = '' - Open ports in the firewall for Readarr - ''; - }; - - settings = servarr.mkServarrSettingsOptions "readarr" 8787; - - environmentFiles = servarr.mkServarrEnvironmentFiles "readarr"; - - user = lib.mkOption { - type = lib.types.str; - default = "readarr"; - description = '' - User account under which Readarr runs. - ''; - }; - - group = lib.mkOption { - type = lib.types.str; - default = "readarr"; - description = '' - Group under which Readarr runs. - ''; - }; - }; - }; - - config = lib.mkIf cfg.enable { - systemd.tmpfiles.settings."10-readarr".${cfg.dataDir}.d = { - inherit (cfg) user group; - mode = "0700"; - }; - - systemd.services.readarr = { - description = "Readarr"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - environment = servarr.mkServarrSettingsEnvVars "READARR" cfg.settings; - - serviceConfig = { - Type = "simple"; - User = cfg.user; - Group = cfg.group; - EnvironmentFile = cfg.environmentFiles; - ExecStart = "${cfg.package}/bin/Readarr -nobrowser -data='${cfg.dataDir}'"; - Restart = "on-failure"; - }; - }; - - networking.firewall = lib.mkIf cfg.openFirewall { - allowedTCPPorts = [ cfg.settings.server.port ]; - }; - - users.users = lib.mkIf (cfg.user == "readarr") { - readarr = { - description = "Readarr service"; - home = cfg.dataDir; - group = cfg.group; - isSystemUser = true; - }; - }; - - users.groups = lib.mkIf (cfg.group == "readarr") { - readarr = { }; - }; - }; -}