Skip to content

Red-Panda-Dev/tbel_proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tokenbel-proxy

Small Go web service that proxies outbound GET requests through a SOCKS5 proxy.

It exposes one business endpoint:

  • GET /socks5 (also available as GET /proxy)

and one technical endpoint:

  • GET /health

Business Logic

/socks5 accepts a target URL via query params, enforces Bearer token auth, forwards the request through SOCKS5, and returns upstream response as-is.

Flow:

  1. Validate Authorization header: Bearer <token>.
  2. Read query params:
    • url (required if target not set): full HTTPS URL used as-is
    • target (required if url not set): host/path without protocol, service prepends https://
    • method (required): only get supported (case-insensitive)
    • data_type (optional): currently ignored, kept for compatibility
  3. Only HTTPS targets are allowed. HTTP URLs are rejected with 400.
  4. If TOKENBEL_PROXY_ALLOWED_DOMAINS is configured, only requests to listed domains (including subdomains) are allowed.
  5. Execute request through SOCKS5 proxy with per-request timeout.
  6. Return upstream status code, headers, and body.

Error behavior:

  • Missing/invalid Bearer token -> 401
  • Missing url/target -> 400
  • HTTP (non-HTTPS) target -> 400
  • Disallowed domain -> 403
  • Invalid method -> 400
  • Rate limit exceeded -> 429
  • Upstream timeout -> 504
  • Proxy/upstream network error -> 502

Error response shape:

{
    "error": "bad_gateway",
    "message": "proxy connection failed",
    "details": "connection refused"
}

Configuration

Configuration is read from environment variables:

Variable Required Description
TOKENBEL_PROXY_BEARER_TOKEN Yes Bearer token for endpoint authentication
TOKENBEL_PROXY_SOCKS5_URL Yes SOCKS5 proxy URL (e.g., socks5://user:pass@host:port)
TOKENBEL_PROXY_PORT No Server port (default: 8080)
TOKENBEL_PROXY_TIMEOUT No Upstream request timeout in seconds (default: 120)
TOKENBEL_PROXY_CLIENT_PROFILE No TLS client profile: chrome_120 or firefox_117 (default: chrome_120)
TOKENBEL_PROXY_INSECURE_TLS No Skip TLS verification: true or false (default: true)
TOKENBEL_PROXY_ALLOWED_DOMAINS No Comma-separated domain allowlist (default: empty = all allowed)
TOKENBEL_PROXY_RATE_LIMIT No Requests per second per IP (default: 0 = unlimited)
TOKENBEL_PROXY_RATE_BURST No Burst size for rate limiter (default: same as rate limit)

Example

export TOKENBEL_PROXY_BEARER_TOKEN="your-secret-token"
export TOKENBEL_PROXY_SOCKS5_URL="socks5://user:password@geo.iproyal.com:12321"
export TOKENBEL_PROXY_ALLOWED_DOMAINS="egr.gov.by,example.com"
export TOKENBEL_PROXY_RATE_LIMIT=5

The service will exit at startup if required variables are missing.

API Contract

1) Health endpoint

GET /health

Checks SOCKS5 proxy TCP reachability. Returns 200 if proxy is reachable, 503 if not.

Success response:

{ "status": "ok" }

Unhealthy response:

{ "status": "unhealthy", "details": "proxy unreachable" }

2) Proxy endpoint

GET /socks5?url=<https-url>&method=get GET /socks5?target=<host/path>&data_type=json&method=get

Required header:

Authorization: Bearer $TOKENBEL_PROXY_BEARER_TOKEN

A X-Request-ID header is set on every response. If the incoming request includes one, it is forwarded; otherwise a random ID is generated.

Example:

curl -i \
  -H "Authorization: Bearer $TOKENBEL_PROXY_BEARER_TOKEN" \
  "http://localhost:8080/socks5?target=egr.gov.by/api/v2/egr/getAllJurNamesByRegNum/191179355&data_type=json&method=get"

Local Build and Run

From project root:

cd src
go mod tidy
go build -o proxy .
./proxy

The service starts on :8080.

Quick checks:

curl -s http://localhost:8080/health
curl -i "http://localhost:8080/socks5?target=example.com&method=get"
# expected: 401 (missing auth header)

Testing

Run all checks:

cd src
go test ./...
go vet ./...
go build ./...

Current unit tests are in:

  • handler/proxy_test.go
  • handler/health_test.go
  • handler/ratelimit_test.go
  • handler/requestid_test.go
  • config/config_test.go

Covered scenarios:

  • unauthorized requests
  • missing target
  • invalid method
  • HTTPS-only enforcement
  • domain allowlist (allowed, blocked, subdomains)
  • per-request timeout (504)
  • request ID generation and forwarding
  • rate limiting (under/over limit, separate IPs)
  • health check (proxy reachable, unreachable, no proxy configured)
  • timeout mapping
  • bad gateway mapping
  • success response forwarding
  • config env var parsing

Docker Build and Deployment

Service includes a multi-stage Dockerfile:

  • Builder: golang:alpine
  • Runtime: alpine:latest

Build image

From repository root:

docker build -t tokenbel-proxy:latest ./src

Run container

docker run --rm -p 8080:8080 \
  -e TOKENBEL_PROXY_BEARER_TOKEN="$TOKENBEL_PROXY_BEARER_TOKEN" \
  -e TOKENBEL_PROXY_SOCKS5_URL="$TOKENBEL_PROXY_SOCKS5_URL" \
  tokenbel-proxy:latest

Validate container

curl -s http://localhost:8080/health

Deployment Notes

For production-like deployment, at minimum:

  1. Restrict inbound access (private network, gateway, ACLs).
  2. Set TOKENBEL_PROXY_ALLOWED_DOMAINS to limit upstream targets.
  3. Enable rate limiting via TOKENBEL_PROXY_RATE_LIMIT.
  4. Set TOKENBEL_PROXY_INSECURE_TLS=false if upstream certificates are valid.
  5. Monitor logs (structured JSON via log/slog) and HTTP status distribution.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors