A Traefik plugin that intelligently sets the X-Real-Ip
header by selecting a configurable IP address (by index/depth) from the X-Forwarded-For
header. By default, it uses the first IP, ensuring your backend services see the correct client IP, even behind multiple proxies! π
For incoming requests, this plugin:
- π΅οΈββοΈ Looks for the
X-Forwarded-For
header. - πͺ Splits the header value by commas to get a list of IP addresses.
- π― Extracts an IP from this list based on the configured
depth
(index). Defaults todepth: 0
(the first IP). - βοΈ Overwrites
X-Real-Ip
with that value if the depth is valid for the list of IPs.
Add to Static configuration
Ensure you are using the latest version
## Static configuration
experimental:
plugins:
traefik-xff-to-xrealip:
moduleName: github.com/jeppestaerk/traefik-xff-to-xrealip
version: v0.1.3
Remember to add your proxy IPs to the forwardedHeaders.trustedIPs
entryPoint configuration in Traefik. Without this, Traefik won't trust the X-Forwarded-For header from your proxies, and this plugin won't work properly.
## Static configuration
entryPoints:
web:
address: ":80"
forwardedHeaders:
trustedIPs:
- "127.0.0.1/32"
- "192.168.1.5" # Your proxy IP eg. the ip of the machine running Cloudflare tunnel
- "172.16.0.0/16" # trust everytihing from docker eg. if running Cloudflare tunnel in docker container
websecure:
address: ":443"
forwardedHeaders:
trustedIPs:
- "127.0.0.1/32"
- "192.168.1.5" # Your proxy IP eg. the ip of the machine running Cloudflare tunnel
- "172.16.0.0/16" # trust everytihing from docker eg. if running Cloudflare tunnel in docker container
Ensure you add forwardedHeaders.trustedIPs
to all your entryPoints, especially if you redirect HTTP to HTTPS.
Add to dynamic configuration
## Dynamic configuration
http:
middlewares:
xff2realip: # Name your middleware instance
plugin:
traefik-xff-to-xrealip: {} # Default depth (0)
# or for a custom depth:
# traefik-xff-to-xrealip:
# depth: 1
## Dynamic configuration
http:
routers:
my-app:
rule: Host(`myapp.example.com`)
service: my-app
middlewares:
- xff2realip@file
Default Behavior (depth: 0)
< 8000 svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">X-Forwarded-For: 203.0.113.5, 10.0.0.1, 192.168.1.100
http:
middlewares:
xff2realip:
plugin:
traefik-xff-to-xrealip: {}
X-Real-Ip: 203.0.113.5
X-Forwarded-For: 203.0.113.5, 10.0.0.1, 192.168.1.100
http:
middlewares:
xff2realip:
plugin:
traefik-xff-to-xrealip:
depth: 1 # Selects the second IP (index 1)
X-Real-Ip: 10.0.0.1
This plugin must be built or declared through Traefik's experimental plugin system.
You can run Traefik with plugins using Docker, Kubernetes, or binary.
go test ./...
GitHub Actions CI is set up to run build and tests on every commit or pull request.
MIT © 2025 Jeppe Stærk