From e5f71257318a5d54ddf3c67e1a66278b6a8a2e22 Mon Sep 17 00:00:00 2001 From: Sergei Poljanski Date: Mon, 6 Apr 2026 02:11:52 +0300 Subject: [PATCH] tun2socks: replace per-app proxy hacks with transparent tunnel for all traffic --- modules/xray.nix | 83 ++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/modules/xray.nix b/modules/xray.nix index f4ef714..c570812 100644 --- a/modules/xray.nix +++ b/modules/xray.nix @@ -1,6 +1,9 @@ -# Xray VLESS+Reality proxy with system-wide proxy settings +# Xray VLESS+Reality with tun2socks transparent proxy (all traffic) { config, pkgs, lib, ... }: +let + xrayServer = "172.232.216.157"; +in { # Xray systemd service systemd.services.xray = { @@ -13,56 +16,54 @@ Restart = "on-failure"; RestartSec = 5; DynamicUser = true; - CapabilityBoundingSet = ""; NoNewPrivileges = true; ProtectSystem = "strict"; ReadOnlyPaths = [ "/etc/xray" ]; }; }; - # System-wide proxy environment variables - networking.proxy = { - default = "http://127.0.0.1:10809"; - noProxy = "127.0.0.1,localhost,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"; + # tun2socks — creates TUN device routing all traffic through SOCKS5 + systemd.services.tun2socks = { + description = "tun2socks transparent proxy"; + after = [ "xray.service" ]; + wants = [ "xray.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStartPre = pkgs.writeShellScript "tun2socks-setup" '' + ${pkgs.iproute2}/bin/ip tuntap add mode tun dev tun0 2>/dev/null || true + ${pkgs.iproute2}/bin/ip addr add 198.18.0.1/15 dev tun0 2>/dev/null || true + ${pkgs.iproute2}/bin/ip link set dev tun0 up + ''; + ExecStart = "${pkgs.tun2socks}/bin/tun2socks -device tun0 -proxy socks5://127.0.0.1:10808 -interface lo"; + ExecStartPost = pkgs.writeShellScript "tun2socks-routes" '' + # Get current default gateway + GW=$(${pkgs.iproute2}/bin/ip route show default | ${pkgs.gawk}/bin/awk '{print $3; exit}') + DEV=$(${pkgs.iproute2}/bin/ip route show default | ${pkgs.gawk}/bin/awk '{print $5; exit}') + + # Route xray server traffic directly (avoid loop) + ${pkgs.iproute2}/bin/ip route add ${xrayServer}/32 via $GW dev $DEV 2>/dev/null || true + + # Route everything else through tun0 + ${pkgs.iproute2}/bin/ip route add default dev tun0 metric 1 2>/dev/null || true + ''; + ExecStopPost = pkgs.writeShellScript "tun2socks-teardown" '' + ${pkgs.iproute2}/bin/ip route del default dev tun0 2>/dev/null || true + ${pkgs.iproute2}/bin/ip route del ${xrayServer}/32 2>/dev/null || true + ${pkgs.iproute2}/bin/ip link set dev tun0 down 2>/dev/null || true + ${pkgs.iproute2}/bin/ip tuntap del mode tun dev tun0 2>/dev/null || true + ''; + Restart = "on-failure"; + RestartSec = 5; + }; }; - # Firefox proxy via enterprise policy + # DNS through tunnel — use public DNS that will go through tun0 + networking.nameservers = [ "1.1.1.1" "8.8.8.8" ]; + + # Firefox — disable WebRTC leak programs.firefox = { enable = true; package = pkgs.firefox-devedition; - policies = { - Proxy = { - Mode = "manual"; - SOCKSProxy = "127.0.0.1:10808"; - SOCKSVersion = 5; - Passthrough = "127.0.0.1,localhost"; - UseProxyForDNS = true; - }; - }; + policies = {}; }; - - # SSH through SOCKS5 proxy - programs.ssh.extraConfig = '' - Host * - ProxyCommand ${pkgs.netcat-openbsd}/bin/nc -X 5 -x 127.0.0.1:10808 %h %p - ''; - - # GNOME proxy settings via dconf - programs.dconf.profiles.user.databases = [{ - settings."org/gnome/system/proxy" = { - mode = "manual"; - }; - settings."org/gnome/system/proxy/http" = { - host = "127.0.0.1"; - port = lib.gvariant.mkUint32 10809; - }; - settings."org/gnome/system/proxy/https" = { - host = "127.0.0.1"; - port = lib.gvariant.mkUint32 10809; - }; - settings."org/gnome/system/proxy/socks" = { - host = "127.0.0.1"; - port = lib.gvariant.mkUint32 10808; - }; - }]; }