Traefik v2.1.4: X-Forwarded-For header doet not pass visitor IP when using IPv6

We use Traefik as a front-end for multiple containers running websites, and some of these sites need an ip-whitelist.

In order to do this we create an ipwhitelist middleware that is part of a chain. We craft a docker run command shown below, filled using parameters passed by our CI/CD pipeline:

docker run \
                --name $name \
                --restart unless-stopped \
                -l traefik.enable=true \
                -l "traefik.http.routers.$name.rule=Host(\"$hostheaders\")" \
                -l traefik.http.routers.$name.entrypoints=http,https \
                -l traefik.http.routers.$name.tls=true \
                -l traefik.http.routers.$name.tls.certresolver=letsEncryptResolver \
                -l traefik.http.services.$name.loadbalancer.passhostheader=true \
                -l traefik.http.routers.$name.middlewares=securedWhitelist-$name \
                -l traefik.http.middlewares.securedWhitelist-$name.chain.middlewares=https-redirect,hsts-header@file,optional-ipwhitelist-$name \
                -l traefik.http.middlewares.optional-ipwhitelist-$name.ipwhitelist.sourcerange=$whitelist \
                -l traefik.http.middlewares.optional-ipwhitelist-$name.ipwhitelist.useXForwardedFor=true \
                -l traefik.http.middlewares.https-redirect.redirectscheme.scheme=https \
               -l traefik.http.middlewares.https-redirect.redirectscheme.permanent=true \
               -l traefik.http.middlewares.https-redirect.redirectscheme.port=443 \
                -l traefik.http.services.$name.loadbalancer.server.port=$port \
                -d $image

So, the whitelist middleware expects the $whitelist parameter, which is a set of comma separated ip-addresses.

This is all fine and pretty cool, but it depends on the correct ip-address being passed to this middleware and what we actually receive is the IP-address of the Traefik instance. See this snippet of the containous/whoami image:

X-Forwarded-For: 172.17.0.1
X-Forwarded-Host: reallycool.hostname.org
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: 20ec8fde9d29
X-Real-Ip: 172.17.0.1

So, that is useless for our purposes.

However, the above is true when you connect to this instance using IPv6! When you connect using IPv4 containous/whoami tells us the following:

X-Forwarded-For: 89.20.***.***
X-Forwarded-Host: reallycool.hostname.org
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: 20ec8fde9d29
X-Real-Ip: 89.20.***.***

So, when Traefik routes traffic to its containers and is accessed via IPv6 it uses the internal IPv4 network addresses and does not pass the correct IPv6 address in the X-forwarded-for and X-real-ip headers.

You could say this is a bug, but maybe this is something you can prevent if you use IPv6 in the docker network? We switched back from using swam mode because IPv6 was a horror to configure in the docker network.

Does anyone have this same issue?

Hello,

Have you configure the forwarded-header options?

https://docs.traefik.io/v2.1/routing/entrypoints/#forwarded-header

I have looked in to those headers but it was unclear to me what IP-addresses should be added as trusted.

[entryPoints.web.forwardedHeaders]
     trustedIPs = ["127.0.0.1/32", "192.168.1.7"]

Should the trustedIPs be the addresses of the traefik instance itself? The docker host is an single instance without any additional proxies in front of it.

For now I am using the following static configuration:

[entryPoints]
  [entryPoints.http]
  address = ":80"

    [entryPoints.http.forwardedHeaders]
      trustedIPs = ["127.0.0.1/32", "172.17.0.1/32"]
      insecure = true

  [entryPoints.https]
  address = ":443"
    [entryPoints.https.forwardedHeaders]
      trustedIPs = ["127.0.0.1/32", "172.17.0.1/32"]
      insecure = true

I'm seeing the same issue, we recently saw a few clients on IPv6 and found their IPv6 was blank in our case, version traefik:v2.2

Have you found any solution to this?

I found that the forwardedHeaders forwarded for instance the username from basic auth.

But X_FORWARDED_FOR is still 10.1.0.1, the IP of traefik, not the client.

1 Like

A year later, with traefik 2.5.4 I get the real client ip in X-Forwarded-For if I use ipv4, but the IPv6Gateway fd30:1::1 on the proxy network, when I use IPv6

I'm using the image: "traefik/whoami" to see this.

I'm seeing something along these lines, all I get in the X-Forwarded-For is the actual K8S host, rather than the client (i.e. my laptop).

Add this to /etc/docker/daemon.json:

 "experimental": true, 
 "ip6tables": true 

Like

{
  "ipv6": true,
  "fixed-cidr-v6": "fd..::/64",
  "experimental": true, 
  "ip6tables": true 
}