asp.net-corekubernetes.net-corex-forwarded-for

Get user ip when my service is behind multiple proxies and WAF


I deployed an ASP.NET Core web application using kubernetes and ran WAF server to manage the incoming request and protect our service.

I had a part of code that gets the IP of the end user and store it in a database for some monitoring aims. It was working perfectly before we upgrade our Kubernetes to the latest version. But after that I am getting the Ip of my Kubernetes cluster as user client Ip.

After checking the logs and spending time on investigation we found that the real user Ip is stored in X-Original-Forwarded-For header and not in X-Forwarded-For.

POST /Account/Login HTTP/1.1
Host: myservice.com
X-Request-ID: 2c7101cdad13f71a90bebb2c8d58f64d
X-Real-IP: 10.11.150.11
X-Forwarded-For: 10.11.150.11
X-Forwarded-Host: myservice.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Scheme: https
X-Scheme: https
X-Original-Forwarded-For: 120.110.100.90
Content-Length: 756
Forwarded: for=120.110.100.90
Forwarded: for=120.110.100.90;proto=https
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Origin: null
Cookie: .AspNetCore.Antiforgery.9TtSrW0…

Also, I add information about my known Networks/Proxies in my startup by using this code:

services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders = ForwardedHeaders.All;

            foreach (var network in getKnownNetworks(Configuration))
            {
                options.KnownNetworks.Add(network);
            }

            foreach (var proxy in getKnownProxies(Configuration))
            {
                options.KnownProxies.Add(proxy);
            }
        }
    );

I also registered ForwardedHeaders middleware in my Configuration part.

How can I read client Ip from other headers?


Solution

  • In ForwardedHeadersOptions you can configure a custom forwarded-for header by setting the ForwardedForHeaderName property like this:

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.All;
    
        // add this line
        options.ForwardedForHeaderName = "X-Original-Forwarded-For";
    
        foreach (var network in getKnownNetworks(Configuration))
        {
            options.KnownNetworks.Add(network);
        }
    
        foreach (var proxy in getKnownProxies(Configuration))
        {
            options.KnownProxies.Add(proxy);
        }
    });