ingress-nginx
ingress-nginx copied to clipboard
hsts-preload does not work with www-redirect
What happened:
Setting hsts-preload: true
in the ingress-nginx controller configmap and creating an ingress with the nginx.ingress.kubernetes.io/from-to-www-redirect
annotation for the www subdomain of a domain does no result in a hsts preload eligible configuration for the used domain.
The resulting redirects are:
http://domain.tld -> http://www.domain.tld -> https://www.domain.tld (with HSTS header)
and
https://domain.tld (without HSTS header) -> https://www.domain.tld (with HSTS header)
What you expected to happen:
I would expect this configuration to result in the domain being eligible for submission to chromes hsts preload lists. This would require the following redirects:
http://domain.tld -> https://domain.tld (with HSTS header)-> https://www.domain.tld (with HSTS header)
NGINX Ingress controller version (exec into the pod and run nginx-ingress-controller --version.):
NGINX Ingress controller Release: v1.10.1 Build: 4fb5aac1dd3669daa3a14d9de3e3cdb371b4c518 Repository: https://github.com/kubernetes/ingress-nginx nginx version: nginx/1.25.3
Kubernetes version (use kubectl version
): 1.29.6
Environment:
-
Cloud provider or hardware configuration: k3s single node cluster
-
OS (e.g. from /etc/os-release): Debian GNU/Linux 12 (bookworm)
-
Kernel (e.g.
uname -a
): Linux 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64 GNU/Linux -
Install tools: k3s
-
Basic cluster related info:
- Client Version: v1.29.6+k3s2 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3 Server Version: v1.29.6+k3s2
-
How was the ingress-nginx-controller installed:
- Via helm
- ingress-nginx ingress-nginx 15 2024-04-26 18:50:45.211182831 +0000 UTC deployed ingress-nginx-4.10.1 1.10.1
-
Values
controller: kind: DaemonSet ingressClassResource: default: true service: ipFamilyPolicy: RequireDualStack ipFamilies: - IPv4 - IPv6 externalTrafficPolicy: Local allocateLoadBalancerNodePorts: false metrics: enabled: true serviceMonitor: enabled: true scrapeInterval: 15s config: ssl-reject-handshake: true enable-ocsp: true hsts-preload: true ssl-ciphers: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384" ssl-ecdh-curve: "secp521r1:secp384r1" ssl-session-timeout: 1d http-snippet: | ssl_conf_command Options PrioritizeChaCha; ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; otlp-collector-host: grafana-k8s-monitoring-grafana-agent.monitoring.svc.cluster.local enable-opentelemetry: true opentelemetry-trust-incoming-span: false otel-sampler: AlwaysOn otel-sampler-ratio: "1.0" opentelemetry: enabled: true addHeaders: X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Referrer-Policy: "strict-origin-when-cross-origin" Server-Timing: "traceparent;desc=\"$opentelemetry_context_traceparent\""
How to reproduce this issue:
- Create a new kind cluster with the ports 80 and 443 exposed:
curl https://gist.githubusercontent.com/SvenKirschbaum/91eb6f19c5b320b4265794f33d934232/raw/ceacfbc4a57ca8b23ac1858171f02b9794b71522/kind.yaml | kind create cluster --config=-
- Install ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.0/deploy/static/provider/kind/deploy.yaml
- Enable the hsts-preload option:
kubectl patch configmap/ingress-nginx-controller -n ingress-nginx --type merge -p '{"data":{"hsts-preload": "true"}}'
- Create an ingress for a www subdomain and add the annotation
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
:kubectl apply -f https://gist.githubusercontent.com/SvenKirschbaum/364de5c2b3c537b91ac124ec1d9ffc33/raw/2cd2c2c885e614be1a82984f27c9f4c236a88ce4/ingress.yaml
- Access the domain and observe the presence of the hsts header and the redirects:
$ curl -vk http://localhost 2>&1 |grep "Location\|strict"
< Location: http://www.localhost
$ curl -vk http://www.localhost 2>&1 |grep "Location\|strict"
< Location: https://www.localhost
$ curl -vk https://localhost 2>&1 |grep "Location\|strict"
< Location: https://www.localhost
$ curl -vk https://www.localhost 2>&1 |grep "Location\|strict"
< strict-transport-security: max-age=31536000; includeSubDomains; preload