Metainformationen zur Seite
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| server:traefik [2025/09/25 14:50] – walbaum | server:traefik [2025/09/25 15:05] (aktuell) – walbaum | ||
|---|---|---|---|
| Zeile 708: | Zeile 708: | ||
| # sniStrict: true | # sniStrict: true | ||
| </ | </ | ||
| + | |||
| + | ===== Traefik security headers and CSP (DRY config) ===== | ||
| + | |||
| + | Last updated: 25.09.2025 | ||
| + | |||
| + | ==== High‑level design ==== | ||
| + | |||
| + | * One baseline for security headers: security-headers-base | ||
| + | * Small header variants you can compose: -noindex, -allowframes, | ||
| + | * Separate CORS middlewares: | ||
| + | * One base CSP: CSP-base (+ per‑service CSP middlewares that only add what’s different) | ||
| + | * Chains compose the above into per‑service “one-liners” you reference from docker-compose labels. | ||
| + | |||
| + | ==== Security headers ==== | ||
| + | |||
| + | === Baseline (security-headers-base) === | ||
| + | |||
| + | Sets the shared hardening and sane defaults. Highlights: | ||
| + | |||
| + | * addVaryHeader: | ||
| + | * contentTypeNosniff: | ||
| + | * browserXssFilter: | ||
| + | * referrerPolicy: | ||
| + | * permissionsPolicy: | ||
| + | * HSTS: forceSTSHeader: | ||
| + | * X-Frame-Options: | ||
| + | * TLS/proxy awareness: sslRedirect: | ||
| + | * Scrub response headers (customResponseHeaders): | ||
| + | * Upstream request header: customRequestHeaders.X-Forwarded-Proto: | ||
| + | Rationale: | ||
| + | |||
| + | * Default deny framing (clickjacking defense); enable per service via -allowframes and control who via CSP. | ||
| + | * Keep includeSubdomains off by default to avoid accidental HSTS lock-in; use the variant when needed. | ||
| + | |||
| + | ==== Variants you can compose ==== | ||
| + | |||
| + | * security-headers-noindex | ||
| + | * Same as base, but X-Robots-Tag: | ||
| + | * security-headers-allowframes | ||
| + | * Same as base, but frameDeny: false (use CSP frame-ancestors to specify who can frame) | ||
| + | * security-headers-hsts-subdomains | ||
| + | * Same as base, but stsIncludeSubdomains: | ||
| + | * cache-public | ||
| + | * Adds Cache-Control: | ||
| + | |||
| + | ==== CORS middlewares ==== | ||
| + | |||
| + | * cors-default | ||
| + | * accessControlAllowMethods: | ||
| + | * accessControlAllowHeaders: | ||
| + | * accessControlMaxAge: | ||
| + | * addVaryHeader: | ||
| + | * cors-collections | ||
| + | * Inherits cors-default + accessControlAllowOriginList: | ||
| + | * https:// | ||
| + | * https:// | ||
| + | |||
| + | ==== Content Security Policy (CSP) ==== | ||
| + | |||
| + | === Base CSP (CSP-base) === | ||
| + | |||
| + | Applies to most services unchanged. | ||
| + | |||
| + | <code yaml> CSP-base: headers: contentSecurityPolicy: | ||
| + | |||
| + | Notes: | ||
| + | |||
| + | * Only one CSP header is honored. Don’t stack multiple CSP middlewares in a single chain; “last header wins.” | ||
| + | * Use Report-Only during testing by duplicating to contentSecurityPolicyReportOnly. | ||
| + | |||
| + | ==== How to add a new service ==== | ||
| + | |||
| + | * If defaults are enough: | ||
| + | * Use secure-global chain. | ||
| + | * If it needs framing: | ||
| + | * Use security-headers-allowframes in the chain and set CSP frame-ancestors to the exact allowlist. | ||
| + | * If it needs special CORS: | ||
| + | * Add or create a cors-< | ||
| + | * If it needs special CSP: | ||
| + | * Copy CSP-base to CSP-< | ||
| + | * Wire it in docker-compose: | ||
| + | * traefik.http.routers.< | ||
| + | ==== Verification (quick commands) ==== | ||
| + | |||
| + | * Check headers: | ||
| + | * curl -sI https://< | ||
| + | * Check CSP is present (and only once): | ||
| + | * curl -sI https://< | ||
| + | * Check CORS (preflight example): | ||
| + | * curl -sI -X OPTIONS https://< | ||
| + | * Check robots indexing: | ||
| + | * curl -sI https://< | ||
| + | |||
| + | ==== Operational notes ==== | ||
| + | |||
| + | * Prefer CSP frame-ancestors over X-Frame-Options for precise embedding control. | ||
| + | * Consider a Report-Only CSP during rollouts (duplicate middleware with contentSecurityPolicyReportOnly). | ||
| + | * HSTS includeSubdomains is opt-in via variant to avoid unintentional hard lock-in. | ||
| + | * If a page doesn’t render: check the browser console for CSP violations first; add only the specific host/type needed. | ||
| + | ==== Appendix: Anchor usage ==== | ||
| + | We used YAML anchors to stay DRY: | ||
| + | |||
| + | * & | ||
| + | * & | ||
| + | This keeps the source config compact while allowing targeted overrides. | ||
| ===== Traefik v3 Healthcheck (Docker) ===== | ===== Traefik v3 Healthcheck (Docker) ===== | ||
| Zeile 815: | Zeile 920: | ||
| * [[https:// | * [[https:// | ||
| - | Authored for SMNS IT by Chattie and AI Programmer | + | Authored for SMNS IT by Chattie and AI Programmer |