Declarative proxy stack for NixOS
  • Nix 76.1%
  • Python 11.6%
  • C 6.9%
  • Shell 5.4%
Find a file
2026-07-10 18:48:06 +05:00
.github/workflows fix gh actions 2026-04-15 17:43:23 +05:00
docs fix: per-site config was not working properly 2026-07-02 19:18:55 +05:00
modules/proxy-suite fix: per-site config was not working properly 2026-07-02 19:18:55 +05:00
nix fix: per-site config was not working properly 2026-07-02 19:18:55 +05:00
pkgs fix: temp migration of zapret and tg-ws-proxy to archive.org 2026-07-10 18:48:06 +05:00
scripts fix: per-site config was not working properly 2026-07-02 19:18:55 +05:00
.gitignore initial commit 2026-04-11 16:50:50 +05:00
flake.lock fix: temp migration of zapret and tg-ws-proxy to archive.org 2026-07-10 18:48:06 +05:00
flake.nix fix: temp migration of zapret and tg-ws-proxy to archive.org 2026-07-10 18:48:06 +05:00
LICENSE add license file 2026-04-26 21:18:22 +05:00
README.md feat(wip): xray proxy backend 2026-06-07 18:15:37 +05:00

proxy-suite-flake

Declarative proxy stack for NixOS.

Bundles sing-box, XRay, zapret-discord-youtube, and tg-ws-proxy. Built specifically for dealing with Roskomnadzor (RKN) and the usual Russian ISP nonsense.

The goal is to replace GUI clients like v2rayN and throne you configure your proxies in Nix, rebuild, and they just work as systemd services.


What it gives you

  • SOCKS5/HTTP proxy on 127.0.0.1:1080 when proxy.enable = true
  • Backend choice use SingBox or XRay through the same services.proxy-suite.proxy option tree
  • Transparent proxy (TProxy) redirect all system traffic through the active backend without configuring each app; start/stop on demand or autostart at boot
  • TUN mode full tunnel via a virtual network interface; useful when TProxy doesn't cover something, with optional boot-time autostart
  • Per-app wrapping run selected apps through the local proxy with proxy-ctl wrap <profile> -- <command>, without enabling global TProxy or TUN
  • Subscription URLs point at a v2rayN/Clash-format subscription endpoint; the module fetches, decodes, and imports all proxies automatically, with a periodic refresh timer
  • Multiple outbounds with automatic latency-based switching or manual selection
  • Per-outbound routing route specific domains, IPs, or geo sets to specific servers
  • Protocol support: vless (Reality, TLS), vmess, trojan, shadowsocks, hysteria2, socks5, socks4, http/https proxy; SingBox also supports TUIC v5, while XRay supports XHTTP/ECH share links
  • proxy-ctl control script for managing services, switching outbounds, and following logs
  • DPI bypass via zapret handles YouTube, Discord, and other sites defined by the project
  • Telegram proxy running local MTProto WebSocket proxy using tg-ws-proxy

Setup

Add to your flake inputs:

inputs.proxy-suite.url = "github:FUFSoB/proxy-suite-flake";

No need to add zapret separately it comes along as a transitive input.

Add the module to your NixOS configuration:

modules = [ inputs.proxy-suite.nixosModules.default ];

Feature-complete starter config:

services.proxy-suite = {
  enable = true;

  proxy = {
    enable = true;
    singBox.enable = true;
    # Or use XRay instead:
    # xray.enable = true;

    port = 1080;

    # Individual proxy example
    outbounds = [
      {
        tag = "nl-vps";
        # Inline url is convenient for testing, but ends up in the Nix store.
        # For real use, prefer urlFile with a url file.
        url = "hy2://password@example.com:443?sni=example.com";
      }
    ];

    # Subscription example
    subscriptions = [
      {
        tag = "main-sub";
        # urlFile is also available to keep the URL out of the Nix store.
        url = "https://example.com/subscription-list.txt";
      }
    ];
    # Automatic switching of outbound based on latency.
    # Default is "first", which just uses the first one in the list.
    selection = "urltest";

    # Keep both available; autostart only one global tunnel.
    tproxy = {
      enable = true;
      autostart = false;
      perApp.enable = true;
    };
    tun = {
      enable = true;
      autostart = false;
      perApp.enable = true;
    };
  };

  zapret = {
    enable = true;
    perApp.enable = true;
  };

  perAppRouting = {
    enable = true;
    createDefaultProfiles = true;
    proxychains.enable = true;
  };

  tray = {
    enable = true;
    autostart = true;
  };

  tgWsProxy = {
    enable = true;
    port = 1443;
    # Inline secret is convenient for testing, but ends up in the Nix store.
    # For real use, prefer secretFile with a secret file.
    secret = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  };
};

Options

To see options and documentation, check out the options reference.

Options and generated README help are refreshed with nix run .#update-docs.


proxy-ctl help

Generated from current proxy-ctl help output.

Usage: proxy-ctl <command> [args]

Commands:
  help                      show this help message
  status [--tray]           show status of all proxy-suite services
  proxy on|off              enable/disable the proxy backend stack
  tproxy on|off             enable/disable TProxy transparent mode
  tun on|off                enable/disable TUN mode
  route-mode default|whitelist|blacklist|all-proxy|all-bypass|status
                            set temporary routing override
  zapret on|off             enable/disable zapret-discord-youtube
  restart                   restart active global proxy-suite services
  logs [service]            follow service logs  (default: proxy-suite-socks)
  outbounds                 list outbounds and current selection
  select <tag>              switch to a specific outbound  (selector mode)
  apps                      list configured per-app routing profiles
  wrap <profile> -- <cmd>   run a command via a perAppRouting profile
  subscription list         show subscriptions, cache age, and proxy count
  subscription update       force-refresh all subscription caches and restart active proxy services