Gazan is a Reverse proxy, service mesh based on Cloudflare's Pingora
What Gazan means? Gazan = Գազան = beast / wild animal in Armenian / Often used as a synonym to something great..
Built on Rust, on top of Cloudflare’s Pingora engine, Gazan delivers world-class performance, security, and scalability — right out of the box.
- ⚙️ Upstream Providers: Supports
file
-based static upstreams, dynamic service discovery viaConsul
, and upcomingKubernetes
integration - 🔁 Hot Reloading: Modify upstreams on the fly via
upstreams.yaml
— no restart needed - 🔮 Automatic WebSocket Support: No special config required — connection upgrades are handled seamlessly
- 🔮 Upcoming Automatic GRPC Support: Zero config for GRPC upstreams and downstreams
- 🔐 TLS Termination: Fully supports TLS for incoming and upstream traffic
- 🛡️ Built-in Auth Support:
- 🧠 CORS & Header Injection: Global and per-route header configuration
- 🧪 Health Checks: Pluggable health check methods for upstreams
- 🛰️ Remote Config Push: Lightweight HTTP API to update configs from CI/CD or other systems
.
├── main.yaml # Main configuration loaded at startup
├── upstreams.yaml # Watched config with upstream mappings
├── etc/
│ ├── server.crt # TLS certificate (required if using TLS)
│ └── key.pem # TLS private key
proxy_address_http
:0.0.0.0:6193
(HTTP listener)proxy_address_tls
:0.0.0.0:6194
(TLS listener, optional)config_address
:0.0.0.0:3000
(HTTP API for remote config push)upstreams_conf
:etc/upstreams.yaml
(location of upstreams config)log_level
:info
(verbosity of logs)hc_method
:HEAD
,hc_interval
:2s
(upstream health checks)user
Optional. Drop privileges to regular user. To bind to privileged ports. Requires to start as root.group
Optional. Drop privileges to regular group- Other defaults: thread count, keep-alive pool size, etc.
provider
:file
orconsul
- File-based upstreams define:
- Hostnames and routing paths
- Backend servers (load-balanced)
- Optional request headers
- Optional TLS for upstreams
- Global headers (e.g., CORS) apply to all proxied responses
- Optional authentication (Basic, API Key, JWT) — currently commented for example
Download the prebuilt binary for your architecture from releases section of GitHub repo
Make the binary executable chmod 755 ./gazan
and run .
./gazan -c path/to/main.yaml
cat > /etc/systemd/system/gazan.service <<EOF
[Service]
Type=forking
PIDFile=/run/gazan.pid
ExecStart=/bin/gazan -d -c /etc/gazan.conf
ExecReload=kill -QUIT $MAINPID
ExecReload=/bin/gazan -u -d -c /etc/gazan.conf
EOF
systemctl enable gazan.service.
systemctl restart gazan.service.
A sample upstreams.yaml
entry:
myhost.mydomain.com:
paths:
"/":
ssl: false
headers:
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
- "X-Proxy-From:Hopaaaaaaaaaaaar"
servers:
- "127.0.0.1:8000"
- "127.0.0.2:8000"
"/foo":
ssl: true
headers:
- "X-Another-Header:Hohohohoho"
servers:
- "127.0.0.4:8000"
- "127.0.0.5:8000"
This means:
- Requests to
myhost.mydomain.com/
will be load balanced to127.0.0.1
and127.0.0.2
servers via plain http. - Requests to
myhost.mydomain.com/foo
will be load balanced to127.0.0.4
and127.0.0.5
servers via https. - You can choose any path, deep nested paths are supported, the best match will be chosen
- Additional headers will be injected into the request.
- TLS is disabled for upstreams (but can be enabled).
- Changes to
upstreams.yaml
are applied immediately. - No need to restart the proxy — just save the file.
To enable TLS for Proxy server: Currently only OpenSSL is supported, working on Boringssl and Rustls
- Set
proxy_address_tls
inmain.yaml
- Provide
tls_certificate
andtls_key_file
You can push new upstreams.yaml
over HTTP to config_address
(:3000
by default). Useful for CI/CD automation or remote config updates.
curl -XPOST --data-binary @./etc/upstreams.txt 127.0.0.1:3000/conf
- Adds authentication to all requests.
- Only one method can be active at a time.
basic
: Standard HTTP Basic Authentication requests.apikey
: Authentication viax-api-key
header, which should match the value in config.jwt
: JWT authentication implemented vix-jwt-token
header.- To obtain JWT token, you should send generate request to built in api server's
/jwt
endpoint. masterkey
: should match configuredmasterkey
inmain.yaml
andupstreams.yaml
.owner
: Just a placeholder, can be anything.valid
: Time in minutes during which the generated token will be valid.
- To obtain JWT token, you should send generate request to built in api server's
Example JWT token generateion request
PAYLOAD='{
"masterkey": "910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774",
"owner": "valod",
"valid": 1
}'
TOK=`curl -s -XPOST -H "Content-Type: application/json" -d "$PAYLOAD" http://127.0.0.1:3000/jwt | cut -d '"' -f4`
echo $TOK
Example Request with JWT token
curl -H "x-jwt-token: ${TOK}" -H 'Host: myip.mydomain.com' http://127.0.0.1:6193/
Example Request with API Key
curl -H "x-api-key: ${APIKEY}" --header 'Host: myip.mydomain.com' http://127.0.0.1:6193/
Example Request with Basic Auth
curl -u username:password -H 'Host: myip.mydomain.com' http://127.0.0.1:6193/
- Uses Pingora under the hood for efficiency and flexibility.
- Designed for edge proxying, internal routing, or hybrid cloud scenarios.
- Transparent, fully automatic WebSocket upgrade support.
- Upcoming transparent, fully automatic GRPC proxy.
- Upcoming Kubernetes integration
- HTTP2 ready.