Bezpieczeństwo
Fail-closed admin API, trusted proxies, walidacja URL, hop-by-hop headers, sekrety w environment i utwardzony kontener.
Model bezpieczeństwa#
Proxy jest projektowane z założeniem, że stoi na granicy sieci — każda warstwa ma bezpieczny default.
Admin API: fail-closed#
- Bearer token z
ADMIN_TOKEN, porównanie constant-time. - Bez tokenu API nie istnieje — nie ma „pustego hasła”.
- Security headers na odpowiedziach admina.
export ADMIN_TOKEN=$(openssl rand -hex 32)
Client IP i trusted proxies#
X-Forwarded-For jest wiarygodny tylko od zaufanych pośredników:
rate_limit:
trusted_proxies:
- 10.0.0.0/8
- 172.16.0.0/12
Bez tej konfiguracji client-supplied forwarding headers są ignorowane, a używany jest socket address. Chroni to przed spoofingiem IP w rate limitingu i logach.
Walidacja URL backendów#
Konfiguracja odrzuca backend URL z:
- credentials (
http://user:pass@host), - query string (
?x=1), - fragmentem (
#frag).
Dozwolone są tylko http i https z hostem.
Hop-by-hop headers#
Nagłówki hop-by-hop są stripowane z requestów do upstreamu zgodnie z RFC 7230: Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, TE, Trailer, Transfer-Encoding, Upgrade.
Sekrety#
| Sekrety | Gdzie |
|---|---|
ADMIN_TOKEN | environment |
REDIS_PASSWORD | environment |
GRAFANA_ADMIN_PASSWORD | environment |
Nigdy w YAML, nigdy w obrazie kontenera, nigdy w logach.
Utwardzony kontener#
Obraz Docker:
- multi-stage build — kompilator nie trafia do runtime,
- non-root user,
- read-only root filesystem,
- dropped capabilities,
- certyfikaty TLS montowane read-only.
FROM golang:1.26-alpine AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /proxy ./cmd/server
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /proxy /proxy
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/proxy"]
TLS#
tls:
cert_file: /etc/tls/server.crt
key_file: /etc/tls/server.key
- Oba pliki muszą istnieć — inaczej proxy odmawia startu.
- TLS 1.2+.
- Certyfikaty montuj read-only.
Checklist produkcyjny#
- Ustaw silny
ADMIN_TOKEN(32+ bajty losowości). - Skonfiguruj
rate_limit.trusted_proxiesdla swojego LB/CDN. - Ogranicz
/admin/*i/metricsdo sieci wewnętrznej. - Włącz TLS termination na proxy lub przed nim.
- Uruchom kontener jako non-root z read-only FS.
- Zostaw retry domyślne — nie ponawiaj requestów z body.
- Monitoruj
rate_limit_errors_total(fail-open Redis).
Rate limiting fail-open
Przy awarii Redis ruch płynie dalej bez limitów (availability over strict limiting). Jeśli potrzebujesz twardego limitu za wszelką cenę, monitoruj rate_limit_errors_total i alertuj — to świadomy trade-off, nie przeoczenie.