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?