Sign inSign up

daniknik/https_proxy

By daniknik

•Updated 8 months ago

Very simple, lightweight, zero-dependency HTTP/HTTPS proxy with TLS-passthrough and authentication.

Image
Networking
Security
Developer tools
0

454

daniknik/https_proxy repository overview

⁠HTTP/HTTPS Forward Proxy

Lightweight, high-performance forward proxy written in Go 1.25 with zero dependencies. Supports HTTP forwarding, HTTPS tunneling (CONNECT method), Basic authentication, and streaming connections.

⁠Features

  • ✅ HTTP forward proxy with http.Transport connection pooling
  • ✅ HTTPS tunneling via CONNECT method (TLS passthrough)
  • ✅ Streaming support (Server-Sent Events, chunked responses)
  • ✅ Basic authentication with constant-time comparison
  • ✅ Transparent mode (strips proxy-revealing headers)
  • ✅ Configurable via TOML file or environment variables
  • ✅ Graceful shutdown on SIGINT/SIGTERM
  • ✅ Docker support with minimal scratch-based image

⁠Quick Start

⁠Build from Source
go build -o proxy .
./proxy
⁠Docker
# Build image
docker build -t https-proxy .

# Run with environment variables
docker run -d \
  -p 8080:8080 \
  -e PROXY_AUTH_USERNAME=admin \
  -e PROXY_AUTH_PASSWORD=secret \
  --name https-proxy \
  daniknik/https_proxy

# Run with config file
docker run -d \
  -p 8080:8080 \
  -v $(pwd)/config.toml:/config.toml:ro \
  --name https-proxy \
  daniknik/https_proxy -config /config.toml

⁠Configuration

Configuration is loaded in priority order: defaults → TOML file → environment variables.

⁠Environment Variables
VariableDefaultDescription
PROXY_LISTEN_ADDR:8080Listen address
PROXY_AUTH_USERNAME""Basic auth username (empty = disabled)
PROXY_AUTH_PASSWORD""Basic auth password
PROXY_TIMEOUT_DIAL10sDial timeout for upstream connections
PROXY_TIMEOUT_IDLE120sIdle connection timeout
PROXY_TIMEOUT_READ30sRead timeout (applies to request headers only)
PROXY_TIMEOUT_WRITE30sWrite timeout
PROXY_TUNNEL_BUFFER_SIZE32768Buffer size for CONNECT tunneling (bytes)
PROXY_LOG_LEVELinfoLog level: debug, info, error
⁠TOML Configuration

Create config.toml:

listen_addr = ":8080"

[auth]
username = "admin"
password = "secret"

[timeout]
dial = "10s"
idle = "120s"
read = "30s"
write = "30s"

[tunnel]
buffer_size = 32768

[log]
level = "info"

⁠Docker Deployment

⁠Basic Setup
# Build image
docker build -t https-proxy .

# Run with authentication
docker run -d \
  --name https-proxy \
  --restart unless-stopped \
  -p 8080:8080 \
  -e PROXY_AUTH_USERNAME=myuser \
  -e PROXY_AUTH_PASSWORD=mypass \
  -e PROXY_LOG_LEVEL=info \
  daniknik/https_proxy
⁠Production Setup with Config File
  1. Create config.toml:
listen_addr = ":8080"

[auth]
username = "production-user"
password = "strong-password-here"

[timeout]
dial = "15s"
idle = "300s"
read = "60s"
write = "300s"

[tunnel]
buffer_size = 65536

[log]
level = "info"
  1. Run container:
docker run -d \
  --name https-proxy \
  --restart unless-stopped \
  -p 8080:8080 \
  -v $(pwd)/config.toml:/config.toml:ro \
  --read-only \
  --cap-drop ALL \
  --security-opt no-new-privileges:true \
  daniknik/https_proxy -config /config.toml
⁠Docker with Resource Limits
docker run -d \
  --name https-proxy \
  --restart unless-stopped \
  -p 8080:8080 \
  -e PROXY_AUTH_USERNAME=admin \
  -e PROXY_AUTH_PASSWORD=secret \
  --memory=256m \
  --cpus=1 \
  daniknik/https_proxy
⁠Check Logs
docker logs -f https-proxy

⁠Usage Examples

⁠HTTP Request
curl -x http://admin:secret@localhost:8080 http://httpbin.org/get
⁠HTTPS Request (CONNECT Tunnel)
curl -x http://admin:secret@localhost:8080 https://httpbin.org/get
⁠Streaming (OpenAI-compatible APIs)
curl https://api.openai.com/v1/chat/completions \
  -x http://admin:secret@localhost:8080 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true
  }'
⁠Python with openai Library
import openai
import os

openai.api_key = os.getenv("OPENAI_API_KEY")
openai.proxy = "http://admin:secret@localhost:8080"

stream = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Write a poem"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.get("content"):
        print(chunk.choices[0].delta.content, end="")
⁠Configure in Application

Python (requests):

import requests

proxies = {
    'http': 'http://admin:secret@localhost:8080',
    'https': 'http://admin:secret@localhost:8080',
}

response = requests.get('https://api.example.com', proxies=proxies)

Node.js:

const axios = require('axios');

const proxy = {
  protocol: 'http',
  host: 'localhost',
  port: 8080,
  auth: {
    username: 'admin',
    password: 'secret'
  }
};

axios.get('https://api.example.com', { proxy });

⁠How It Works

⁠HTTP Forwarding
  1. Client sends request with absolute URL: GET http://example.com/path
  2. Proxy validates auth, sanitizes headers
  3. Forwards request via http.Transport.RoundTrip (no redirect following)
  4. Streams response back to client
⁠HTTPS Tunneling (CONNECT)
  1. Client sends: CONNECT api.openai.com:443
  2. Proxy establishes TCP connection to target
  3. Returns HTTP/1.1 200 Connection Established
  4. Hijacks connection and performs bidirectional byte copy
  5. Client performs TLS handshake directly with upstream (end-to-end encryption)

No SSL certificate needed — proxy operates at TCP level, never decrypts TLS traffic.

⁠Header Sanitization

Proxy removes hop-by-hop and proxy-revealing headers:

  • Connection, Keep-Alive, Proxy-Authorization
  • X-Forwarded-For, X-Forwarded-Host, Via, Forwarded
  • Headers listed in Connection header value

⁠Streaming Support

  • ✅ Server-Sent Events (SSE) — OpenAI, Anthropic Claude, etc.
  • ✅ HTTP/2 — via CONNECT tunnel
  • ✅ Chunked Transfer-Encoding — streamed without buffering
  • ✅ WebSocket over CONNECT — full bidirectional support for wss://
  • ✅ Long-lived connections — no timeout on response body streaming

⁠Security Notes

  • Basic auth uses crypto/subtle.ConstantTimeCompare to prevent timing attacks
  • Docker image runs as non-root user (UID 65534)
  • Docker image is read-only and drops all capabilities
  • Proxy doesn't log request/response bodies
  • HTTPS traffic is never decrypted (TLS passthrough)

⁠Troubleshooting

⁠Connection timeouts with streaming

Increase write timeout for long-running streaming responses:

docker run -d \
  -p 8080:8080 \
  -e PROXY_TIMEOUT_WRITE=600s \
  daniknik/https_proxy
⁠Authentication failures

Check credentials format:

# Correct
curl -x http://user:pass@localhost:8080 https://example.com

# Incorrect (missing scheme)
curl -x user:pass@localhost:8080 https://example.com
⁠Docker networking

If running proxy and client in separate containers, use Docker network:

docker network create proxy-net

docker run -d \
  --name https-proxy \
  --network proxy-net \
  -e PROXY_AUTH_USERNAME=admin \
  -e PROXY_AUTH_PASSWORD=secret \
  daniknik/https_proxy

# In client container, use: http://https-proxy:8080

⁠License

This project is provided as-is for educational and production use.

Tag summary

Content type

Image

Digest

sha256:396ef5b82…

Size

2.5 MB

Last updated

8 months ago

docker pull daniknik/https_proxy