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>
104 lines
3.0 KiB
Markdown
104 lines
3.0 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
cp config/example.yaml config/s5p.yaml
|
|
```
|
|
|
|
```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.
|