<p>Have an <code>ingress-nginx-controller</code> Deployment in kubernetes cluster which passes requests to backend services within the cluster and this all currently works as expected.</p>
<p>There is now a requirement within one of the backend services to get the caller's client IP address from within but, with the nginx controller in its default configuration, the backend service is only seeing the kubernetes cluster's network IP address when it calls <code>HttpServletRequest.getRemoteAddr()</code> and not the client caller's IP address.</p>
<p>I understand that requests when proxied can have the client IP address overridden which I am assuming is what is happening here as the request goes through the nginx controller.</p>
<p>I have added a debug log in the backend service to print all relevant headers within received requests and, with the nginx controller in its default configuration, I am seeing the following <code>X-</code> headers within each request received:</p>
<pre><code>x-request-id:3821cea91ffdfd04bed8516586869bdd5
x-real-ip:100.10.75.1
x-forwarded-proto:https
x-forwarded-host:www.myexample.com
x-forwarded-port:443
x-scheme:https
</code></pre>
<p>I have read in various places that nginx can be configured to pass the client's IP address in <code>X-Forwarded-For</code> header for example (which as can be seen in debug log above it is not currently included in client requests).</p>
<p>Looking at the <code>nginx.conf</code> in the ingress-nginx-controller Deployment, the backend's domain server configuration has the following set:</p>
<pre><code>            proxy_set_header X-Request-ID           $req_id;
            proxy_set_header X-Real-IP              $remote_addr;
            
            proxy_set_header X-Forwarded-For        $remote_addr;
            
            proxy_set_header X-Forwarded-Proto      $pass_access_scheme;
            
            proxy_set_header X-Forwarded-Host       $best_http_host;
            proxy_set_header X-Forwarded-Port       $pass_port;
            
            proxy_set_header X-Scheme               $pass_access_scheme;
            
            # Pass the original X-Forwarded-For
            proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
</code></pre>
<p>Doing a <code>kubectl describe deploy -n ingress-nginx ingress-nginx-controller</code> shows that the nginx controller has the following configmap argument: <code>--configmap=ingress-nginx/ingress-nginx-controller</code> so, using this information, what do I need to include in a custom yaml that I can then apply in order to override the nginx config settings to have it pass the client IP to the backend service?</p>

<p>In order to have the nginx controller pass the client's ip address to the backend service I applied the following configmap yaml config:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.10.1
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.41.2
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  compute-full-forwarded-for: &quot;true&quot;
  use-forwarded-headers: &quot;false&quot;
  real-ip-header: proxy_protocol
</code></pre>
<p>I believe the configuration section that matters in this config is the line: <code>real-ip-header: proxy_protocol</code></p>
<p>With this <code>configmap</code> applied to the <code>nginx controller</code> I can now see the client's IP address (no longer the kubernetes cluster's network IP address) shown in the request's <code>x-real-ip</code> header.</p>
