Skip to content

SSL errors with from-to-www-redirect (ERR_CERT_AUTHORITY_INVALID/MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT) #7103

Closed as not planned
@VengefulAncient

Description

@VengefulAncient

NGINX Ingress controller version: v.0.44.0

Kubernetes version (use kubectl version): v1.19.9-gke-1400

Environment:

  • Cloud provider or hardware configuration: GKE
  • Install tools: Helm v3
  • Others: certificates are issued by cert-manager

What happened:

Essentially the same issue as in #5675 except we're trying to redirect from www. to naked domain and not the other way around. Trying to load https://www.example.com in Chrome produces NET::ERR_CERT_AUTHORITY_INVALID error.

In Firefox, it's MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT and clicking Accept the Risk and Continue proceeds to correctly follow redirects and load the site. Subsequent requests then also work fine.

What you expected to happen:

Redirect from www. to naked domain works without errors.

How to reproduce it:

Ingress is configured in line with what was suggested by aledbf: no backend for www. but www. domain is included in TLS hosts. According to several threads on the topic I've perused, that approach should work.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-front
  namespace: example
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($host = example.co.uk) {
          return 301 https://example.com$request_uri;
      }
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: example-front
            port:
              number: 80
  - host: example.co.uk
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: example-front
            port:
              number: 80
  tls:
  - hosts:
    - example.com
    - www.example.com
    - example.co.uk
    - www.example.co.uk
    secretName: example-front-tls

Anything else we need to know:

  1. Ingress controller logs mention: the server www.example.com has SSL configured but the SSL certificate does not contains a CN for example.com. Redirects will not work for HTTPS to HTTPS. This is false, I've checked and the certificate does contain CN for example.com.

  2. The logs have the same warning for https://www.example.co.uk (we own a .co.uk version of our domain just to rewrite it to .com) but navigating to https://www.example.co.uk works exactly as expected: there is a 308 redirecting to https://example.co.uk and then a 301 to https://example.com. Why is this not happening for https://www.example.com? (Note that adding the same 301 redirect if block from www.example.com to example.com does not fix the issue, nor should it be the solution.)

  3. On the first request after opening private browsing, requesting www.example.com or http://www.example.com in Chrome or Firefox will proceed as follows:

    • first 308 from www. to naked domain
    • then 308 from http to https

    Immediately after though, requesting either of these in a new tab results in the same error again. Firefox network console shows nothing, but Chrome logs a 307 from http to https and then fails on the next request which asks for https://www.example.com. (Manually prefixing the URL with https:// always results in the error, even on the first request.) Notice how on the first attempt, www. to naked domain happened first, and the issue did not occur. This mirrors the behaviour described in 2043, which is apparently not fixed to this date.

  4. The issue can be bypassed by adding www.example.com as a host to spec.rules. I don't consider this a valid configuration or a solution to this issue for several reasons:

    • Documentation states:

      For HTTPS to HTTPS redirects is mandatory the SSL Certificate defined in the Secret, located in the TLS section of Ingress, contains both FQDN in the common name of the certificate.

      This directive is fulfilled by my configuration. There is nothing about having to add the www. domain as a backend.

    • It defeats the point of from-to-www-redirect annotation

    • It complicates ingress Helm templates and bloats the resulting manifest

    • It does not actually result in a redirect (it merely handles requests on www. as another backend), as evidenced by the following warnings in the logs:

      • Already exists an Ingress with "www.example.com" hostname. Skipping creation of redirection from "www.example.com" to "example.com".
      • Already exists an Ingress with "example.com" hostname. Skipping creation of redirection from "example.com" to "www.example.com".

Based on these findings, it appears that there is a long-existing bug with this annotation. People are using workarounds such as a conditional rewrite block and they really shouldn't need to. It would be really amazing to have this actually fixed and put all the relevant discussions to rest once and for all.

I've also noticed that the annotation documentation claims:

If at some point a new Ingress is created with a host equal to one of the options (like domain.com) the annotation will be omitted.

How exactly will it be "omitted"? My cluster does have other Ingress objects with example.com as a host (without www. or from-to-www-redirect on them) but the generated nginx.conf still has redirect blocks for example.com location so it does not look like anything was "omitted":

		set_by_lua_block $redirect_to {
			local request_uri = ngx.var.request_uri
			if string.sub(request_uri, -1) == "/" then
			request_uri = string.sub(request_uri, 1, -2)
			end
			return string.format("%s://%s%s", ngx.var.scheme, "example.com", request_uri)
		}
		return 308 $redirect_to;

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.kind/bugCategorizes issue or PR as related to a bug.lifecycle/rottenDenotes an issue or PR that has aged beyond stale and will be auto-closed.priority/important-longtermImportant over the long term, but may not be staffed and/or may need multiple releases to complete.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions