Skip to content

Support dynamic headers with $ in custom-header ConfigMapΒ #13831

@manuelchichi

Description

@manuelchichi

What happened:

When trying to set a custom header dynamically from an upstream header in ingress-nginx using the annotation nginx.ingress.kubernetes.io/custom-headers ConfigMap, we run into issues with $ characters.

For example:

Having the following configmap:

apiVersion: v1
data:
  X-Accel-Buffering: "$upstream_http_x_accel_buffering"
kind: ConfigMap
metadata:
  name: x-accel-buffering-test

And the corresponding ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress                                                              
metadata:       
  annotations:    
    nginx.ingress.kubernetes.io/custom-headers: namespace/x-accel-buffering-test
    ...
  name: accel-buffering

Then the generated nginx.conf will generate something like this:

more_set_headers "X-Accel-Buffering: ${literal_dollar}upstream_http_x_accel_buffering";

What you expected to happen:

nginx.conf shouldn't have the ${literal_dollar} part:

more_set_headers "X-Accel-Buffering: $upstream_http_x_accel_buffering";

nginx.tmpl is replacing $ with ${literal_dollar} here. I don't know if this is intended.

NGINX Ingress controller version: v1.12.5

Kubernetes version: v1.33.2

Environment:

  • Cloud provider or hardware configuration: AWS EKS
  • OS (e.g. from /etc/os-release): Amazon Linux 2023
  • Kernel (e.g. uname -a): 6.12

How to reproduce this issue:

As minimally and precisely as possible. Keep in mind we do not have access to your cluster or application.
Help up us (if possible) reproducing the issue using minikube or kind.

Install minikube/kind

Install the ingress controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml

Install an application that will act as default backend (is just an echo app)

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/docs/examples/http-svc.yaml

Create an ingress (please add any additional annotation required)

echo "
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: foo-bar
    annotations:
      kubernetes.io/ingress.class: nginx
      nginx.ingress.kubernetes.io/custom-headers: namespace/x-accel-buffering-test
  spec:
    ingressClassName: nginx # omit this if you're on controller version below 1.0.0
    rules:
    - host: foo.bar
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: http-svc
              port: 
                number: 80
" | kubectl apply -f -

Create the custom header configmap

apiVersion: v1
data:
  X-Accel-Buffering: "$upstream_http_x_accel_buffering"
kind: ConfigMap
metadata:
  name: x-accel-buffering-test

Make a request and check the Headers

POD_NAME=$(k get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o NAME)
kubectl exec -it -n ingress-nginx $POD_NAME -- curl -vH 'Host: foo.bar' localhost

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.needs-priorityneeds-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions