[Solved] Kong ingress using own cert instead of Ingress-specified

I’ve set up Kong (Helm chart version 1.14.5 from https://charts.konghq.com) as an ingress controller (db-less with CRDs and ingress definitions for configuration). The issue I’m having is that when I query the SSL port Kong responds with the self-signed certificate instead of the one specified in the ingress resource.

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    konghq.com/methods: GET,HEAD
    kubernetes.io/ingress.class: kong
  name: myservice-anonymous
  namespace: myservice
spec:
  rules:
    - host: myservice.domain.dom
      http:
        paths:
          - backend:
              serviceName: {{ .Release.Name }}-myservice
              servicePort: 8080
            path: /
    - host: sub.altdomain.com
      http:
        paths:
          - backend:
              serviceName: {{ .Release.Name }}-myservice
              servicePort: 8080
            path: /
  tls:
    - hosts:
        - myservice.domain.com
      secretName: myservice.domain.com-tls
    - hosts:
        - sub.altdomain.com
      secretName: sub.altdomain.com-tls
curl -vvv -k -H "Host: myservice.domain.com" https://<ingress IP>/
...
* Server certificate:
*  subject: C=US; ST=California; L=San Francisco; O=Kong; OU=IT Department; CN=localhost
*  start date: Mar  2 14:50:59 2021 GMT
*  expire date: Jan 19 03:14:08 2038 GMT
*  issuer: C=US; ST=California; L=San Francisco; O=Kong; OU=IT Department; CN=localhost
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
...
openssl x509 -in cert -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            64:e4:15:26:79:d4:c6:e8:f8:2f:68:cb:30:85:10:47:10:90:f9:1b
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = "CloudFlare, Inc.", OU = CloudFlare Origin SSL Certificate Authority, L = San Francisco, ST = California
        Validity
            Not Before: Mar  1 01:24:00 2021 GMT
            Not After : Feb 26 01:24:00 2036 GMT
        Subject: O = "CloudFlare, Inc.", OU = CloudFlare Origin CA, CN = CloudFlare Origin Certificate
...

As you can see Kong is serving its own certificate instead of the one provided by the secret. The ingress-controller container in the Kong pod is not logging any errors (I tried deleting and mangling the secret and Kong detects that). I’m at a loss as to what I may have missed and would appreciate suggestions.

Though it’s also a hostname, the HTTP Host header isn’t used to select which certificate Kong presents. It’s only sent after the TLS handshake completes.

Kong needs to receive server name indication information from a TLS client to select a certificate other than its default. curl will always use the hostname from the URL for SNI even if you override the Host header. To send your chosen hostname for both SNI and Host, you should use:

curl -vvv -k https://myservice.domain.com --resolve myservice.domain.com:443:INGRESS_IP

--resolve creates a DNS override for that request, which allows you to use that hostname in the URL, which sets the proper SNI during the TLS handshake.

@traines D’oh, it seems so obvious in retrospect. I was so convinced that I had made a configuration mistake that I hadn’t considered that I wasn’t sending the correct SNI.

As a side note, it seems that if SNI is not present Kong will use its self-signed cert (or I presume the default ingress cert if present), then resolve the Host header and serve the appropriate route. Is there a way to configure Kong to return an error (either 404 or another appropriate code) if the request does not include SNI for a matching route?

Routes support SNI as an additional criteria. You can set them with an annotation: Kubernetes Ingress Controller annotations - v1.1.x | Kong - Open-Source API Management and Microservice Management