You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: static trustedIPs helper for entrypoint forwardedHeaders (#118)
Adds a guided Trusted IPs helper in the Static Config editor that writes
forwardedHeaders.trustedIPs onto an entrypoint, so Traefik trusts
X-Forwarded-For from proxies you control (Cloudflare, your own LAN/proxies).
- New POST /api/static/trusted-ips/preview parses the current static YAML,
merges the selected sources additively (dedup by normalized network) and
returns the exact new raw plus a preview (existing / added / invalid /
final). It never writes to disk; the result is saved through the existing
static-config save path, so it keeps the backup and restart flow and works
on the Host and on remote agents alike.
- Cloudflare IPv4+IPv6 ranges are hardcoded with a capture date and refreshed
on release (no runtime fetch). Private-range and free-form CIDR sources are
also offered; invalid CIDRs are flagged and skipped.
- UI: a Trusted IPs button in the Static Config header (Host and agent), a
preview modal with a global/restart warning that links to the Client IP
Diagnostic, and a trustedIPs count badge on each entrypoint row.
- Entrypoint edits preserve forwardedHeaders, so the helper never clobbers a
hand-authored value.
- Docs: a Trusted IPs helper section in docs/static.md including a note on
how to refresh the hardcoded Cloudflare ranges.
Copy file name to clipboardExpand all lines: docs/static.md
+20Lines changed: 20 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -59,6 +59,26 @@ Multiple edits in one session only require a single restart.
59
59
60
60
---
61
61
62
+
## Trusted IPs helper
63
+
64
+
Behind a proxy such as Cloudflare, Traefik only believes `X-Forwarded-For` from sources listed in an entrypoint's `forwardedHeaders.trustedIPs`. Until those are set, your logs, CrowdSec, `ipAllowList` and the login limiter all see the proxy IP instead of the real client. The **Trusted IPs** button in the Static Config header opens a guided helper that writes that field for you.
65
+
66
+
1. Pick the target entrypoint (for example `websecure`). Any `trustedIPs` already configured are shown.
67
+
2. Choose one or more sources:
68
+
-**Cloudflare edge ranges** - the full IPv4 + IPv6 set, hardcoded with a capture date. Nothing is fetched at runtime.
-**Your own proxies / LAN** - free-form CIDRs or single IPs, one per line. Invalid entries are flagged and skipped.
71
+
3. Click **Preview change** to see exactly which ranges will be added. Existing entries are kept, and anything already trusted is deduplicated - the helper only ever adds.
72
+
4. Click **Apply & Save** to stage the change into the static config, back it up, and save. As with any static change, a **Restart required** banner then appears.
73
+
74
+
Because `trustedIPs` lives in the static config, this is global and needs a Traefik restart. Every trusted range can forge client IPs downstream, so only add proxies you control. Use the [Client IP Diagnostic](hardening.md) to confirm what actually reaches the app before and after. The helper works for the Host and for remote agents.
75
+
76
+
::: tip Refreshing the Cloudflare ranges
77
+
The hardcoded ranges live in `_CLOUDFLARE_IPS_V4` / `_CLOUDFLARE_IPS_V6` in `app.py`, sourced from [cloudflare.com/ips](https://www.cloudflare.com/ips/) (`/ips-v4` + `/ips-v6`). They are refreshed on release; replace both lists from that source and bump `_CLOUDFLARE_IPS_CAPTURED`.
html+=`<div class="text-xs px-3 py-2 rounded" style="background:rgba(234,179,8,0.1);color:#ca8a04">Nothing new to add - every selected range is already trusted on <span class="font-mono">${_esc(d.entrypoint)}</span>.</div>`;
0 commit comments