From cf3362a67b1377c262695db3648721c7dab1e01f Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 5 Mar 2024 01:21:44 +0100 Subject: [PATCH 1/6] Updating vpn submodule --- flake.lock | 30 +++++++++++++++--------------- nixarr/jellyfin/default.nix | 2 +- nixarr/lidarr/default.nix | 2 +- nixarr/nixarr.nix | 2 +- nixarr/openssh/default.nix | 2 +- nixarr/prowlarr/default.nix | 2 +- nixarr/radarr/default.nix | 2 +- nixarr/readarr/default.nix | 2 +- nixarr/sonarr/default.nix | 2 +- nixarr/transmission/default.nix | 4 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/flake.lock b/flake.lock index aab114d..129bc90 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ ] }, "locked": { - "lastModified": 1705332421, - "narHash": "sha256-USpGLPme1IuqG78JNqSaRabilwkCyHmVWY0M9vYyqEA=", + "lastModified": 1708939976, + "narHash": "sha256-O5+nFozxz2Vubpdl1YZtPrilcIXPcRAjqNdNE8oCRoA=", "owner": "numtide", "repo": "devshell", - "rev": "83cb93d6d063ad290beee669f4badf9914cc16ec", + "rev": "5ddecd67edbd568ebe0a55905273e56cc82aabe3", "type": "github" }, "original": { @@ -28,11 +28,11 @@ ] }, "locked": { - "lastModified": 1706830856, - "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", + "lastModified": 1709336216, + "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", + "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", "type": "github" }, "original": { @@ -76,11 +76,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1708501555, - "narHash": "sha256-zJaF0RkdIPbh8LTmnpW/E7tZYpqIE+MePzlWwUNob4c=", + "lastModified": 1709386671, + "narHash": "sha256-VPqfBnIJ+cfa78pd4Y5Cr6sOWVW8GYHRVucxJGmRf8Q=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b50a77c03d640716296021ad58950b1bb0345799", + "rev": "fa9a51752f1b5de583ad5213eb621be071806663", "type": "github" }, "original": { @@ -122,11 +122,11 @@ ] }, "locked": { - "lastModified": 1708335038, - "narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=", + "lastModified": 1709546977, + "narHash": "sha256-R0bi8zAWt1s1q7lSvwiFI8+kEL29rm4WtYTqPgjlEBs=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65", + "rev": "e7a277c5d12bf570efa2427d9cfdb760b9a0512f", "type": "github" }, "original": { @@ -142,11 +142,11 @@ ] }, "locked": { - "lastModified": 1709159289, - "narHash": "sha256-66eFi/SgygAMOLLLkH5oqwBiI4iE5Bj/kBJmmMhX8fg=", + "lastModified": 1709597689, + "narHash": "sha256-6pSgM6s2Rm2zAA/dYKAOK7wLNkzox5hBKOC5E5TJoO8=", "owner": "Maroka-chan", "repo": "VPN-Confinement", - "rev": "93804a1050d3699418f0f9472e9c5eca1aa8153d", + "rev": "2f5fffe81305e731593b1923acdf1c7653f1b17c", "type": "github" }, "original": { diff --git a/nixarr/jellyfin/default.nix b/nixarr/jellyfin/default.nix index d92f888..9a0f079 100644 --- a/nixarr/jellyfin/default.nix +++ b/nixarr/jellyfin/default.nix @@ -244,7 +244,7 @@ in with lib; { # Port mappings # TODO: openports if expose.vpn vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; }; } diff --git a/nixarr/lidarr/default.nix b/nixarr/lidarr/default.nix index 2b7cd73..adbeb4a 100644 --- a/nixarr/lidarr/default.nix +++ b/nixarr/lidarr/default.nix @@ -61,7 +61,7 @@ in { # Port mappings # TODO: openports vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; services.nginx = mkIf cfg.vpn.enable { diff --git a/nixarr/nixarr.nix b/nixarr/nixarr.nix index a142222..1519abe 100644 --- a/nixarr/nixarr.nix +++ b/nixarr/nixarr.nix @@ -226,7 +226,7 @@ in { ./dnsleaktest.sh '' + (if cfg.vpn.vpnTestService.port != null then '' echo "starting netcat on port ${builtins.toString cfg.vpn.vpnTestService.port}:" - nc -vnlpu ${builtins.toString cfg.vpn.vpnTestService.port} + nc -vnlp ${builtins.toString cfg.vpn.vpnTestService.port} '' else ""); }; in "${vpn-test}/bin/vpn-test"; diff --git a/nixarr/openssh/default.nix b/nixarr/openssh/default.nix index 126782e..5e737ce 100644 --- a/nixarr/openssh/default.nix +++ b/nixarr/openssh/default.nix @@ -85,7 +85,7 @@ in { # Port mappings # TODO: openports vpnnamespaces.wg = { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; }; } diff --git a/nixarr/prowlarr/default.nix b/nixarr/prowlarr/default.nix index a0fa1e5..6d2ac0e 100644 --- a/nixarr/prowlarr/default.nix +++ b/nixarr/prowlarr/default.nix @@ -64,7 +64,7 @@ in { # Port mappings vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; services.nginx = mkIf cfg.vpn.enable { diff --git a/nixarr/radarr/default.nix b/nixarr/radarr/default.nix index ebfa84d..3e6827e 100644 --- a/nixarr/radarr/default.nix +++ b/nixarr/radarr/default.nix @@ -62,7 +62,7 @@ in { # Port mappings vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; services.nginx = mkIf cfg.vpn.enable { diff --git a/nixarr/readarr/default.nix b/nixarr/readarr/default.nix index 243ddbb..e5258fe 100644 --- a/nixarr/readarr/default.nix +++ b/nixarr/readarr/default.nix @@ -60,7 +60,7 @@ in { # Port mappings vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; services.nginx = mkIf cfg.vpn.enable { diff --git a/nixarr/sonarr/default.nix b/nixarr/sonarr/default.nix index e7bb4ee..73cc144 100644 --- a/nixarr/sonarr/default.nix +++ b/nixarr/sonarr/default.nix @@ -66,7 +66,7 @@ in { # Port mappings vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; }; services.nginx = mkIf cfg.vpn.enable { diff --git a/nixarr/transmission/default.nix b/nixarr/transmission/default.nix index 5c03d15..aafa578 100644 --- a/nixarr/transmission/default.nix +++ b/nixarr/transmission/default.nix @@ -337,8 +337,8 @@ in { # Port mappings # TODO: open peerPort vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = cfg.uiPort; To = cfg.uiPort; }]; - #openUdpPorts = [cfg.peerPort]; + portMappings = [{ from = cfg.uiPort; to = cfg.uiPort; }]; + openVPNPorts = [{ port = 24745; protocol = "both"; }]; #openTcpPorts = [cfg.peerPort]; }; From 17866268eff538a242e3b4f6ca06b02a1a1ac032 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 7 Mar 2024 09:54:17 +0100 Subject: [PATCH 2/6] Added tools to manage hard linking --- nixarr/nixarr.nix | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/nixarr/nixarr.nix b/nixarr/nixarr.nix index 1519abe..87799af 100644 --- a/nixarr/nixarr.nix +++ b/nixarr/nixarr.nix @@ -6,6 +6,14 @@ }: with lib; let cfg = config.nixarr; + list-unlinked = pkgs.writeShellApplication { + name = "list-unlinked"; + runtimeInputs = with pkgs; [util-linux]; + text = '' + find "$1" -type f -links 1 -exec du -h {} + | sort -h + ''; + }; + in { imports = [ ./jellyfin @@ -56,6 +64,15 @@ in { ''; }; + mediaUsers = mkOption { + type = with types; listOf str; + default = []; + example = [ "user" ]; + description = '' + Extra users to add to the media group. + ''; + }; + mediaDir = mkOption { type = types.path; default = "/data/media"; @@ -147,7 +164,7 @@ in { ]; users.groups = { - media = {}; + media.members = cfg.mediaUsers; streamer = {}; torrenter = {}; }; @@ -180,6 +197,11 @@ in { "d '${cfg.mediaDir}/torrents/readarr' 0755 torrenter media - -" ]; + environment.systemPackages = with pkgs; [ + jdupes + list-unlinked + ]; + # TODO: wtf to do about openports vpnnamespaces.wg = { enable = cfg.vpn.enable ; From bca4dc559034a9acaf35b3dcf729e18afc555a3a Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Sun, 10 Mar 2024 14:51:24 +0100 Subject: [PATCH 3/6] Testing vpn-test-service --- nixarr/nixarr.nix | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nixarr/nixarr.nix b/nixarr/nixarr.nix index 87799af..09e2377 100644 --- a/nixarr/nixarr.nix +++ b/nixarr/nixarr.nix @@ -256,11 +256,6 @@ in { bindsTo = ["netns@wg.service"]; requires = ["network-online.target"]; after = ["wg.service"]; - serviceConfig = { - #User = "torrenter"; - NetworkNamespacePath = "/var/run/netns/wg"; - BindReadOnlyPaths = ["/etc/netns/wg/resolv.conf:/etc/resolv.conf:norbind" "/data/test.file:/etc/test.file:norbind"]; - }; }; }; } From 31ed200f7ea4c2db1962fded213e489168a2b4e8 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 12 Mar 2024 09:15:12 +0100 Subject: [PATCH 4/6] Updated vpn --- nixarr/ddns/default.nix | 163 ++++++++++++++++++++++---------- nixarr/jellyfin/default.nix | 5 +- nixarr/nixarr.nix | 12 ++- nixarr/openssh/default.nix | 4 +- nixarr/transmission/default.nix | 8 +- 5 files changed, 133 insertions(+), 59 deletions(-) diff --git a/nixarr/ddns/default.nix b/nixarr/ddns/default.nix index bb4a75c..bfe70e5 100644 --- a/nixarr/ddns/default.nix +++ b/nixarr/ddns/default.nix @@ -6,9 +6,66 @@ }: with lib; let cfg = config.nixarr.ddns; + ddns-njalla = pkgs.writeShellApplication { + name = "ddns-njalla"; + + runtimeInputs = with pkgs; [ curl jq ]; + + # Thanks chatgpt... + text = '' + # Path to the JSON file + json_file="${cfg.njalla.keysFile}" + + # Convert the JSON object into a series of tab-separated key-value pairs using jq + # - `to_entries[]`: Convert the object into an array of key-value pairs. + # - `[.key, .value]`: For each pair, create an array containing the key and the value. + # - `@tsv`: Convert the array to a tab-separated string. + # The output will be a series of lines, each containing a key and a value separated by a tab. + jq_command='to_entries[] | [.key, .value] | @tsv' + + # Read the converted output line by line + # - `IFS=$'\t'`: Use the tab character as the field separator. + # - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator. + while IFS=$'\t' read -r key val; do + # For each key-value pair, execute the curl command + # Replace `''${key}` and `''${val}` in the URL with the actual key and value. + curl -s "https://njal.la/update/?h=''${key}&k=''${val}&auto" + done < <(jq -r "$jq_command" "$json_file") + ''; + }; in { options.nixarr.ddns = { njalla = { + vpn = { + enable = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + **Required options:** + + - [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile) + - [`nixarr.vpn.enable`](#nixarr.vpn.enable) + + Whether or not to enable DDNS over VPN for a + [Njalla](https://njal.la/) domain. Setting this will point to + the public ip of your VPN. Useful if you're running services + over VPN and want a domain that points to the corresponding ip. + + **Note:** You can enable both this and the regular njalla DDNS + service. + ''; + }; + + keysFile = mkOption { + type = with types; nullOr path; + default = null; + example = "/data/.secret/njalla/keys-file.json"; + description = '' + See [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile) + ''; + }; + }; enable = mkOption { type = types.bool; default = false; @@ -60,60 +117,70 @@ in { nixarr.ddns.njalla.keysFile option to be set, but it was not. ''; } + { + assertion = cfg.njalla.vpn.enable -> ( + cfg.njalla.vpn.keysFile != null && + nixarr.vpn.enable + ); + message = '' + The nixarr.ddns.njalla.enable option requires the + nixarr.vpn.enable option to be set, but it was not. + ''; + } ]; - systemd.timers = mkIf cfg.njalla.enable { - ddnsNjalla = { - description = "Timer for setting the Njalla DDNS records"; + systemd.timers = mkMerge [ + (mkIf cfg.njalla.enable { + ddnsNjalla = { + description = "Timer for setting the Njalla DDNS records"; - timerConfig = { - OnBootSec = "30"; # Run 30 seconds after system boot - OnCalendar = "hourly"; - Persistent = true; # Run service immediately if last window was missed - RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min - }; + timerConfig = { + OnBootSec = "30"; # Run 30 seconds after system boot + OnCalendar = "hourly"; + Persistent = true; # Run service immediately if last window was missed + RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min + }; - wantedBy = ["multi-user.target"]; - }; - }; + wantedBy = ["multi-user.target"]; + }; + }) + (mkIf cfg.njalla.vpn.enable { + ddnsNjallaVpn = { + description = "Timer for setting the Njalla DDNS records over VPN"; + + timerConfig = { + OnBootSec = "30"; # Run 30 seconds after system boot + OnCalendar = "hourly"; + Persistent = true; # Run service immediately if last window was missed + RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min + }; + + wantedBy = ["multi-user.target"]; + }; + }) + ]; - systemd.services = let - ddns-njalla = pkgs.writeShellApplication { - name = "ddns-njalla"; - - runtimeInputs = with pkgs; [ curl jq ]; - - # Thanks chatgpt... - text = '' - # Path to the JSON file - json_file="${cfg.njalla.keysFile}" - - # Convert the JSON object into a series of tab-separated key-value pairs using jq - # - `to_entries[]`: Convert the object into an array of key-value pairs. - # - `[.key, .value]`: For each pair, create an array containing the key and the value. - # - `@tsv`: Convert the array to a tab-separated string. - # The output will be a series of lines, each containing a key and a value separated by a tab. - jq_command='to_entries[] | [.key, .value] | @tsv' - - # Read the converted output line by line - # - `IFS=$'\t'`: Use the tab character as the field separator. - # - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator. - while IFS=$'\t' read -r key val; do - # For each key-value pair, execute the curl command - # Replace `''${key}` and `''${val}` in the URL with the actual key and value. - curl -s "https://njal.la/update/?h=''${key}&k=''${val}&auto" - done < <(jq -r "$jq_command" "$json_file") - ''; - }; - in mkIf cfg.njalla.enable { - ddnsNjalla = { - description = "Sets the Njalla DDNS records"; + systemd.services = mkMerge [ + (mkIf cfg.njalla.enable { + ddnsNjalla = { + description = "Sets the Njalla DDNS records"; - serviceConfig = { - ExecStart = getExe ddns-njalla; - Type = "oneshot"; + serviceConfig = { + ExecStart = getExe ddns-njalla; + Type = "oneshot"; + }; }; - }; - }; + }) + (mkIf cfg.njalla.vpn.enable { + ddnsNjallaVpn = { + description = "Sets the Njalla DDNS records over VPN"; + + serviceConfig = { + ExecStart = getExe ddns-njalla; + Type = "oneshot"; + }; + }; + }) + ]; }; } diff --git a/nixarr/jellyfin/default.nix b/nixarr/jellyfin/default.nix index 9a0f079..bb0e4fb 100644 --- a/nixarr/jellyfin/default.nix +++ b/nixarr/jellyfin/default.nix @@ -244,7 +244,10 @@ in with lib; { # Port mappings # TODO: openports if expose.vpn vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ from = defaultPort; to = defaultPort; }]; + portMappings = [{ From = defaultPort; To = defaultPort; }]; + openVPNPorts = optionalString cfg.expose.vpn.enable [ + { port = cfg.expose.vpn.port; protocol = "tcp"; } + ]; }; }; } diff --git a/nixarr/nixarr.nix b/nixarr/nixarr.nix index 09e2377..fd115c4 100644 --- a/nixarr/nixarr.nix +++ b/nixarr/nixarr.nix @@ -203,8 +203,11 @@ in { ]; # TODO: wtf to do about openports - vpnnamespaces.wg = { - enable = cfg.vpn.enable ; + vpnnamespaces.wg = mkIf cfg.vpn.enable { + enable = true; + openVPNPorts = optionalList cfg.vpn.vpnTestService.enable [ + { port = cfg.vpn.vpnTestService.port; protocol = "tcp"; } + ]; accessibleFrom = [ "192.168.1.0/24" "127.0.0.1" @@ -213,8 +216,9 @@ in { }; # TODO: openports - systemd.services.vpn-test-service = { - enable = cfg.vpn.vpnTestService.enable; + systemd.services.vpn-test-service = mkIf cfg.vpn.vpnTestService.enable { + enable = true; + vpnconfinement = { enable = true; vpnnamespace = "wg"; diff --git a/nixarr/openssh/default.nix b/nixarr/openssh/default.nix index 5e737ce..bdcac94 100644 --- a/nixarr/openssh/default.nix +++ b/nixarr/openssh/default.nix @@ -83,9 +83,9 @@ in { }; # Port mappings - # TODO: openports vpnnamespaces.wg = { - portMappings = [{ from = defaultPort; to = defaultPort; }]; + portMappings = [{ From = defaultPort; To = defaultPort; }]; + openVPNPorts = map (x: { port = x; protocol = "both"; }) services.openssh.ports; }; }; } diff --git a/nixarr/transmission/default.nix b/nixarr/transmission/default.nix index aafa578..d318c3d 100644 --- a/nixarr/transmission/default.nix +++ b/nixarr/transmission/default.nix @@ -335,11 +335,11 @@ in { }; # Port mappings - # TODO: open peerPort vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ from = cfg.uiPort; to = cfg.uiPort; }]; - openVPNPorts = [{ port = 24745; protocol = "both"; }]; - #openTcpPorts = [cfg.peerPort]; + portMappings = [{ From = cfg.uiPort; To = cfg.uiPort; }]; + openVPNPorts = [ + { port = cfg.peerPort; protocol = "both"; } + ]; }; services.nginx = mkIf cfg.vpn.enable { From ec656712e22e7351f1c06e0f901946cf8c35219a Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 12 Mar 2024 09:33:17 +0100 Subject: [PATCH 5/6] Added bazarr --- nixarr/bazarr/default.nix | 89 +++++++++++++++++++++++++++++++++++++++ nixarr/lidarr/default.nix | 1 + nixarr/nixarr.nix | 2 + 3 files changed, 92 insertions(+) create mode 100644 nixarr/bazarr/default.nix diff --git a/nixarr/bazarr/default.nix b/nixarr/bazarr/default.nix new file mode 100644 index 0000000..49293cb --- /dev/null +++ b/nixarr/bazarr/default.nix @@ -0,0 +1,89 @@ +{ + config, + lib, + ... +}: +with lib; let + cfg = config.nixarr.bazarr; + nixarr = config.nixarr; +in { + options.nixarr.bazarr = { + enable = mkEnableOption "the bazarr service."; + + stateDir = mkOption { + type = types.path; + default = "${nixarr.stateDir}/bazarr"; + defaultText = literalExpression ''"''${nixarr.stateDir}/bazarr"''; + example = "/home/user/.local/share/nixarr/bazarr"; + description = "The state directory for bazarr"; + }; + + vpn.enable = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + **Required options:** [`nixarr.vpn.enable`](#nixarr.vpn.enable) + + Route Bazarr traffic through the VPN. + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.vpn.enable -> nixarr.vpn.enable; + message = '' + The nixarr.bazarr.vpn.enable option requires the + nixarr.vpn.enable option to be set, but it was not. + ''; + } + ]; + + systemd.tmpfiles.rules = [ + "d '${cfg.stateDir}' 0700 bazarr root - -" + ]; + + services.bazarr = { + enable = cfg.enable; + user = "bazarr"; + group = "media"; + dataDir = cfg.stateDir; + }; + + # Enable and specify VPN namespace to confine service in. + systemd.services.bazarr.vpnconfinement = mkIf cfg.vpn.enable { + enable = true; + vpnnamespace = "wg"; + }; + + # Port mappings + # TODO: openports + vpnnamespaces.wg = mkIf cfg.vpn.enable { + portMappings = [{ from = config.bazarr.listenPort; to = config.bazarr.listenPort; }]; + }; + + services.nginx = mkIf cfg.vpn.enable { + enable = true; + + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + + virtualHosts."127.0.0.1:${builtins.toString config.bazarr.listenPort}" = { + listen = [ + { + addr = "0.0.0.0"; + port = config.bazarr.listenPort; + } + ]; + locations."/" = { + recommendedProxySettings = true; + proxyWebsockets = true; + proxyPass = "http://192.168.15.1:${builtins.toString config.bazarr.listenPort}"; + }; + }; + }; + }; +} diff --git a/nixarr/lidarr/default.nix b/nixarr/lidarr/default.nix index adbeb4a..caa768e 100644 --- a/nixarr/lidarr/default.nix +++ b/nixarr/lidarr/default.nix @@ -6,6 +6,7 @@ with lib; let cfg = config.nixarr.lidarr; nixarr = config.nixarr; + defaultPort = 8686; in { options.nixarr.lidarr = { enable = mkEnableOption "the Lidarr service."; diff --git a/nixarr/nixarr.nix b/nixarr/nixarr.nix index fd115c4..14d5372 100644 --- a/nixarr/nixarr.nix +++ b/nixarr/nixarr.nix @@ -17,6 +17,7 @@ with lib; let in { imports = [ ./jellyfin + ./bazarr ./ddns ./radarr ./lidarr @@ -53,6 +54,7 @@ in { The following services are supported: - [Jellyfin](#nixarr.jellyfin.enable) + - [Bazarr](#nixarr.bazarr.enable) - [Lidarr](#nixarr.lidarr.enable) - [Prowlarr](#nixarr.prowlarr.enable) - [Radarr](#nixarr.radarr.enable) From 39f6357a0afefbe60f365589c277d8311b9227b7 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 12 Mar 2024 17:28:21 +0100 Subject: [PATCH 6/6] Fixed bazarr and cross-seed --- nixarr/bazarr/bazarr-module/default.nix | 85 +++++++++++++++++++++++++ nixarr/bazarr/default.nix | 10 +-- nixarr/ddns/default.nix | 15 +++-- nixarr/jellyfin/default.nix | 9 +-- nixarr/nixarr.nix | 7 +- nixarr/transmission/default.nix | 15 ++--- 6 files changed, 115 insertions(+), 26 deletions(-) create mode 100644 nixarr/bazarr/bazarr-module/default.nix diff --git a/nixarr/bazarr/bazarr-module/default.nix b/nixarr/bazarr/bazarr-module/default.nix new file mode 100644 index 0000000..2ab8d40 --- /dev/null +++ b/nixarr/bazarr/bazarr-module/default.nix @@ -0,0 +1,85 @@ +{ 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"); + + 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 49293cb..128a78b 100644 --- a/nixarr/bazarr/default.nix +++ b/nixarr/bazarr/default.nix @@ -7,6 +7,10 @@ with lib; let cfg = config.nixarr.bazarr; nixarr = config.nixarr; in { + imports = [ + ./bazarr-module + ]; + options.nixarr.bazarr = { enable = mkEnableOption "the bazarr service."; @@ -41,11 +45,7 @@ in { } ]; - systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 bazarr root - -" - ]; - - services.bazarr = { + util-nixarr.services.bazarr = { enable = cfg.enable; user = "bazarr"; group = "media"; diff --git a/nixarr/ddns/default.nix b/nixarr/ddns/default.nix index bfe70e5..0a6235e 100644 --- a/nixarr/ddns/default.nix +++ b/nixarr/ddns/default.nix @@ -14,7 +14,7 @@ with lib; let # Thanks chatgpt... text = '' # Path to the JSON file - json_file="${cfg.njalla.keysFile}" + json_file="$1" # Convert the JSON object into a series of tab-separated key-value pairs using jq # - `to_entries[]`: Convert the object into an array of key-value pairs. @@ -120,7 +120,7 @@ in { { assertion = cfg.njalla.vpn.enable -> ( cfg.njalla.vpn.keysFile != null && - nixarr.vpn.enable + config.nixarr.vpn.enable ); message = '' The nixarr.ddns.njalla.enable option requires the @@ -166,17 +166,22 @@ in { description = "Sets the Njalla DDNS records"; serviceConfig = { - ExecStart = getExe ddns-njalla; + ExecStart = ''${getExe ddns-njalla} "${cfg.njalla.keysFile}"''; Type = "oneshot"; }; }; }) - (mkIf cfg.njalla.vpn.enable { + (mkIf (cfg.njalla.vpn.enable && config.nixarr.vpn.enable) { ddnsNjallaVpn = { description = "Sets the Njalla DDNS records over VPN"; + vpnconfinement = { + enable = true; + vpnnamespace = "wg"; + }; + serviceConfig = { - ExecStart = getExe ddns-njalla; + ExecStart = ''${getExe ddns-njalla} "${cfg.njalla.vpn.keysFile}"''; Type = "oneshot"; }; }; diff --git a/nixarr/jellyfin/default.nix b/nixarr/jellyfin/default.nix index bb0e4fb..0da0c93 100644 --- a/nixarr/jellyfin/default.nix +++ b/nixarr/jellyfin/default.nix @@ -244,10 +244,11 @@ in with lib; { # Port mappings # TODO: openports if expose.vpn vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = defaultPort; To = defaultPort; }]; - openVPNPorts = optionalString cfg.expose.vpn.enable [ - { port = cfg.expose.vpn.port; protocol = "tcp"; } - ]; + portMappings = [{ from = defaultPort; to = defaultPort; }]; + openVPNPorts = optional cfg.expose.vpn.enable { + port = cfg.expose.vpn.port; + protocol = "tcp"; + }; }; }; } diff --git a/nixarr/nixarr.nix b/nixarr/nixarr.nix index 14d5372..20f0521 100644 --- a/nixarr/nixarr.nix +++ b/nixarr/nixarr.nix @@ -207,9 +207,10 @@ in { # TODO: wtf to do about openports vpnnamespaces.wg = mkIf cfg.vpn.enable { enable = true; - openVPNPorts = optionalList cfg.vpn.vpnTestService.enable [ - { port = cfg.vpn.vpnTestService.port; protocol = "tcp"; } - ]; + openVPNPorts = optional cfg.vpn.vpnTestService.enable { + port = cfg.vpn.vpnTestService.port; + protocol = "tcp"; + }; accessibleFrom = [ "192.168.1.0/24" "127.0.0.1" diff --git a/nixarr/transmission/default.nix b/nixarr/transmission/default.nix index d318c3d..46bc728 100644 --- a/nixarr/transmission/default.nix +++ b/nixarr/transmission/default.nix @@ -224,19 +224,16 @@ in { ]; systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0700 torrenter root - -" + "d '${cfg.stateDir}' 0750 torrenter torrenter - -" # This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883) - "d '${cfg.stateDir}/.config/transmission-daemon' 0700 torrenter root - -" - ] ++ ( - if cfg-cross-seed.enable then - [ "d '${cfg-cross-seed.stateDir}' 0700 cross-seed root - -" ] - else [] - ); + "d '${cfg.stateDir}/.config/transmission-daemon' 0750 torrenter torrenter - -" + ] ++ optional cfg-cross-seed.enable + "d '${cfg-cross-seed.stateDir}' 0700 cross-seed root - -"; util-nixarr.services.cross-seed = mkIf cfg-cross-seed.enable { enable = true; dataDir = cfg-cross-seed.stateDir; - #group = "media"; + group = "torrenter"; settings = { torrentDir = "${nixarr.mediaDir}/torrents"; outputDir = "${nixarr.mediaDir}/torrents/.cross-seed"; @@ -336,7 +333,7 @@ in { # Port mappings vpnnamespaces.wg = mkIf cfg.vpn.enable { - portMappings = [{ From = cfg.uiPort; To = cfg.uiPort; }]; + portMappings = [{ from = cfg.uiPort; to = cfg.uiPort; }]; openVPNPorts = [ { port = cfg.peerPort; protocol = "both"; } ];