diff --git a/.env.example b/.env.example index a0a4609..2ceed63 100644 --- a/.env.example +++ b/.env.example @@ -13,7 +13,7 @@ PROXY_SECRET= # Example: "10.0.0.0/8,172.16.0.0/12" ALLOWED_CIDR= -# API key header: a request carrying this header bypasses the IP allowlist (IP OR key). +# API key header: a request carrying this header bypasses both the IP allowlist and PROXY_SECRET check. # Set both or neither. Name: [A-Za-z0-9-], value: [A-Za-z0-9._~+/=-]. Only matters if ALLOWED_CIDR is set. # Generate value with: openssl rand -hex 32 AUTH_HEADER_NAME= diff --git a/README.md b/README.md index 66d646a..0448d8f 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ 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://:8082/...`) with the `X-Proxy-Token` header and the original API key. -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. +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; a valid key header satisfies this check too) — 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`, 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. diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 3984d28..c67374c 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -22,7 +22,7 @@ if [ -z "${ACME_EMAIL}" ]; then exit 1 fi -# --- 1. API key header (optional bypass of the IP allowlist) --- +# --- 1. API key header (optional: bypasses both the IP allowlist and the token check) --- KEY_MATCH="" if [ -n "${AUTH_HEADER_NAME}" ] || [ -n "${AUTH_HEADER_VALUE}" ]; then if [ -z "${AUTH_HEADER_NAME}" ] || [ -z "${AUTH_HEADER_VALUE}" ]; then @@ -67,12 +67,15 @@ GUARDRULE echo "[entrypoint] IP allowlist configured: ${CIDR_LIST}" fi -# --- 3. Token auth (legacy, applied in addition to the checks above) --- +# --- 3. Token auth (legacy X-Proxy-Token; a valid key header also satisfies it) --- if [ -z "${PROXY_SECRET}" ]; then echo "[entrypoint] PROXY_SECRET is not set — token auth disabled (open mode)" else cat >> "${MATCHERS}" <> "${GUARD}" <