Edit: I was made aware that my original post could be interpreted as advertisement. I fail to see why this is the case, however I have removed all references to non-Traefik tools with the consequence of losing context for the problem.
We are trying to replace the Kubernetes manifest-based installation of Traefik with the Traefik Helm chart. Originally, using the manifest approach to installing Traefik, we configured certificates by mounting them into the Traefik container and pointing to them via the traefik.toml file:
[tls]
[[tls.certificates]]
certFile = "/certs/tls.crt"
keyFile = "/certs/tls.key"
stores = ["default"]
[tls.stores]
[tls.stores.default]
[tls.stores.default.defaultCertificate]
certFile = "/certs/tls.crt"
keyFile = "/certs/tls.key"
[tls.options.default]
minVersion = "VersionTLS12"
sniStrict = true
As you can see, we have strict SNI enabled. In order to use the same certificate by default across all ingress routes, unless another certificate is specified, we have been required to point to the certificate twice.
Now we try to do this the Kubernetes CRD-way. Strict SNI is configured via a TLSOption resource:
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: default
labels:
app.kubernetes.io/name: traefik
helm.sh/chart: traefik-10.19.4
app.kubernetes.io/managed-by: Helm
spec:
minVersion: VersionTLS12
sniStrict: true
For the certificate, we understand that we can use a TLSStore resource:
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
labels:
app.kubernetes.io/name: traefik
helm.sh/chart: traefik-10.19.4
app.kubernetes.io/managed-by: Helm
spec:
defaultCertificate:
secretName: "our-certificate-secret"
But as one might expect, this does not work as long as strict SNI is enabled. If we disable strict SNI, the certificate works as expected. We can see in the source code that Traefik explicitly skips checking the default certificate for a hostname match if strict SNI is enabled. So the question is, how does one replicate the following piece of configuration with Traefik CRDs and/or the cli arguments:
[tls]
[[tls.certificates]]
certFile = "/certs/tls.crt"
keyFile = "/certs/tls.key"
stores = ["default"]
Furthermore, we have noticed that if we configure a single IngressRoute to use our certificate, that certificate also becomes available to other IngressRoutes. For instance, the following:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: "traefik-ping"
annotations:
kubernetes.io/ingress.class: "traefik-internal"
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`something.something`) && Path(`/ping`)
services:
- kind: Service
name: "traefik-ping"
namespace: "traefik"
port: 9000
tls:
secretName: "our-certificate-secret"
Will also enable other IngressRoutes without a tls section to use the same certificate (assuming the certificate matches the hostnames). We do not like this approach to making our certificate available, since it means that deleting the ping route will break TLS for other unrelated IngressRoutes.
Note: Our Traefik ping IngressRoute is only available on a private virtual network behind our client-facing gateways.