ipWhiteList with excludedIPs setting will result in empty IP address when there is 1 IP address in X-Forwarded-For Header

Description

Hey guys, I noticed that when there is 1 IP address in the X-Forwarded-For header and I am using the ipStrategy.excludedIPs or ipStrategy.depth=1 setting, it will always return an empty IP address. This results in me getting a forbidden because the empty IP address is not in the IP whitelist source range.

Current Behavior

Setup

My setup is fairly simple, I am using traefik to forward my requests to the containious/whoami docker container. This docker container will show the request headers that it received from traefik.

In my ipWhitelist middleware I put "0.0.0.0/0 to white list all IPv4 addresses and 0000:0000::/0 to whitelist all IPv6 addresses.

[Issue] Accessing Traefik directly - 1 IP address in X-Forwarded-For header

When I access traefik directly (meaning no tunnels in between and I am inside the same network) I only have 1 IP address in the X-Forwarded-For header.

When I have 1 IP in the X-Forwarded-For header and I set the excludedIPs or the depth=1 setting, I get a 403 forbidden response. I am expecting a 200 response instead.

Headers

X-Forwarded-For: 192.168.1.123

Middleware Setting

    known-ips-internal:
      ipWhiteList:
        sourceRange:
          - "0.0.0.0/0"  # Whitelisting ipv4 for testing
          - "0000:0000::/0"  # Whitelisting all ipv6 for testing
        ipStrategy:
          excludedIPs:
            - 172.16.0.0/12
          # depth: 1  # this setting has the same behavior if enabled

Logs

time="2023-02-09T22:32:04-08:00" level=debug msg="Rejecting IP : empty IP address" middlewareName=known-ips-internal@file middlewareType=IPWhiteLister

[Behaving as expected] Accessing Traefik via cloudflare tunnel - 2 IP addresses in X-Forwarded-For header

When I accessing via the cloudflare tunnel I have 2 IPs in the X-Forwarded-For header. It will look like this: X-Forwarded-For: <public IP>, <cloudflared container IP>. When I use the excludedIPs setting it will select the correct IP address which is the public IP address.

Headers

X-Forwarded-For: 111.222.333.444, 172.22.0.123

Middleware Setting

    known-ips-internal:
      ipWhiteList:
        sourceRange:
          - "0.0.0.0/0"  # Whitelisting ipv4 for testing
          - "0000:0000::/0"  # Whitelisting all ipv6 for testing
        ipStrategy:
          excludedIPs:
            - 172.16.0.0/12

Logs

time="2023-02-09T22:27:15-08:00" level=debug msg="Accepting IP 111.222.333.444" middlewareName=known-ips-internal@file middlewareType=IPWhiteLister

Expected Behavior

For the scenario I listed above when I have 1 IP address in the X-Forwarded-For header and I am using a different excludedIPs, I expect it to use that IP address to evaluate for the IP whitelist.

i'm having the same issue,

i have an nginx RP that on the host and traefik as a docker container whith middleware configured to allow 192.168.0.0/16 and exludedIp of 172.20.0.1

Nginx forward the requests to traefik (and add X-Forwarded-For and X-Real-IP headers)
but the middleware reject the request

even tough there is already the header in the request

tcpdump on docker interface :

 172.20.0.1.55706 > 172.20.0.6.http: Flags [P.], cksum 0x6421 (incorrect -> 0x09bc), seq 1:3020, ack 1, win 502, options [nop,nop,TS val 1888465225 ecr 593107050], length 3019: HTTP, length: 3019
        GET /jenkins HTTP/1.0
        Host: *******
        X-Real-IP: 192.168.0.2
        X-Forwarded-For: 192.168.0.2
        X-Forwarded-Proto: http
        X-Forwarded-Login: *********
        X-Forwarded-Name: ********
        X-Forwarded-User: **********
        Connection: close

if i disable the ipStrategy i get the docker ip as remoteAddr (172.20.0.1) which is not whitelisted


i saw also this on the middleware doc

As a middleware, whitelisting happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to X-Forwarded-For during the last stages of proxying, i.e. after it has already passed through whitelisting. Therefore, during whitelisting, as the previous network hop is not yet present in X-Forwarded-For, it cannot be matched against sourceRange.

not sure if i understand the bold part