mirror of
				https://github.com/nmasur/dotfiles
				synced 2025-11-04 07:03:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
# Transmission is a bittorrent client, which can run in the background for
 | 
						|
# automated downloads with a web GUI.
 | 
						|
 | 
						|
{
 | 
						|
  config,
 | 
						|
  pkgs,
 | 
						|
  lib,
 | 
						|
  ...
 | 
						|
}:
 | 
						|
 | 
						|
let
 | 
						|
  inherit (config.nmasur.settings) hostnames username;
 | 
						|
  cfg = config.nmasur.presets.services.transmission;
 | 
						|
in
 | 
						|
{
 | 
						|
 | 
						|
  options.nmasur.presets.services.transmission.enable =
 | 
						|
    lib.mkEnableOption "Transmission BitTorrent service";
 | 
						|
 | 
						|
  config =
 | 
						|
    let
 | 
						|
      namespace = config.networking.wireguard.interfaces.wg0.interfaceNamespace;
 | 
						|
      vpnIp = lib.strings.removeSuffix "/32" (
 | 
						|
        builtins.head config.networking.wireguard.interfaces.wg0.ips
 | 
						|
      );
 | 
						|
    in
 | 
						|
    lib.mkIf cfg.enable {
 | 
						|
 | 
						|
      # Setup transmission
 | 
						|
      services.transmission = {
 | 
						|
        enable = true;
 | 
						|
        settings = {
 | 
						|
          port-forwarding-enabled = false;
 | 
						|
          rpc-authentication-required = true;
 | 
						|
          rpc-port = 9091;
 | 
						|
          rpc-bind-address = "0.0.0.0";
 | 
						|
          rpc-username = username;
 | 
						|
          # This is a salted hash of the real password
 | 
						|
          # https://github.com/tomwijnroks/transmission-pwgen
 | 
						|
          rpc-password = "{c4c5145f6e18bcd3c7429214a832440a45285ce26jDOBGVW";
 | 
						|
          rpc-host-whitelist = hostnames.transmission;
 | 
						|
          rpc-host-whitelist-enabled = true;
 | 
						|
          rpc-whitelist = lib.mkDefault "127.0.0.1"; # Overwritten by Cloudflare
 | 
						|
          rpc-whitelist-enabled = true;
 | 
						|
        };
 | 
						|
      };
 | 
						|
 | 
						|
      # Configure Cloudflare DNS to point to this machine
 | 
						|
      services.cloudflare-dyndns.domains = [ hostnames.transmission ];
 | 
						|
 | 
						|
      # Bind transmission to wireguard namespace
 | 
						|
      systemd.services.transmission = lib.mkIf config.wireguard.enable {
 | 
						|
        bindsTo = [ "netns@${namespace}.service" ];
 | 
						|
        requires = [
 | 
						|
          "network-online.target"
 | 
						|
          "transmission-secret.service"
 | 
						|
        ];
 | 
						|
        after = [
 | 
						|
          "wireguard-wg0.service"
 | 
						|
          "transmission-secret.service"
 | 
						|
        ];
 | 
						|
        unitConfig.JoinsNamespaceOf = "netns@${namespace}.service";
 | 
						|
        serviceConfig.NetworkNamespacePath = "/var/run/netns/${namespace}";
 | 
						|
      };
 | 
						|
 | 
						|
      # Create reverse proxy for web UI
 | 
						|
      nmasur.presets.services.caddy.routes =
 | 
						|
        let
 | 
						|
          # Set if the download domain is the same as the Transmission domain
 | 
						|
          useDownloadDomain = hostnames.download == hostnames.transmission;
 | 
						|
        in
 | 
						|
        lib.mkAfter [
 | 
						|
          {
 | 
						|
            group = if useDownloadDomain then "download" else "transmission";
 | 
						|
            match = [
 | 
						|
              {
 | 
						|
                host = [ hostnames.transmission ];
 | 
						|
                path = if useDownloadDomain then [ "/transmission*" ] else null;
 | 
						|
              }
 | 
						|
            ];
 | 
						|
            handle = [
 | 
						|
              {
 | 
						|
                handler = "reverse_proxy";
 | 
						|
                upstreams = [
 | 
						|
                  { dial = "localhost:${builtins.toString config.services.transmission.settings.rpc-port}"; }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
            ];
 | 
						|
          }
 | 
						|
        ];
 | 
						|
 | 
						|
      # Caddy and Transmission both try to set rmem_max for larger UDP packets.
 | 
						|
      # We will choose Transmission's recommendation (4 MB).
 | 
						|
      boot.kernel.sysctl."net.core.rmem_max" = 4194304;
 | 
						|
 | 
						|
      # Allow inbound connections to reach namespace
 | 
						|
      systemd.services.transmission-web-netns = lib.mkIf config.wireguard.enable {
 | 
						|
        description = "Forward to transmission in wireguard namespace";
 | 
						|
        requires = [ "transmission.service" ];
 | 
						|
        after = [ "transmission.service" ];
 | 
						|
        serviceConfig = {
 | 
						|
          Restart = "on-failure";
 | 
						|
          TimeoutStopSec = 300;
 | 
						|
        };
 | 
						|
        wantedBy = [ "multi-user.target" ];
 | 
						|
        script = ''
 | 
						|
          ${pkgs.iproute2}/bin/ip netns exec ${namespace} ${pkgs.iproute2}/bin/ip link set dev lo up
 | 
						|
          ${pkgs.socat}/bin/socat tcp-listen:9091,fork,reuseaddr exec:'${pkgs.iproute2}/bin/ip netns exec ${namespace} ${pkgs.socat}/bin/socat STDIO "tcp-connect:${vpnIp}:9091"',nofork
 | 
						|
        '';
 | 
						|
      };
 | 
						|
    };
 | 
						|
}
 |