diff --git a/flake.lock b/flake.lock index f6f57d3..1a27e68 100644 --- a/flake.lock +++ b/flake.lock @@ -138,7 +138,8 @@ "inputs": { "agenix": "agenix", "nixpkgs": "nixpkgs_2", - "unifi-os-server": "unifi-os-server" + "unifi-os-server": "unifi-os-server", + "vpn-confinement": "vpn-confinement" } }, "systems": { @@ -189,6 +190,21 @@ "repo": "unifi-os-server", "type": "github" } + }, + "vpn-confinement": { + "locked": { + "lastModified": 1784582736, + "narHash": "sha256-a3V/LkUvwbN30QlCwPjNQq88TGOXiqXAzcYTSWgYIp4=", + "owner": "Maroka-chan", + "repo": "VPN-Confinement", + "rev": "bd17046da0262f3a93524845982825fa2ed23f40", + "type": "github" + }, + "original": { + "owner": "Maroka-chan", + "repo": "VPN-Confinement", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 6b1c958..df40e15 100644 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,7 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; agenix.url = "github:ryantm/agenix"; unifi-os-server.url = "github:rcambrj/unifi-os-server"; + vpn-confinement.url = "github:Maroka-chan/VPN-Confinement"; }; outputs = { @@ -12,6 +13,7 @@ nixpkgs, agenix, unifi-os-server, + vpn-confinement, ... } @ inputs: { nixosConfigurations.Hermes = nixpkgs.lib.nixosSystem { @@ -24,6 +26,7 @@ ./modules/system agenix.nixosModules.default unifi-os-server.nixosModules.unifi-os-server + vpn-confinement.nixosModules.default ]; }; }; diff --git a/modules/services/default.nix b/modules/services/default.nix index da5d7f5..44bd10d 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -4,6 +4,7 @@ ... }: { imports = [ + ./transmission.nix ./vaultwarden.nix ./navidrome.nix ./caddy.nix diff --git a/modules/services/transmission.nix b/modules/services/transmission.nix new file mode 100644 index 0000000..129088b --- /dev/null +++ b/modules/services/transmission.nix @@ -0,0 +1,59 @@ +{ + pkgs, + lib, + config, + inputs, + ... +}: { + # Define VPN network namespace + vpnNamespaces.wg0 = { + enable = true; + wireguardConfigFile = "${config.age.secrets.wg0.path}"; + accessibleFrom = [ + "10.0.0.0/24" + ]; + portMappings = [ + { + from = 9091; + to = 9091; + } + ]; + openVPNPorts = [ + { + port = 51413; + protocol = "both"; + } + ]; + }; + + systemd.services.transmission = { + vpnConfinement = { + enable = true; + vpnNamespace = "wg0"; + }; + + wants = ["wg0.service"]; + after = ["wg0.service"]; + partOf = ["wg0.service"]; + serviceConfig = { + Restart = "always"; + RestartSec = 5; + }; + }; + + services.transmission = { + enable = true; + settings = { + "rpc-bind-address" = "0.0.0.0"; # Bind RPC/WebUI to VPN network namespace address + "rpc-whitelist-enabled" = false; + "rpc-whitelist" = "10.0.0.*,127.0.0.1"; + download-dir = "/mnt/media/downloads"; + incomplete-dir-enabled = false; + }; + }; + + age.secrets.wg0 = { + file = ../../secrets/wg0.age; + path = "/run/secrets/wg0.conf"; + }; +} diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 83cfa0b..ae81f40 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -11,4 +11,5 @@ in { "gitea-runner.age".publicKeys = systems; "navidrome.age".publicKeys = systems; "vaultwarden.age".publicKeys = systems; + "wg0.age".publicKeys = systems; } diff --git a/secrets/wg0.age b/secrets/wg0.age new file mode 100644 index 0000000..9b0e956 Binary files /dev/null and b/secrets/wg0.age differ