Issue using ipWhiteList with "ipStrategy.excludedIPs" / "ipStrategy.depth" setting

Hey guys,

I'm trying to use the ipWhiteList middleware but I am getting a "Forbidden" message when trying to access. I ran into an issue with the excludedIPs setting and the depth setting.

TLDR My theory is the following:

  • When using excludedIPs and the X-Forwarded-For header only has 1 ip address then it will always return an empty IP address.
  • The depth setting in the documentation is incorrect. Depth actually starts at 0 and not 1.

My setup for context

  • I am running whoami as one of the services behind traefik to see request info such as headers.
  • I am using cloudflare tunnel (IP address 172.22.0.X)
  • I am running traefik in a docker container in the same docker network as whoami and cloudflared
  • traefik is hosted on port 80 of the machine
  • My computer's IP address is 192.168.1.X in these examples
  • My public IP is x.x.x.x in these examples

whoami response via cloudflare tunnel

X-Forwarded-For: x.x.x.x, 172.22.0.X
X-Forwarded-Host: mydomain.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: ...
X-Is-Trusted: yes
X-Real-Ip: x.x.x.x

whoami response via internal IP

I'm using a DNS server to rewrite the entry for mydomain.com to be the IP address of where traefik is hosted.

X-Forwarded-For: x.x.x.x, 172.22.0.X
X-Forwarded-Host: mydomain.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: ...
X-Is-Trusted: yes
X-Real-Ip: x.x.x.x

excludedIPs setting

My theory is when there is only 1 IP address in the X-Forwarded-For header the excludedIPs setting always returns an empty IP address.

Here is the middleware configuration I have setup:

  middlewares:
    known-ips-internal:
      ipWhiteList:
        sourceRange:
          - "127.0.0.1/32"
          - "10.0.0.0/8"
          - "172.16.0.0/12"
          - "192.168.0.0/16"
        ipStrategy:
          excludedIPs:
            - "172.16.0.0/12"  # I should probably scope this down to the docker network's IP range

:white_check_mark: When I use the excludedIPs setting and I try to access whoami via the cloudflare tunnel, I am getting a Forbidden result and this is okay. The debug logs show this message:

time="2022-11-22T08:57:21-08:00" level=debug msg="Rejecting IP x.x.x.x: \"x.x.x.x\" matched none of the trusted IPs" middlewareName=known-ips-internal@file middlewareType=IPWhiteLister

:x: However, when I try to access whoami internally I am also getting a forbidden which is unexpected. The debug logs show that the ip address is empty. The X-Forwarded-For header is: 192.168.1.X

time="2022-11-22T09:03:24-08:00" level=debug msg="Rejecting IP : empty IP address" middlewareType=IPWhiteLister middlewareName=known-ips-internal@file

depth setting

I believe the depth documentation on the website is incorrect. The starting index is actually 0 not 1.

Here is the middleware configuration I have setup:

  middlewares:
    known-ips-internal:
      ipWhiteList:
        sourceRange:
          - "127.0.0.1/32"
          - "10.0.0.0/8"
          - "172.16.0.0/12"
          - "192.168.0.0/16"
        ipStrategy:
          depth: 0  # I also tested with depth 1 and depth 2

Connecting internally

When I use depth: 0 and have X-Forwarded-For: 192.168.1.X, it will return the correct IP address:

time="2022-11-22T09:08:56-08:00" level=debug msg="Accepting IP 192.168.1.X" middlewareType=IPWhiteLister middlewareName=known-ips-internal@file

When I use depth: 1 and have X-Forwarded-For: 192.168.1.X, it will return the an empty IP address:

time="2022-11-22T09:22:33-08:00" level=debug msg="Rejecting IP : empty IP address" middlewareType=IPWhiteLister middlewareName=known-ips-internal@file

Connecting via cloudflare tunnel

When I use depth: 0 and have X-Forwarded-For: x.x.x.x, 172.22.0.X, it will return 172.22.0.X. This is undesired because I want it to block:

time="2022-11-22T09:18:28-08:00" level=debug msg="Accepting IP 172.22.0.X" middlewareName=known-ips-internal@file middlewareType=IPWhiteLister

When I use depth: 1 and have X-Forwarded-For: x.x.x.x, 172.22.0.X, it will return x.x.x.x. This is desired for me:

time="2022-11-22T09:18:58-08:00" level=debug msg="Rejecting IP x.x.x.x: \"x.x.x.x\" matched none of the trusted IPs" middlewareName=known-ips-internal@file middlewareType=IPWhiteLister

What a beautiful written post :grinning:

I haven’t checked your details, but did you see the notes?

take the IP located at the depth position (starting from the right)

depth is ignored if its value is less than or equal to 0

I saw the “starting from the right side” note. I did not see the “if 0 or less is ignored” part. Thanks for pointing that out, it makes sense why I was able to get access because the depth was ignored.

I’m still having the issue where depth doesn’t work when I set it to 1. It picks the second element starting at the right side. In my post the section “ Connecting via cloudflare tunnel” shows an example of that.

I also still have an issue when trying to use excludeIPs.