Files
s5p/README.md
user b07ea49965 feat: add connection retry and metrics
Retry failed proxy connections with a fresh random proxy on each
attempt (configurable via retries setting, proxy_source only).
Track connection metrics and log summary every 60s and on shutdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 04:54:13 +01:00

3.0 KiB

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)
  • Dynamic proxy source: fetch proxies from an HTTP API, rotate per-connection
  • Connection retry with proxy rotation (configurable attempts)
  • Connection metrics (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                              # max attempts (proxy_source only)

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

proxy_source:
  url: http://10.200.1.250:8081/proxies
  proto: socks5                       # optional filter
  limit: 1000
  refresh: 300                        # cache refresh (seconds)

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] -> [random proxy from source] -> 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 source is configured, a random proxy is appended to the chain per-connection. Each hop only sees its immediate neighbors.