summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--secrets/cifs-transmission.agebin0 -> 368 bytes
-rw-r--r--secrets/secrets.nix1
-rw-r--r--system/linde.nix118
3 files changed, 118 insertions, 1 deletions
diff --git a/secrets/cifs-transmission.age b/secrets/cifs-transmission.age
new file mode 100644
index 00000000..f17f7451
--- /dev/null
+++ b/secrets/cifs-transmission.age
Binary files differdiff --git a/secrets/secrets.nix b/secrets/secrets.nix
index 1c10148f..b60f6cc9 100644
--- a/secrets/secrets.nix
+++ b/secrets/secrets.nix
@@ -22,6 +22,7 @@ let
     photoprism = [ linde ];
     cifs-photoprism = [ linde ];
     cifs-paperless = [ linde ];
+    cifs-transmission = [ linde ];
   };
 in
 builtins.listToAttrs (
diff --git a/system/linde.nix b/system/linde.nix
index 458deb52..a2eae51f 100644
--- a/system/linde.nix
+++ b/system/linde.nix
@@ -47,6 +47,7 @@ in
     photoprism.file = ../secrets/photoprism.age;
     cifs-photoprism.file = ../secrets/cifs-photoprism.age;
     cifs-paperless.file = ../secrets/cifs-paperless.age;
+    cifs-transmission.file = ../secrets/cifs-transmission.age;
     golink = let golink = config.services.golink; in {
       # hope this doesn't collide...
       path = "${golink.dataDir}/.config/tsnet-golink/auth.key";
@@ -305,7 +306,7 @@ in
   };
   users.users.alan = {
     shell = "/run/current-system/sw/bin/fish";
-    extraGroups = [ "wheel" "caddy" "docker" "laminar" ];
+    extraGroups = [ "wheel" "caddy" "docker" "laminar" "transmission" ];
     isNormalUser = true;
     home = "/home/alan";
     createHome = true;
@@ -1086,4 +1087,119 @@ in
       "/srv/photoprism/sidecar"
     ];
   };
+
+  fileSystems."/srv/transmission" = {
+    device = "//u439959-sub4.your-storagebox.de/u439959-sub4";
+    fsType = "smb3";
+    options =
+      let
+        # prevents hanging on network split
+        automount_opts = [
+          "x-systemd.automount"
+          "noauto"
+          "x-systemd.idle-timeout=1h"
+          "x-systemd.mount-timeout=5s"
+        ];
+      in
+      automount_opts ++ [
+        "credentials=${config.age.secrets.cifs-transmission.path}"
+        "seal"
+        "multichannel"
+        "nobrl" # needed for sqlite
+        "forceuid"
+        "forcegid"
+        "uid=${toString config.ids.uids.transmission}"
+        "gid=${toString config.ids.gids.transmission}"
+      ];
+  };
+  containers.bt =
+    let
+      externalDir = "/srv/transmission";
+      localAddress6 = "fc00::9091";
+      tsHostname = "bt.${ts-domain}";
+      tsPort = 41643;
+      hostConfig = config;
+    in
+    {
+      autoStart = true;
+      # does TS need this?
+      enableTun = true;
+      privateNetwork = true;
+      hostAddress6 = "fc00::1";
+      inherit localAddress6;
+      forwardPorts = [{
+        hostPort = tsPort;
+      }];
+      bindMounts = {
+        ${config.services.transmission.home} = {
+          hostPath = hostConfig.services.transmission.home;
+          isReadOnly = false;
+        };
+        ${externalDir} = {
+          hostPath = externalDir;
+          isReadOnly = false;
+        };
+      };
+      config = { config, lib, pkgs, ... }: {
+        system.stateVersion = "24.11";
+        networking = {
+          useHostResolvConf = false;
+          resolvconf.enable = false;
+          firewall.trustedInterfaces = [ "tailscale0" ];
+          firewall.rejectPackets = true;
+          nameservers = hostConfig.networking.nameservers;
+        };
+        services.resolved = {
+          enable = true;
+          llmnr = "false";
+        };
+        services.tailscale = {
+          enable = true;
+          openFirewall = true;
+          permitCertUid = "caddy";
+          port = tsPort;
+        };
+        services.caddy = {
+          enable = true;
+          email = "caddy@alanpearce.eu";
+          virtualHosts = {
+            "http://" = {
+              hostName = "bt";
+              extraConfig = ''
+                redir ${tsHostname}{uri}
+              '';
+            };
+            ${tsHostname} = {
+              extraConfig = ''
+                encode zstd gzip
+                tls {
+                  get_certificate tailscale
+                }
+                reverse_proxy localhost:${toString config.services.transmission.settings.rpc-port}
+              '';
+            };
+          };
+        };
+        services.transmission = {
+          enable = true;
+          openFirewall = true;
+          webHome = pkgs.flood-for-transmission;
+          settings = {
+            utp-enabled = true;
+            incomplete-dir-enabled = false;
+            incomplete-dir = "/srv/transmission/leeching";
+            download-dir = "/srv/transmission/seeding";
+            rpc-bind-address = "::1";
+            rpc-whitelist-enabled = false;
+            rpc-host-whitelist = tsHostname;
+            rpc-host-whitelist-enabled = true;
+          };
+        };
+        systemd.services.transmission = {
+          serviceConfig = {
+            RootDirectory = lib.mkForce "";
+          };
+        };
+      };
+    };
 }