RepoCloudflare (Workers AI)Cloudflare (Workers AI)published Jan 26, 2026seen 5d

cloudflare/proxy-everything

Go

Open original ↗

Captured source

source ↗
published Jan 26, 2026seen 5dcaptured 9hhttp 200method plain

cloudflare/proxy-everything

Language: Go

Stars: 7

Forks: 1

Open issues: 0

Created: 2026-01-26T18:19:15Z

Pushed: 2026-04-24T17:01:02Z

Default branch: main

Fork: no

Archived: no

README:

proxyeverything

It's a TPROXY based docker container sidecar to proxy all traffic from a docker container to wherever you want.

It leverages HTTP CONNECT to proxy traffic from the container to the host.

Why do I need this?

This is very useful to do things like "listen to all IP ports that the container connects to". You can implement your own gateway for docker containers like this.

(your gateway) [proxy-everything] [user container]

How to build

GOOS=linux CGO_ENABLED=0 go build .

Attention: Do NOT run proxy-everything on your development machine without isolating it in a docker container or its own network namespace, it will modify your iptables.

You should run it on its own docker container. See "How to use it with Docker".

How to implement your own gateway for proxy-everything to use

A gateway server should:

1. Listen on a TCP port (default: 49121) accessible from the container's Docker bridge network (typically 172.17.0.1:49121).

2. Accept HTTP CONNECT requests. proxy-everything will send requests in this format:

CONNECT : HTTP/1.1
Host: :
User-Agent: proxy-everything/0.0.1/
Connection: close
X-Forwarded-For:
X-Proto: tcp

Optional headers may also be present:

  • X-Tls-Sni: when outbound TLS traffic exposes SNI.
  • X-Hostname: when outbound HTTP traffic exposes a Host header and no SNI was available.

3. Parse the destination from the Host header (or request URI) to know where to dial.

4. Establish a connection to the destination (the original target the container wanted to reach).

5. Respond with HTTP status codes:

  • 2xx if the connection to the destination succeeded - the tunnel is now established.
  • 400 if the connection to the destination failed (e.g., connection refused).
  • The rest of status codes are treated as errors from the gateway.

6. Relay data bidirectionally between the proxy-everything client and the destination after sending the 200 OK response. The server should:

  • Copy data from the proxy connection to the destination connection.
  • Copy data from the destination connection back to the proxy connection.
  • Handle half-close properly (close write side when read side receives EOF).

See dummyserver.go for a simple reference implementation. If you don't want to implement your own, run proxy-everything's reference implementation like:

SERVER=1 ./proxy-everything

How to use it with Docker

export CONTAINER=mycontainer

$ docker build -t proxy-everything:dev .

$ docker run \
--add-host=host.docker.internal:host-gateway \
-d --name $(CONTAINER) ubuntu:latest sleep infinity

$ docker run \
-it --rm --cap-add=NET_ADMIN \
--network container:$(CONTAINER) \
--name $(CONTAINER)-proxy proxy-everything:dev

# In another terminal
$ docker exec $(CONTAINER) bash
# You can run commands here to check how proxy-everything works

This will make proxy-everything to $(DOCKER_GATEWAY_IP):49121, DOCKER_GATEWAY_IP which usually belongs to 172.17.0.0/16. At startup proxy-everything will use the default DNS resolver of the container to resolve host.docker.internal so it knows which IP to use to proxy traffic.

When you use proxy-everything as a tool that proxies connections to your own host process, you need to make sure you listen in the right IP, usually this can be accomplished by talking to docker and asking the network gateway of the container.

Example:

$ docker network inspect bridge
[
{
"Name": "bridge",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
...

By the default by this example, the TCP address you should be listening in to receive proxy-everything traffic is 172.17.0.1:49121.

TLS interception

Pass -tls-intercept to terminate TLS inside the proxy so the gateway sees plaintext.

docker run \
-it --rm --cap-add=NET_ADMIN \
--network container:$(CONTAINER) \
proxy-everything:dev -tls-intercept

At startup an ephemeral CA is written to /ca/ca.crt and /ca/ca.key. For outbound TLS connections the proxy peeks the SNI from the ClientHello and adds an X-Tls-Sni header to the CONNECT request. If no SNI is present and the payload looks like HTTP, it also peeks the HTTP request headers and adds X-Hostname. The gateway then decides:

  • 200 -- terminate TLS. The proxy presents a leaf cert (signed by the ephemeral CA) to the container and forwards plaintext to the gateway.
  • 202 -- pass-through. Raw TLS bytes are forwarded as-is; the session stays end-to-end between the container and the origin.

To make the container trust the CA:

docker cp $(CONTAINER)-proxy:/ca/ca.crt /tmp/ca.crt
docker cp /tmp/ca.crt $(CONTAINER):/usr/local/share/ca-certificates/proxy-everything.crt
docker exec $(CONTAINER) update-ca-certificates

Without -tls-intercept all traffic is forwarded as raw bytes and no CA is generated.

Ingress CONNECT listener

Pass -http-ingress-address= to enable an always-on ingress listener inside proxy-everything. If the flag is empty, no ingress listener is started.

  • CONNECT requests are accepted on that listener.
  • X-Dst-Addr must contain the full destination as IP:port.
  • If the destination port is closed, the listener returns 400.
  • GET /ca returns the PEM-encoded CA certificate (/ca/ca.crt). Only useful when -tls-intercept is enabled. Returns 404 if the certificate doesn't exist.
  • PUT /egress updates shared runtime configuration. Supported fields are:
  • port -- updates http-egress-port
  • internet.enabled -- enables or disables internet forwarding for DNS interception
  • dns.allowHostnames -- array of hostname globs such as *.google.com, google.com, or *

Example:

# Fetch the CA certificate (requires -tls-intercept)
curl http://127.0.0.1:49122/ca -o ca.crt

curl -X PUT http://127.0.0.1:49122/egress \
-H 'Content-Type: application/json' \
-d '{"port":8080,"internet":{"enabled":true},"dns":{"allowHostnames":["*.google.com","google.com"]}}'

curl -v -x http://127.0.0.1:49122 https://ignored.example \
-H 'X-Dst-Addr: 172.17.0.1:8443'

DNS interception

UDP interception is currently limited to DNS on port…

Excerpt shown — open the source for the full document.

Notability

notability 2.0/10

Low traction, routine repo