azurekubernetesnginxnginx-ingressingress-controller

How to add X-Original-Forwarded-For as request header in NGINX Ingress Controller?


I am using F5 NGINX Ingress Controller.

Note: I am not using Kubernetes community edition ( Ingress-nginx)

I have achieved traffic splitting using Virtual server for NGINX Ingress Controller. However in the production some clients are using ip whitelisting and in order to pass the request we use header X-Original-Forwarded-For

I want to set X-Original-Forwarded-For request header in NGINX Ingress Controller

https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/#configmap-and-virtualservervirtualserverroute-resources

According to above link setting on ingress level it affects virtual server too.

I am using helm and env.yaml to isntallnginx ingress controller we until now no luck

env.yaml

# Traffic split Nginx Ingress 
controller:
  replicaCount: 2
  config:
    log-format-upstream: '$http_x_forwarded_for - $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id'
  service:
    loadBalancerIP: "xxx.xxxx.xxxx"
    externalTrafficPolicy: "Local"
    annotations:
      service.beta.kubernetes.io/azure-load-balancer-resource-group: "xxxxxxx"
      nginx.org/location-snippets: |
         more_set_input_headers "X-Original-Forwarded-For: jatin";

helm command to install

helm upgrade --install nginx-ingress nginx-stable/nginx-ingress \
  --version 1.0.2 -n nginx-ingress --create-namespace \
  --set controller.ingressClass.create=true \
  --set controller.ingressClass.name=nginx-ingress \
  --set controller.ingressClass.setAsDefaultIngress=false \
  -f ./nginx-ingress/env/env.yaml

Even tried adding on the virtual server resource as shown here

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  namespace: xxxxxx
  name: nginx-vs-traffic-split
  annotations:
    nginx.ingress.kubernetes.io/ingress.class: nginx-ingress

spec:
  host: xxxxx.com
  upstreams:
  - name: xxxxx-a
    service: xxxx-a
    port: 80
  - name: xxxx-b
    service: xxxx-b
    port: 80
  - name: xxxx-c
    service: xxxx-c
    port: 80
  routes:
  - path: /
    location-snippets: |
      add_header my-test-header test-value;   
    splits:
    # The sum of the weights of all splits must be equal to 100
    - weight: 33
      action:
        pass: xxxxx-a
    - weight: 33
      action:
        pass: xxxx-b
    - weight: 34
      action:
        pass: xxxxx-c 

Update:

https://docs.nginx.com/nginx-ingress-controller/installation/ingress-nginx/#migration-with-kubernetes-ingress-resources

I saw this link where configuration-snippet is used location-snippets inside nginx

I tried even with this still no luck


Solution

  • After reading https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header I understood which headers need to be added to the request headers.

    I solved it by enabling snippets on the nginx-ingress ( as snippets are disabled by default) on helm chart and added location-snippets on virtual-server resource

    Command for enabling snippets

    helm upgrade --install nginx-ingress nginx-stable/nginx-ingress \
      --set controller.enableSnippets=true \
      --version 1.0.2 -n nginx-ingress --create-namespace \
      --set controller.ingressClass.create=true \
      --set controller.ingressClass.name=nginx-ingress \
      --set controller.ingressClass.setAsDefaultIngress=false \
      -f ./nginx-ingress/env/env.yaml
    

    Virtual server resource

    apiVersion: k8s.nginx.org/v1
    kind: VirtualServer
    metadata:
      name: nginx-vs-traffic-split
      annotations:
        nginx.ingress.kubernetes.io/ingress.class: nginx-ingress
    spec:
      host: {{.Values.domain.my-domain}}
      upstreams:
      - name: web-nginx 
        service: web-nginx 
        port: 80
      - name: web-octane 
        service: web-octane 
        port: 80
      - name: web 
        service: web 
        port: 80
      routes:
      - path: /
        splits:    
        # Header configuration is required for customers who use IP whitelist feature.
        # If this configuration is not present then all the requests will be blocked.
        location-snippets: |
          proxy_set_header 'X-Original-Forwarded-For' '$http_x_azure_clientip';
        splits: 
        # The sum of the weights of all splits must be equal to 100   
        - weight: {{.Values.trafficSplitWeight.nginx}}
          action:
            pass: web-nginx