How can I correctly setup custom headers with nginx ingress?

Andrei Dascalu picture Andrei Dascalu · Jan 8, 2019 · Viewed 18k times · Source

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!

Answer

Petr Šejn picture Petr Šejn · Apr 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