Hide the Nginx version in response headers

Posted on Mon 04 October 2021 in devops

We run a couple of Kubernetes (k8s) clusters in Azure and on the back of a pentest exercise we were requested to ensure that we do not return the Nginx version in the HTTP response headers.

Due to our Infrastructure as Code (IaC) first approach we could easily ensure this by making a relatively small change in our Terraform & Helm codebase. We install and configure our Nginx ingress controllers with this helm_release resource:

resource "helm_release" "nginx_ingress_controller" {
# EXTERNALRESOURCE: https://kubernetes.github.io/ingress-nginx
name       = var.workload
chart      = "ingress-nginx"
namespace  = "kube-system"
repository = "https://kubernetes.github.io/ingress-nginx"
version    = var.ingress_helm_chart_version

values = [
    templatefile(
    "${path.module}/templates/ingress-nginx-values.yaml.tpl",
    {
        kind                     = "DaemonSet",
        ingress_load_balancer_ip = var.ingress_load_balancer_ip
    }
    )
]
}

All that was required was to add the following 3 lines under the controller section in the ingress-nginx-values.yaml.tpl file:

controller:
  config:
    proxy-hide-headers: "Server"
    server-tokens: "False"

After a redeploy of the ingress controllers we seamlessly went from showing the versions in the Server header:

$ curl -I http://10.1.0.1
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Content-Type: text/html
Content-Length: 8715
Connection: keep-alive

to:

$ curl -I http://10.1.0.1
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html
Content-Length: 8715
Connection: keep-alive

Happy pentesters are always good and it should now take a bit more work for any malicious actor to determine which flaws can be exploited on our ingress controllers versions.