A secure HTTP/HTTPS proxy server in Go with Basic authentication, TLS support, and upstream proxy chaining.
- HTTP and HTTPS proxy modes
- Basic authentication
- TLS with configurable certificates
- Upstream proxy chaining (proxy chain support)
- Supports HTTP and HTTPS upstream proxies
- Configurable via
config.yamlor environment variables (HTTPS_PROXY,HTTP_PROXY) - Basic authentication to upstream proxy
- Selectable outbound network (
auto, IPv4-only, or IPv6-only) - Bounded dial, TLS handshake, and response-header timeouts
- Configurable via YAML file
- Systemd service support
- Graceful shutdown of HTTP requests and hijacked CONNECT tunnels
Download the latest binary from the Releases page.
https://hub.docker.com/r/hightemp/https_proxy
One-liner (HTTP proxy on port 8080, no authentication):
docker run -d --name https_proxy -p 8080:8080 hightemp/https_proxy:latestEnable Basic auth via env vars:
docker run -d --name https_proxy -p 8080:8080 \
-e PROXY_USERNAME=alice -e PROXY_PASSWORD=s3cret \
hightemp/https_proxy:latestIf both
usernameandpasswordare empty, authentication is disabled.
With a custom config:
docker run -d --name https_proxy -p 8080:8080 -v $(pwd)/config.yaml:/etc/https_proxy/config.yaml:ro hightemp/https_proxy:latestAny of these override the corresponding YAML field:
| Variable | Overrides |
|---|---|
PROXY_ADDR |
proxy_addr |
PROXY_USERNAME |
username |
PROXY_PASSWORD |
password |
PROXY_PROTO |
proto (http / https) |
PROXY_CERT_PATH |
cert_path |
PROXY_KEY_PATH |
key_path |
PROXY_UPSTREAM_PROXY |
upstream_proxy |
PROXY_NETWORK |
network (auto / tcp4 / tcp6) |
PROXY_DIAL_TIMEOUT |
dial_timeout |
PROXY_TLS_HANDSHAKE_TIMEOUT |
tls_handshake_timeout |
PROXY_RESPONSE_HEADER_TIMEOUT |
response_header_timeout |
PROXY_READ_HEADER_TIMEOUT |
read_header_timeout |
PROXY_IDLE_TIMEOUT |
idle_timeout |
PROXY_SHUTDOWN_TIMEOUT |
shutdown_timeout |
The bundled docker-compose.yml starts an HTTP proxy, an HTTPS proxy, and a certbot sidecar that issues and auto-renews Let's Encrypt certificates into a shared volume. All settings come from a .env file — no YAML editing required.
-
Copy the env template and fill it in:
cp .env.example .env # edit DOMAIN, EMAIL, PROXY_USERNAME, PROXY_PASSWORD -
Issue the initial Let's Encrypt certificate (port 80 must be reachable on
$DOMAIN):docker compose run --rm --service-ports certbot issue
-
Start the stack:
docker compose up -d
Certbot renews certificates automatically every 12 hours. Restart the HTTPS proxy after a renewal if needed:
docker compose restart https-proxy-
Clone the repository:
git clone https://github.com/hightemp/https_proxy cd https_proxy -
Build the project:
make build
Create a config.yaml file (see config.example.yaml):
proxy_addr: 127.0.0.1:8080
username: "your_username"
password: "your_password"
proto: http
cert_path: ""
key_path: ""
network: auto
dial_timeout: 10s
tls_handshake_timeout: 10s
response_header_timeout: 30s
read_header_timeout: 15s
idle_timeout: 2m
shutdown_timeout: 15s
# upstream_proxy: http://user:pass@upstream-proxy:8080The example listens on localhost. Set proxy_addr to 0.0.0.0:8080 only when the proxy must accept remote connections, and configure authentication before exposing it.
| Parameter | Description |
|---|---|
proxy_addr |
Listen address and port |
username |
Basic auth username |
password |
Basic auth password |
proto |
http or https |
cert_path |
Path to TLS certificate (for https mode) |
key_path |
Path to TLS private key (for https mode) |
upstream_proxy |
Upstream proxy URL for chaining (optional) |
network |
Outbound address family: auto, tcp4, or tcp6 |
dial_timeout |
TCP connection timeout |
tls_handshake_timeout |
Outbound TLS handshake timeout |
response_header_timeout |
Upstream CONNECT/HTTP response-header timeout |
read_header_timeout |
Incoming request-header timeout |
idle_timeout |
Incoming keep-alive idle timeout |
shutdown_timeout |
Graceful shutdown deadline |
Timeout values use Go duration syntax, for example 500ms, 10s, or 2m. Unknown YAML keys and invalid values stop the proxy at startup instead of being silently ignored.
network: auto uses Go's normal dual-stack dialing. If the server advertises IPv6 but its IPv6 route is broken, use IPv4-only dialing so affected requests fail over immediately:
network: tcp4The setting applies to direct CONNECT targets, ordinary forwarded HTTP requests, and the connection to an upstream proxy. When chaining through an upstream proxy, that upstream still resolves and connects to the final target itself.
To route all traffic through an upstream proxy, set upstream_proxy in config.yaml:
upstream_proxy: http://user:pass@upstream-proxy:8080HTTPS upstream proxies are also supported:
upstream_proxy: https://user:pass@upstream-proxy:8443If upstream_proxy is not set in the config, the proxy falls back to standard environment variables (HTTPS_PROXY, HTTP_PROXY, NO_PROXY).
An explicitly configured upstream URL is validated at startup and never silently falls back to a direct connection. Percent-encode reserved characters in credentials, for example user%40example for user@example and p%3Ass for p:ss.
Generate self-signed certificates:
bash generate_certs.shOr use Let's Encrypt:
sudo certbot certonly --standalone -d example.comcert_path: "/etc/letsencrypt/live/example.com/fullchain.pem"
key_path: "/etc/letsencrypt/live/example.com/privkey.pem"./https_proxy -config config.yamlsudo make installManage the service:
make start / stop / restart / status| Command | Description |
|---|---|
make build |
Build the binary |
make build-static |
Build a static binary (linux/amd64) |
make run |
Run the proxy |
make install |
Install binary, config and systemd service |
make uninstall |
Remove binary and service (keep config) |
make uninstall-full |
Remove everything including config |
make release |
Tag version from VERSION file and push |
make docker-build |
Build Docker image hightemp/https_proxy:VERSION and :latest |
make docker-push |
Build and push image to Docker Hub |
make docker-release |
Alias for docker-push |
-
Update the version in the
VERSIONfile. -
Run:
make release
This will commit, create a git tag
vX.Y.Z, and push it. GitHub Actions will automatically build binaries and create a release.
This project is licensed under the MIT License.