简体   繁体   中英

Updating ingress-nginx-controller ConfigMap to Pass Client IP to Backend Service

Have an ingress-nginx-controller Deployment in kube.netes cluster which passes requests to backend services within the cluster and this all currently works as expected.

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 kube.netes cluster's.network IP address when it calls HttpServletRequest.getRemoteAddr() and not the client caller's IP address.

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.

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 X- headers within each request received:

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

I have read in various places that nginx can be configured to pass the client's IP address in X-Forwarded-For header for example (which as can be seen in debug log above it is not currently included in client requests).

Looking at the nginx.conf in the ingress-nginx-controller Deployment, the backend's domain server configuration has the following set:

            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;

Doing a kubectl describe deploy -n ingress-nginx ingress-nginx-controller shows that the nginx controller has the following configmap argument: --configmap=ingress-nginx/ingress-nginx-controller 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?

In order to have the nginx controller pass the client's ip address to the backend service I applied the following configmap yaml config:

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: "true"
  use-forwarded-headers: "false"
  real-ip-header: proxy_protocol

I believe the configuration section that matters in this config is the line: real-ip-header: proxy_protocol

With this configmap applied to the nginx controller I can now see the client's IP address (no longer the kubernetes cluster's network IP address) shown in the request's x-real-ip header.

To pass the real Client IP, without much config changes. We need to use use-forwarded-headers: 'true' in the ConfigMap as shown in the below snippet.

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  allow-snippet-annotations: 'true'
  ssl-redirect: 'false'
  use-forwarded-headers: 'true'

use-forwarded-headers ¶

If true, NGINX passes the incoming X-Forwarded-* headers to upstreams. Use this option when NGINX is behind another L7 proxy/load balancer that is setting these headers.

If false, NGINX ignores incoming X-Forwarded-* headers, filling them with the request information it sees. Use this option if NGINX is exposed directly to the inte.net, or it's behind an L3/packet-based load balancer that doesn't alter the source IP in the packets.

By enabling this header, the X-Forwarded-* header will not be appended or replaced by any internal IP.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM