diff --git a/README.md b/README.md index ff989dc..4eab144 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,16 @@ through configurable chains of SOCKS4, SOCKS5, and HTTP CONNECT proxies. - Per-hop authentication (username/password) - DNS leak prevention (domain names forwarded to proxies, never resolved locally) - Tor integration (SOCKS5 hop + control port NEWNYM for circuit rotation) -- Multi-listener: different ports with different chain depths (Tor-only, Tor+1, Tor+2) -- Managed proxy pool: multiple sources (API + file), health-tested, weighted selection +- Multi-Tor round-robin (`tor_nodes` distributes traffic across Tor instances) +- Multi-listener: different ports with different chain depths and pool assignments +- Named proxy pools: independent sources, health testing, and state per pool +- MITM source filter (`mitm: true/false` adds `?mitm=0/1` to API requests) - Per-proxy failure backoff (60s cooldown), stale proxy expiry, chain pre-flight - Fast warm start (seconds on restart vs minutes on cold start) - Connection retry with proxy rotation (configurable attempts) - Dead proxy reporting to upstream API (optional `report_url`) - SIGHUP hot reload (timeout, retries, log_level, pool config) -- Connection metrics with pool stats (logged periodically and on shutdown) +- Connection metrics with per-listener latency and pool stats - Concurrent connection limit with backpressure (`max_connections`) - Async HTTP client for proxy source fetching (parallel, no threads) - First-hop TCP connection pool (pre-warmed, stale-evicted) @@ -73,39 +75,52 @@ max_connections: 256 # concurrent connection limit pool_size: 8 # pre-warmed connections to first hop api_listen: 127.0.0.1:1081 # control API (disabled by default) -# Multi-listener: each port gets a different chain depth +# Named proxy pools (each with independent sources and health testing) +proxy_pools: + clean: + sources: + - url: http://10.200.1.250:8081/proxies/all + mitm: false # filter: ?mitm=0 + refresh: 300 + test_interval: 120 + max_fails: 3 + mitm: + sources: + - url: http://10.200.1.250:8081/proxies/all + mitm: true # filter: ?mitm=1 + refresh: 300 + test_interval: 120 + max_fails: 3 + +# Multi-listener: each port gets a chain depth and pool assignment listeners: - listen: 0.0.0.0:1080 + pool: clean chain: - socks5://127.0.0.1:9050 - - pool # Tor + 2 pool proxies + - pool # Tor + 2 clean proxies - pool - listen: 0.0.0.0:1081 + pool: clean chain: - socks5://127.0.0.1:9050 - - pool # Tor + 1 pool proxy + - pool # Tor + 1 clean proxy - listen: 0.0.0.0:1082 chain: - socks5://127.0.0.1:9050 # Tor only + - listen: 0.0.0.0:1083 + pool: mitm + chain: + - socks5://127.0.0.1:9050 + - pool # Tor + 2 MITM proxies + - pool -# Old single-listener format still works: -# listen: 127.0.0.1:1080 -# chain: -# - socks5://127.0.0.1:9050 +# Singular proxy_pool: still works (becomes pool "default") tor: control_port: 9051 # Tor control port (NEWNYM) password: "" # or cookie_file for auth newnym_interval: 0 # periodic circuit rotation (0 = manual) - -proxy_pool: - sources: - - url: http://10.200.1.250:8081/proxies - proto: socks5 - - file: /etc/s5p/proxies.txt # one proxy URL per line - refresh: 300 # re-fetch interval (seconds) - test_interval: 120 # health test cycle (seconds) - max_fails: 3 # evict after N consecutive failures ``` `config/s5p.yaml` is gitignored; `config/example.yaml` is the tracked template. @@ -134,13 +149,14 @@ Options: ## How Chaining Works ``` -:1080 Client -> s5p -> Tor -> [pool] -> [pool] -> Destination (2 pool hops) -:1081 Client -> s5p -> Tor -> [pool] -> Destination (1 pool hop) -:1082 Client -> s5p -> Tor -> Destination (0 pool hops) +:1080 Client -> s5p -> Tor -> [clean] -> [clean] -> Dest (2 clean hops) +:1081 Client -> s5p -> Tor -> [clean] -> Dest (1 clean hop) +:1082 Client -> s5p -> Tor -> Dest (Tor only) +:1083 Client -> s5p -> Tor -> [mitm] -> [mitm] -> Dest (2 MITM hops) ``` s5p connects to Hop1 via TCP, negotiates the hop protocol (SOCKS5/4/HTTP), -then over that tunnel negotiates with Hop2, and so on. If a proxy pool is -configured, alive proxies are appended per-connection (one per `pool` entry), -weighted toward those with the most recent successful health test. Each hop -only sees its immediate neighbors. +then over that tunnel negotiates with Hop2, and so on. Each listener draws +from its assigned named pool -- alive proxies are appended per-connection +(one per `pool` entry), weighted toward those with the most recent successful +health test. Each hop only sees its immediate neighbors.