user 0816a7f0cb feat: add static chain health check before pool tests
Test the static chain (without pool proxy) before running pool health
tests. If the chain itself is unreachable, skip proxy testing and log a
clear warning. Prevents false mass-failure when the issue is upstream
(e.g., Tor is down), not the exit proxies.
2026-02-15 15:59:26 +01:00
2026-02-15 06:18:20 +01:00

s5p

SOCKS5 proxy server with Tor and proxy-chain support. Routes connections through configurable chains of SOCKS4, SOCKS5, and HTTP CONNECT proxies.

Features

  • SOCKS5 server (RFC 1928)
  • Proxy chaining: tunnel through multiple hops in sequence
  • Supported hop protocols: SOCKS5, SOCKS4/4a, HTTP CONNECT
  • Per-hop authentication (username/password)
  • DNS leak prevention (domain names forwarded to proxies, never resolved locally)
  • Tor integration (Tor is just another SOCKS5 hop)
  • Managed proxy pool: multiple sources (API + file), health-tested, weighted selection
  • Per-proxy failure backoff (60s cooldown) and stale proxy expiry
  • Connection retry with proxy rotation (configurable attempts)
  • Connection metrics with pool stats (logged periodically and on shutdown)
  • Container-ready (Alpine-based, podman/docker)
  • Graceful shutdown (SIGTERM/SIGINT)
  • Pure Python, asyncio-based, minimal dependencies

Quick Start

# Install locally
cd ~/git/s5p
python -m venv .venv && source .venv/bin/activate
pip install -e .

# Run with Tor
s5p -C socks5://127.0.0.1:9050

# Run with config file
cp config/example.yaml config/s5p.yaml  # edit with your proxies
s5p -c config/s5p.yaml

# Test it
curl --proxy socks5h://127.0.0.1:1080 https://check.torproject.org/api/ip

Container

make build   # podman-compose build
make up      # podman-compose up -d
make logs    # podman-compose logs -f
make down    # podman-compose down

Source and config are bind-mounted, not baked into the image.

Configuration

Copy the example and edit with your proxy chain:

cp config/example.yaml config/s5p.yaml
listen: 127.0.0.1:1080
timeout: 10
retries: 3

chain:
  - socks5://127.0.0.1:9050          # Tor

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.

CLI Reference

s5p [-c FILE] [-l [HOST:]PORT] [-C URL[,URL,...]] [-S URL] [-t SEC] [-r N] [-v|-q]

Options:
  -c, --config FILE        YAML config file
  -l, --listen [HOST:]PORT Listen address (default: 127.0.0.1:1080)
  -C, --chain URL[,URL]    Comma-separated proxy chain
  -S, --proxy-source URL   Proxy source API URL
  -t, --timeout SEC        Per-hop timeout (default: 10)
  -r, --retries N          Max attempts per connection (default: 3, proxy_source only)
  -v, --verbose            Debug logging
  -q, --quiet              Errors only
  --cprofile [FILE]        Enable cProfile, dump to FILE (default: s5p.prof)
  -V, --version            Show version

How Chaining Works

Client -> s5p -> [static chain] -> [weighted alive proxy from pool] -> Destination

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, an alive proxy is appended per-connection, weighted toward those with the most recent successful health test. Each hop only sees its immediate neighbors.

Description
No description provided
Readme 769 KiB
Languages
Python 99.6%
Makefile 0.2%
Dockerfile 0.2%