Hello everyone,
I have a traefik service running on Docker Swarm, and it seems like there is an issue regarding X-Real-IP
and X-Forwarded-For
headers
This is the output I am getting
"[INFO] X-Forwarded-For: , ip: 10.0.0.2, X-Real-IP: 10.0.0.2"
The domain.com
directly points to the server where traefik is listening on via A
record, so there is no LB's in front currently. The 10.0.0.2
is also a bit weird, the docker network is 10.0.1.0/24
, and my VPC CIDR is set to 10.0.1.0/24
as well.
Any help is appreciated
> docker network inspect internal
[
{
"Name": "internal",
"Id": "npnme4jlce9k58h02z9mf0zmj",
"Created": "2025-01-15T07:22:28.526343178Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.1.0/24",
"Gateway": "10.0.1.1"
}
]
},
And this is my plugin code that is printing this
func (d *Decoder) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
d.setForwardedHeaders(req)
}
func (d *Decoder) setForwardedHeaders(req *http.Request) {
ip := d.clientIP(req)
d.logInfo(fmt.Sprintf(
"X-Forwarded-For: %s, ip: %s, X-Real-IP: %s",
req.Header.Get("X-Forwarded-For"),
ip,
req.Header.Get("X-Real-IP"),
))
if ip == "" {
return
}
oldXFF := req.Header.Get("X-Forwarded-For")
if oldXFF == "" {
req.Header.Set("X-Forwarded-For", ip)
}
xRealIP := req.Header.Get("X-Real-IP")
if xRealIP == "" {
req.Header.Set("X-Real-IP", ip)
}
}
func (d *Decoder) clientIP(req *http.Request) string {
xff := req.Header.Get("X-Forwarded-For")
if xff != "" {
parts := strings.Split(xff, ",")
ipStr := strings.TrimSpace(parts[0])
if net.ParseIP(ipStr) != nil {
return ipStr
}
}
remoteIP, _, err := net.SplitHostPort(req.RemoteAddr)
if err == nil && net.ParseIP(remoteIP) != nil {
return remoteIP
}
return ""
}
My file provider
middleware:
query-decoder:
plugin:
decoder:
headers:
X-Processed-By: "X"
fps-forward-header:
headers:
customRequestHeaders:
Host: 'remote_url'
routers:
fps-forward-router:
rule: 'Host(`domain.com`) && PathPrefix(`/path`)'
priority: 100
entryPoints:
- websecure
service: fps-forward-service
middlewares:
- query-decoder
- fps-forward-header
services:
fps-forward-service:
loadBalancer:
servers:
- url: 'https://external_url'
passHostHeader: true
Static config
api:
insecure: true
dashboard: true
experimental:
localPlugins:
decoder:
moduleName: traefik/decoder
log:
# level: INFO
level: DEBUG
format: json
entrypoints:
web:
address: :80
websecure:
address: :443
http:
tls:
domains:
- main: domain.com
providers:
swarm:
endpoint: unix:///var/run/docker.sock
exposedByDefault: false
file:
filename: /etc/traefik/providers/file.prod.yml
My stack containing traefik
networks:
internal:
external: true
services:
traefik:
image: traefik/traefik:experimental-master
command: --configFile=/etc/traefik/traefik.prod.yml
deploy:
placement:
constraints: [node.role==manager]
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /config/traefik:/etc/traefik
- /data/traefik/plugins:/plugins-local/src/seotraefik
networks:
- internal
Docker inspect
"NetworkSettings": {
"Bridge": "",
"SandboxID": "ccb10d1f8595e6ff955a45c6e3cc6361979cbe0c99780e3aeabcbc4ffe227185",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": null
},
"SandboxKey": "/var/run/docker/netns/ccb10d1f8595",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"ingress": {
"IPAMConfig": {
"IPv4Address": "10.0.0.106"
},
"Links": null,
"Aliases": [
"732f837a7313"
],
"NetworkID": "kosrbb1k154jmn7smd2qj50l2",
"EndpointID": "e568eeb026d5e1ec8c5dc27c4725a239ecc7ae75e255540502e989891ffa1fed",
"Gateway": "",
"IPAddress": "10.0.0.106",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:0a:00:00:6a",
"DriverOpts": null
},
"internal": {
"IPAMConfig": {
"IPv4Address": "10.0.1.125"
},
"Links": null,
"Aliases": [
"732f837a7313"
],
"NetworkID": "npnme4jlce9k58h02z9mf0zmj",
"EndpointID": "89914a4cd9814ebc393fea790452d67d66eb03ce054f0e28c724e74e77b9b36c",
"Gateway": "",
"IPAddress": "10.0.1.125",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:0a:00:01:7d",
"DriverOpts": null
}
}
}
}
]