⚠️ Status: untested. This extension is provided as-is and has not been tested in production. Please feel free to fork, modify, improve, and open pull requests.Licensed under GNU GPLv3 (see LICENSE).
An Envoy ext_authz integration: a small external
authorization HTTP service (Go) that consults the
ip-block.com decision API, plus the Envoy config that
wires the ext_authz filter to it.
- Tested against: Envoy 1.38.x (latest stable, 2026).
- Mode: HTTP
ext_authz(no gRPC/proto dependencies — the service is plainnet/http).
| File | Purpose |
|---|---|
main.go |
The ext_authz HTTP check server. |
go.mod |
Module (standard library only). |
envoy.yaml |
Envoy listener + ext_authz filter + clusters. |
client -> Envoy (listener :8080)
| ext_authz HTTP check (1s timeout)
v
ip-block service (:9000) --POST /v1/check--> api.ip-block.com
| 200 allow / 403 block / 302 redirect
v
allow: proxy to app_service | block: Envoy returns the deny response
The service returns 200 to allow, 403 to block (or 302 with Location
when IPB_BLOCK_ACTION=redirect). Envoy relays a non-2xx auth response straight to
the client.
cd extensions/Envoy
go build -o ip-block-authz .
IPB_SITE_ID=your-site-id \
IPB_API_KEY=your-api-key \
IPB_LISTEN=:9000 \
./ip-block-authz(You can also run it under systemd; it is a normal long-lived HTTP server.)
Merge the ext_authz http filter and the ip_block_authz cluster from
envoy.yaml into your config. Key points:
http_service.server_uri.timeout: 1senforces the 1-second budget.failure_mode_allow: truemakes Envoy fail open if the auth service itself is unreachable (the service also fails open on ip-block.com API errors internally).authorization_request.allowed_headersforwardsx-forwarded-for,user-agentandrefererto the checker.authorization_response.allowed_client_headerslets theLocation/Content-Typefrom a deny response reach the client (needed for redirect blocking).use_remote_address: true+xff_num_trusted_hopsensure Envoy computes a correctX-Forwarded-For; the service reads the left-most entry as the client IP.
| Var | Default | Meaning |
|---|---|---|
IPB_LISTEN |
:9000 |
Listen address of the check service. |
IPB_ENABLED |
1 |
Master switch (0 = always allow). |
IPB_SITE_ID |
— (required) | Site id. |
IPB_API_KEY |
— (required) | API key (JSON body). |
IPB_API_URL |
https://api.ip-block.com/v1/check |
Endpoint. |
IPB_FAIL_OPEN |
1 |
Allow on error/timeout; 0 fails closed. |
IPB_CACHE_TTL |
300 |
Per-IP cache seconds (0 disables). |
IPB_TIMEOUT_MS |
1000 |
API timeout. |
IPB_REAL_IP_HEADER |
X-Forwarded-For |
Header carrying the client IP. |
IPB_BLOCK_ACTION |
403 |
403 or redirect. |
IPB_BLOCK_REDIRECT |
https://www.ip-block.com/blocked.php |
Redirect target. |
IPB_BLOCK_MESSAGE |
Access denied. |
403 body. |
IPB_WHITELIST |
— | Comma-separated IPs never checked. |
- Blocks only on
{"action":"block"}; otherwise allows (subject toIPB_FAIL_OPEN). - API errors are not cached; the next request retries.
allow/blockdecisions are cached forIPB_CACHE_TTL. - Whitelisted IPs short-circuit before the cache/API.
GET /healthzreturns 200 for readiness/liveness probes.
- The cache is in-memory per service instance. Run one instance per Envoy (or a small pool); each keeps its own short-TTL cache.
- For very high throughput, front the service with several replicas behind the
ip_block_authzcluster and/or swap the in-memory cache for Redis.