ingress-nginx: SSL redirect broken when default-ssl-certificate is used

Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see https://kubernetes.io/docs/tasks/debug-application-cluster/troubleshooting/.): no

What keywords did you search in NGINX Ingress controller issues before filing this one? (If you have found any duplicates, you should instead reply there.): tls redirect, ssl redirect


Is this a BUG REPORT or FEATURE REQUEST? (choose one): BUG REPORT

NGINX Ingress controller version: >= 0.26.0

Kubernetes version (use kubectl version): 1.15.3

Environment:

  • Cloud provider or hardware configuration: https://metakube.syseleven.de/ on OpenStack
  • OS (e.g. from /etc/os-release): Ubuntu 18.04.3 LTS
  • Kernel (e.g. uname -a): 4.15.0-64-generic
  • Install tools: Helm with stable/nginx-ingress
  • Others:

What happened: When you configure ingress-nginx to use a default-ssl-certificate for ingresses that do not contain a secretName in their TLS configuration, the certificate is used correctly but http requests are not redirect to https anymore. This is still working on version 0.25.1.

What you expected to happen: By default http requests to this ingress are redirected to https.

How to reproduce it (as minimally and precisely as possible): Add an argument:

--default-ssl-certificate=namespace/wildcard-certificate

to the ingress nginx controller.

Create an ingress like:

kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: ingress-name
spec:
  tls:
    - hosts:
        - ingress.example.com
  rules:
    - host: ingress.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: backend-service
              servicePort: 80

TLS works then correctly but redirects do not.

If you force tls redirects with an annotation, the redirect works:

kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: ingress-name
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
    - hosts:
        - ingress.example.com
  rules:
    - host: ingress.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: backend-service
              servicePort: 80

Anything else we need to know:

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 21
  • Comments: 18 (7 by maintainers)

Commits related to this issue

Most upvoted comments

As explained by @prageethw the solution is to use force-ssl-redirect: "true" in the controller’s ConfigMap (if it was not clear for those not using Helm). Beware this option is not documented on https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap !

jee after some trial got it working on latest, note this config does SSL offloading at ELB and redirect HTTP to https

helm install  stable/nginx-ingress --name nginx-ingress --namespace nginx-ingress \
            --version 1.36.0 \
            --set controller.publishService.enabled=true \
            --set controller.service.targetPorts.https=http \
            --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-proxy-protocol"=* \
            --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol"=http \
            --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-connection-idle-timeout"=3600 \
            --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-ssl-cert"=$AWS_SSL_CERT_ARN \
            --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-ssl-ports"=https \
            --set-string controller.config.ssl-redirect=true \
            --set-string controller.config.use-forwarded-headers=true \
            --set-string controller.config.use-proxy-protocol=false \
            --set-string controller.config.force-ssl-redirect=true \
            --set-string controller.config.hsts=true
kubectl -n nginx-ingress  rollout status deployment nginx-ingress-controller

Is this still a thing? We’re running 0.30.0 in AKS, 1.15.8, and don’t get ssl-redirect to work.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    certmanager.k8s.io/acme-dns01-provider: dns
    certmanager.k8s.io/cluster-issuer: letsencrypt-dns
    ingress.kubernetes.io/force-ssl-redirect: 'true'
    ingress.kubernetes.io/ssl-redirect: 'true'
    kubernetes.io/ingress.class: nginx-external
    kubernetes.io/tls-acme: 'true'
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
    nginx.ingress.kubernetes.io/server-snippet: |-
      http2_max_field_size 16k;
      http2_max_header_size 128k;
    nginx.ingress.kubernetes.io/ssl-redirect: 'true'
  labels:
    app.kubernetes.io/instance: applicaion
    app.kubernetes.io/name: applicaion
    team: team
    name: applicaion
  name: applicaion
  namespace: team-application
spec:
  rules:
    - host: applicaion.domain.com
      http:
        paths:
          - backend:
              serviceName: applicaion
              servicePort: 80
            path: /
  tls:
    - hosts:
        - applicaion.domain.com
      secretName: domain-tls

I seem to be seeing the same thing on 0.26.1. When I roll back to an older ingress container (0.23) we see a proper redirect to https in our particular environment.

In my case, I have…

    nginx.ingress.kubernetes.io/proxy-redirect-from: ~*^https?://[^/]*(.*)$ $scheme://$host:$server_port$1
    nginx.ingress.kubernetes.io/ssl-redirect: "true"

If I add nginx.ingress.kubernetes.io/force-ssl-redirect: "true" to our ingress, things work as I expect. I’m passing --default-ssl-certificate=whatever to the ingress-controller on startup.