diff --git a/hosts/sobotka/server.nix b/hosts/sobotka/server.nix index 70e7bb5e..d8f5acf3 100644 --- a/hosts/sobotka/server.nix +++ b/hosts/sobotka/server.nix @@ -28,5 +28,11 @@ credentialsFile = config.age.secrets.vaultwardenCloudflared.path; }; }; + deluge.enable = true; + wireguard-netns = { + enable = true; + namespace = "vpn"; + configFile = config.age.secrets.wireguardCredentials.path; + }; }; } diff --git a/modules/default.nix b/modules/default.nix index fa9b6cd0..a3aeca93 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -126,6 +126,8 @@ ./server/vaultwarden ./server/prowlarr ./server/lidarr + ./server/deluge + ./server/wireguard-netns ]; }; settings = { diff --git a/modules/nixos/services/agenix/default.nix b/modules/nixos/services/agenix/default.nix index 74f22a64..a6598565 100644 --- a/modules/nixos/services/agenix/default.nix +++ b/modules/nixos/services/agenix/default.nix @@ -60,6 +60,7 @@ in { cloudflareFirewallApiKey.file = "${self}/secrets/cloudflareFirewallApiKey.age"; cloudflareDnsApiToken.file = "${self}/secrets/cloudflareDnsApiToken.age"; cloudflareDnsCredentials.file = "${self}/secrets/cloudflareDnsCredentials.age"; + wgCredentials.file = "${self}/secrets/wgCredentials.age"; vaultwardenCloudflared.file = "${self}/secrets/vaultwardenCloudflared.age"; vaultwarden-env.file = "${self}/secrets/vaultwarden-env.age"; homepage-env.file = "${self}/secrets/homepage-env.age"; diff --git a/modules/server/deluge/default.nix b/modules/server/deluge/default.nix index 9c3673fb..15f14c46 100644 --- a/modules/server/deluge/default.nix +++ b/modules/server/deluge/default.nix @@ -58,7 +58,7 @@ in { "network-online.target" "${ns}.service" ]; - services.deluged.serviceConfig.NetworkNamespacePath = ["/var/run/netns/${ns}"]; + services.deluged.serviceConfig.NetworkNamespacePath = "/var/run/netns/${ns}"; sockets."deluged-proxy" = { enable = true; description = "Socket for Proxy to Deluge WebUI"; diff --git a/modules/server/wireguard-netns/default.nix b/modules/server/wireguard-netns/default.nix new file mode 100644 index 00000000..1fe12422 --- /dev/null +++ b/modules/server/wireguard-netns/default.nix @@ -0,0 +1,60 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.server.wireguard-netns; +in { + options.server.wireguard-netns = { + enable = lib.mkEnableOption "Enable a network namespace with WireGuard VPN"; + configFile = lib.mkOption { + type = lib.types.path; + description = "Path to the WireGuard configuration file (e.g., mullvad.conf)"; + }; + namespace = lib.mkOption { + type = lib.types.str; + default = "vpn"; + description = "Name of the network namespace"; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services."netns@${cfg.namespace}" = { + description = "WireGuard VPN netns (${cfg.namespace})"; + after = ["network-online.target"]; + wantedBy = ["multi-user.target"]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = pkgs.writeShellScript "netns-${cfg.namespace}-setup" '' + set -eux + + CONFIG=${cfg.configFile} + NS=${cfg.namespace} + ADDR=$(awk -F' *= *' '/^Address/ { print $2 }' "$CONFIG") + DNS=$(awk -F' *= *' '/^DNS/ { print $2 }' "$CONFIG") + + # Clean up any existing netns + ip netns delete "$NS" 2>/dev/null || true + + ip netns add "$NS" + ip link add wg0 type wireguard + ip link set wg0 netns "$NS" + ip -n "$NS" addr add "$ADDR" dev wg0 + ip -n "$NS" link set wg0 up + ip netns exec "$NS" wg setconf wg0 "$CONFIG" + ip netns exec "$NS" ip link set lo up + ip netns exec "$NS" ip route add default dev wg0 + + # Set DNS + mkdir -p /etc/netns/"$NS" + echo "nameserver $DNS" > /etc/netns/"$NS"/resolv.conf + ''; + ExecStop = pkgs.writeShellScript "netns-${cfg.namespace}-teardown" '' + ip netns delete ${cfg.namespace} || true + ''; + }; + }; + }; +} diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 5f958d3c..b555e05c 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -17,4 +17,5 @@ in { "vaultwardenCloudflared.age".publicKeys = [cnst kima usobotka rsobotka]; "cloudflareDnsApiToken.age".publicKeys = [cnst kima usobotka rsobotka]; "cloudflareDnsCredentials.age".publicKeys = [cnst kima usobotka rsobotka]; + "wgCredentials.age".publicKeys = [cnst kima usobotka rsobotka]; } diff --git a/secrets/wgCredentials.age b/secrets/wgCredentials.age new file mode 100644 index 00000000..608b3adb Binary files /dev/null and b/secrets/wgCredentials.age differ