feat: add header key auth as alternative to IP allowlist
Build Admin / Build image (push) Successful in 43s

This commit is contained in:
vasyansk committed 2026-10-24 14:20:52 +07:00
1 parent 1a4ad47c77
commit c144d0967f
4 files changed
+48 -7

No files matched your search

+5 -3
View File
@@ -37,6 +37,8 @@ DOMAIN=proxy.bildme.ru
ACME_EMAIL=you@example.com
PROXY_SECRET=<openssl rand -hex 32>
ALLOWED_CIDR=10.0.0.0/8,172.16.0.0/12
AUTH_HEADER_NAME=X-Api-Key # optional: access from any IP by header
AUTH_HEADER_VALUE=<openssl rand -hex 32>
docker compose up -d
```
@@ -207,7 +209,7 @@ option.WithHeader("X-Proxy-Token", os.Getenv("PROXY_SECRET")),
### `403 {"error":"ip_not_allowed"}`
The caller's source IP is not in `ALLOWED_CIDR`. Check the effective list:
The caller's source IP is not in `ALLOWED_CIDR` and the request has no valid `AUTH_HEADER_NAME: AUTH_HEADER_VALUE` header. Check the effective list:
```bash
docker exec api-proxy cat /etc/caddy/matchers.caddy
@@ -240,8 +242,8 @@ docker inspect --format='{{.State.Health.Status}}' api-proxy
## How It Works
1. A k8s pod sends a request to `https://proxy.bildme.ru/elevenlabs/v1/text-to-speech/...` (or `http://<vm-ip>:8082/...`) with the `X-Proxy-Token` header and the original API key.
2. Caddy checks the source IP against `ALLOWED_CIDR` and validates `X-Proxy-Token` — rejecting with 403 if either fails. `/health` is answered before both guards.
2. Caddy lets the request through if the source IP is in `ALLOWED_CIDR` **or** it carries the `AUTH_HEADER_NAME: AUTH_HEADER_VALUE` header, then validates `X-Proxy-Token` (if `PROXY_SECRET` is set) — rejecting with 403 on failure. `/health` is answered before both guards.
3. `handle_path` strips the prefix (`/elevenlabs/`, `/openai/`, `/telegram/`, `/openrouter/`, `/deepseek/`) and the request is forwarded over HTTPS with the upstream host as both `Host` header and TLS SNI.
4. `X-Proxy-Token` and all IP-leaking headers (`X-Forwarded-*`, `X-Real-IP`, `True-Client-IP`, `CF-Connecting-IP`, `X-Client-IP`, `Forwarded`, `Via`) are removed before forwarding; API keys pass through unchanged.
4. `X-Proxy-Token`, the `AUTH_HEADER_NAME` header and all IP-leaking headers (`X-Forwarded-*`, `X-Real-IP`, `True-Client-IP`, `CF-Connecting-IP`, `X-Client-IP`, `Forwarded`, `Via`) are removed before forwarding; API keys pass through unchanged.
5. Responses stream back unbuffered (`flush_interval -1`) — critical for binary audio, SSE token streams and Telegram long-polling.
6. Access control fragments (`matchers.caddy`, `guard.caddy`) are generated from environment variables at container start by `docker-entrypoint.sh`.