https://github.com/grepplabs/reverse-http
Reverse HTTP proxy over QUIC protocol
https://github.com/grepplabs/reverse-http
edge go golang http https quic reverse-http reverse-proxy tunnel
Last synced: 20 days ago
JSON representation
Reverse HTTP proxy over QUIC protocol
- Host: GitHub
- URL: https://github.com/grepplabs/reverse-http
- Owner: grepplabs
- License: apache-2.0
- Created: 2024-02-26T12:46:37.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-11-05T08:12:30.000Z (3 months ago)
- Last Synced: 2025-11-05T08:34:34.745Z (3 months ago)
- Topics: edge, go, golang, http, https, quic, reverse-http, reverse-proxy, tunnel
- Language: Go
- Homepage:
- Size: 139 KB
- Stars: 5
- Watchers: 1
- Forks: 1
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# reverse-http
[](https://github.com/grepplabs/reverse-http/actions/workflows/build.yml)
[](https://opensource.org/licenses/Apache-2.0)
[](https://github.com/grepplabs/reverse-http/releases)
Reverse HTTP proxy over QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)).
## Architecture
### Standalone

* Agent connection process
* An agent initiates a connection to the proxy server utilizing the `QUIC` protocol.
* The connection between the agent and the proxy is persistent
* Upon connection, the proxy server performs an agent authentication
* The proxy keeps track of agents' connections
* Each agent is uniquely identified by an `agentID`
* Multiple agents can simultaneously connect to the proxy.
* Only one connection per `agentID` is allowed.
* Client connection process
* Clients establish a connection with the HTTP proxy by issuing an `HTTP CONNECT` request. This standard method allows the client to specify the desired destination.
* During the connection process, the proxy authenticates the connecting client using basic `Proxy-Authorization`, where the `username` is utilized to specify the `agentID` that the client wishes to connect to.
* Once authenticated, the proxy server locates the corresponding agent's `QUIC` connection that is already being tracked.
* Proxy opens a new `QUIC` stream to the agent and sends all subsequent data through it
* The agent proceeds with the `CONNECT` procedure by establishing a new TCP connection to the requested destination.
### HA setup

* Agent connection process
* An agent initiates a connection to the UDP load balancer, which in turn establishes a connection with one of the proxy servers
* Upon establishing a connection, the proxy server records an entry in `memcached` for an agentID along with its own HTTP proxy address.
* Client connection process
* Clients connect to the TCP load balancer, which then establishes a connection with one of the LB servers.
* Upon connection, the LB server retrieves the HTTP proxy address and an agentID from Memcached.
* The LB server then sends an `HTTP CONNECT` request to the proxy.
## Install binary release
1. Get latest tag version
```
TAG=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/grepplabs/reverse-http/releases/latest | grep -o 'tag/.*' | sed 's/tag\///')
VERSION=$(echo -n $TAG | grep -o 'v[0-9.]*' | sed 's/v//')
```
2. Download the release
* Linux
```
curl -Ls https://github.com/grepplabs/reverse-http/releases/download/${TAG}/reverse-http_${VERSION}_linux_amd64.tar.gz | tar xz
```
* MacOS Intel
```
curl -Ls https://github.com/grepplabs/reverse-http/releases/download/${TAG}/reverse-http_${VERSION}_darwin_amd64.tar.gz | tar xz
```
* MacOS Apple Silicon
```
curl -Ls https://github.com/grepplabs/reverse-http/releases/download/${TAG}/reverse-http_${VERSION}_darwin_arm64.tar.gz | tar xz
```
3. Move the binary to a file location on your system PATH.
```
mv ./reverse-http /usr/local/bin/reverse-http
```
## Docker run
```
docker run --rm ghcr.io/grepplabs/reverse-http:latest --help
```
## Build
### build binary
make clean build
## Quick requirements
https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes
```bash
sudo bash -c 'echo net.core.rmem_max=2500000 >> /etc/sysctl.conf'
sudo bash -c 'echo net.core.wmem_max=2500000 >> /etc/sysctl.conf'
sudo sysctl -p
```
## Local test standalone
### no auth
```bash
make start-proxy
make start-agent
curl -x "http://4711:noauth@localhost:3128" https://httpbin.org/ip
```
### jwt auth
```bash
make start-proxy-jwt
make start-agent-jwt
make curl-proxy-jwt
```
## Local test docker-compose
```bash
make TEST_AUTH=noauth docker-compose.run
make TEST_AGENT_ID=4711 curl-proxy
make TEST_AGENT_ID=4712 curl-proxy
```
## Whitelisting patterns
```
localhost
localhost:80
localhost:1000-2000
*.zone
*.zone:80
*.zone:1000-2000
127.0.0.1
127.0.0.1:80
127.0.0.1:1000-2000
10.0.0.1/8
10.0.0.1/8:80
10.0.0.1/8:1000-2000
1000::/16
1000::/16:80
1000::/16:1000-2000
[2001:db8::1]/64
[2001:db8::1]/64:80
[2001:db8::1]/64:1000-2000
2001:db8::1
[2001:db8::1]
[2001:db8::1]:80
[2001:db8::1]:1000-2000
```