How can I correctly setup custom headers with nginx ingress?

1/7/2019

I have the following configuration:

daemonset:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      serviceAccountName: nginx-ingress
      containers:
      - image: nginx/nginx-ingress:1.4.2-alpine
        imagePullPolicy: Always
        name: nginx-ingress
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: https
          containerPort: 443
          hostPort: 443
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        args:
          - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
          - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret 

main config:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: nginx-ingress
data:
  proxy-set-headers: "nginx-ingress/custom-headers"
  proxy-connect-timeout: "11s"
  proxy-read-timeout: "12s"
  client-max-body-size: "5m"
  gzip-level: "7"
  use-gzip: "true"
  use-geoip2: "true"

custom headers:

apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-headers
  namespace: nginx-ingress
data:
  X-Forwarded-Host-Test: "US"
  X-Using-Nginx-Controller: "true"
  X-Country-Name: "UK" 

I am encountering the following situations:

  • If I change one of "proxy-connect-timeout", "proxy-read-timeout" or "client-max-body-size", I can see the changes appearing in the generated configs in the controller pods
  • If I change one of "gzip-level" (even tried "use-gzip") or "use-geoip2", I see no changes in the generated configs (eg: "gzip on;" is always commented out and there's no other mention of zip, the gzip level doesn't appear anywhere)
  • The custom headers from "ingress-nginx/custom-headers" are not added at all (was planning to use them to pass values from geoip2)

Otherwise, all is well, the controller logs show that my only backend (an expressJs app that dumps headers) is server correctly, I get expected responses and so on.

I've copied as much as I could from the examples on github, making a minimum of changes but no results (including when looking at the examples for custom headers).

Any ideas or pointers would be greatly appreciated.

Thanks!

-- Andrei Dascalu
kubernetes
nginx-ingress

3 Answers

4/8/2019

Use ingress rule annotations.

Example:
 apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "server: hide";
      more_set_headers "X-Content-Type-Options: nosniff";
      more_set_headers "X-Frame-Options: DENY";
      more_set_headers "X-Xss-Protection: 1";
  name: myingress
  namespace: default
spec:
  tls:
  - hosts:

I used nginx server 1.15.9

-- Petr Ĺ ejn
Source: StackOverflow

1/8/2019

Looks like you are using kubernetes-ingress from NGINX itself instead of ingress-nginx which is the community nginx ingress controller.

If you see the supported ConfigMap keys for kubernetes-ingress none of the gzip options are supported. If you see the ConfigMap options for ingress-nginx you'll see all the gzip keys that can be configured.

Try switching to the community nginx ingress controller.

-- Rico
Source: StackOverflow

1/8/2019

For posterity: nginx community controller => quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0

nginx kubernetes controller => nginx/nginx-ingress:edge (as show in docs)

custom headers configmap for community => proxy-set-headers: "nginx-ingress/custom-headers"

custom headers configmap for kubernetes => add-headers: "nginx-ingress/custom-headers"

-- Andrei Dascalu
Source: StackOverflow