From 909f531fd7b8c975d433beade514438555a992cb Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 27 Nov 2025 17:17:13 -0600 Subject: [PATCH] feat: got port forwarding working --- modules/nixos/guests/torrent/default.nix | 121 +++++++++++++---------- 1 file changed, 68 insertions(+), 53 deletions(-) diff --git a/modules/nixos/guests/torrent/default.nix b/modules/nixos/guests/torrent/default.nix index b58f8c4..682a133 100755 --- a/modules/nixos/guests/torrent/default.nix +++ b/modules/nixos/guests/torrent/default.nix @@ -30,56 +30,6 @@ in # Disable default firewall - we're doing it manually firewall.enable = false; - # Configure iptables killswitch at boot, before any services - localCommands = '' - # Default DROP everything - ${pkgs.iptables}/bin/iptables -P INPUT DROP - ${pkgs.iptables}/bin/iptables -P OUTPUT DROP - ${pkgs.iptables}/bin/iptables -P FORWARD DROP - - # Flush existing rules - ${pkgs.iptables}/bin/iptables -F - ${pkgs.iptables}/bin/iptables -t nat -F - ${pkgs.iptables}/bin/iptables -X - - # Allow loopback - ${pkgs.iptables}/bin/iptables -A INPUT -i lo -j ACCEPT - ${pkgs.iptables}/bin/iptables -A OUTPUT -o lo -j ACCEPT - - # Allow established/related connections on VPN interface only - ${pkgs.iptables}/bin/iptables -A INPUT -i wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - ${pkgs.iptables}/bin/iptables -A OUTPUT -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - - # Allow established/related connections on local network (for management) - ${pkgs.iptables}/bin/iptables -A INPUT -i enp0s5 -s ${localNet} -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -d ${localNet} -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - - # Allow SSH on all interfaces (for management) - ${pkgs.iptables}/bin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT - ${pkgs.iptables}/bin/iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - - # Allow local network for management (WebUI, etc) - NEW connections - ${pkgs.iptables}/bin/iptables -A INPUT -i enp0s5 -s ${localNet} -j ACCEPT - ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -d ${localNet} -j ACCEPT - - # CRITICAL: Only allow WireGuard endpoint before VPN is up - ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -p udp --dport ${toString torrentPort} -d ${vpnEndpoint} -j ACCEPT - ${pkgs.iptables}/bin/iptables -A INPUT -i enp0s5 -p udp --sport ${toString torrentPort} -s ${vpnEndpoint} -j ACCEPT - - # DNS: Only allow through VPN gateway (10.2.0.1) - no local DNS leaks - # This rule will only work once WireGuard is up - # If you need DNS before VPN for WireGuard hostname resolution, uncomment below: - # ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -p udp --dport 53 -d 192.168.50.1 -j ACCEPT - - # Block IPv6 completely (defense in depth, even though we disabled it) - ${pkgs.iptables}/bin/ip6tables -P INPUT DROP 2>/dev/null || true - ${pkgs.iptables}/bin/ip6tables -P OUTPUT DROP 2>/dev/null || true - ${pkgs.iptables}/bin/ip6tables -P FORWARD DROP 2>/dev/null || true - - # Log dropped packets (optional, for debugging - comment out in production) - ${pkgs.iptables}/bin/iptables -A OUTPUT -j LOG --log-prefix "KILLSWITCH-OUT: " --log-level 4 - ${pkgs.iptables}/bin/iptables -A INPUT -j LOG --log-prefix "KILLSWITCH-IN: " --log-level 4 - ''; wg-quick.interfaces = { wg0 = { address = [ "10.2.0.2/32" ]; @@ -100,25 +50,44 @@ in # Now we can safely open the VPN tunnel for all traffic postUp = '' - # Allow all traffic through VPN interface + echo "VPN UP: Opening network for VPN and local traffic" + + # Allow ALL traffic through VPN interface ${pkgs.iptables}/bin/iptables -A INPUT -i wg0 -j ACCEPT ${pkgs.iptables}/bin/iptables -A OUTPUT -o wg0 -j ACCEPT + # Allow local network traffic (WebUI, management) + ${pkgs.iptables}/bin/iptables -A INPUT -i enp0s5 -s ${localNet} -j ACCEPT + ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -d ${localNet} -j ACCEPT + # NAT for VPN ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE - # Allow forwarding through VPN + # Allow forwarding through VPN (for port forwarding) ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT ${pkgs.iptables}/bin/iptables -A FORWARD -o wg0 -j ACCEPT + ${pkgs.iptables}/bin/iptables -A FORWARD -i enp0s5 -o wg0 -j ACCEPT + ${pkgs.iptables}/bin/iptables -A FORWARD -o enp0s5 -i wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + + echo "VPN UP: Network opened for VPN and local traffic" ''; preDown = '' - # Remove VPN-specific rules (killswitch rules stay!) + echo "VPN DOWN: Removing VPN rules, killswitch remains active" ${pkgs.iptables}/bin/iptables -D INPUT -i wg0 -j ACCEPT 2>/dev/null || true ${pkgs.iptables}/bin/iptables -D OUTPUT -o wg0 -j ACCEPT 2>/dev/null || true + + ${pkgs.iptables}/bin/iptables -D INPUT -i enp0s5 -s ${localNet} -j ACCEPT 2>/dev/null || true + ${pkgs.iptables}/bin/iptables -D OUTPUT -o enp0s5 -d ${localNet} -j ACCEPT 2>/dev/null || true + ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE 2>/dev/null || true + ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT 2>/dev/null || true ${pkgs.iptables}/bin/iptables -D FORWARD -o wg0 -j ACCEPT 2>/dev/null || true + ${pkgs.iptables}/bin/iptables -D FORWARD -i enp0s5 -o wg0 -j ACCEPT 2>/dev/null || true + ${pkgs.iptables}/bin/iptables -D FORWARD -o enp0s5 -i wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true + + echo "VPN DOWN: Killswitch rules remain - no internet access" ''; }; }; @@ -292,6 +261,52 @@ in done ''; }; + killswitch-init = { + description = "Initialize VPN Killswitch Before Network"; + wantedBy = [ "network-pre.target" ]; + before = [ + "network-pre.target" + "network.target" + ]; + after = [ "systemd-modules-load.service" ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = '' + echo "KILLSWITCH: Setting up firewall rules BEFORE network services" + + # Default DROP everything + ${pkgs.iptables}/bin/iptables -P INPUT DROP + ${pkgs.iptables}/bin/iptables -P OUTPUT DROP + ${pkgs.iptables}/bin/iptables -P FORWARD DROP + + ${pkgs.iptables}/bin/iptables -F + ${pkgs.iptables}/bin/iptables -t nat -F + ${pkgs.iptables}/bin/iptables -X + + # Allow loopback + ${pkgs.iptables}/bin/iptables -A INPUT -i lo -j ACCEPT + ${pkgs.iptables}/bin/iptables -A OUTPUT -o lo -j ACCEPT + + # CRITICAL: Only allow WireGuard endpoint traffic before VPN is up + ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -p udp --dport ${toString torrentPort} -d ${vpnEndpoint} -j ACCEPT + ${pkgs.iptables}/bin/iptables -A INPUT -i enp0s5 -p udp --sport ${toString torrentPort} -s ${vpnEndpoint} -j ACCEPT + + # Allow SSH from local network (for management) + ${pkgs.iptables}/bin/iptables -A INPUT -i enp0s5 -s ${localNet} -p tcp --dport 22 -j ACCEPT + ${pkgs.iptables}/bin/iptables -A OUTPUT -o enp0s5 -d ${localNet} -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + + # Block IPv6 completely + ${pkgs.iptables}/bin/ip6tables -P INPUT DROP 2>/dev/null || true + ${pkgs.iptables}/bin/ip6tables -P OUTPUT DROP 2>/dev/null || true + ${pkgs.iptables}/bin/ip6tables -P FORWARD DROP 2>/dev/null || true + + echo "KILLSWITCH: Initialized - Network locked down" + ''; + }; }; };