Certificates
This page describes the two ways provided by the h8lio platform to manage the TLS certificates to secure your ingress routes (https scheme) using:
Traefik
Traefik integrates the TLS certificates management and we are providing a default certificate resolver using LetsEncrypt HTTP-01 Challenge which can be be used in your routes.
🟢 Pros:
- Simplest solution to secure your routes as it is transparently managed by the Traefik Proxy and the provided
defaultcertificate resolver.
🔴 Cons:
- No much control of your certificates as they are internally managed by Traefik using our
defaultcertificate resolver - Risk to reached the LetsEncrypt rates limits if you create lot of routes at once or if your route configuration is wrong and the LetsEncrypt challenge fails several times (see Best Practices)
- the LetsEncrypt HTTP-01 challenge doesn’t allow wildcard certificates
Usage
Here is an example how to use the default certificate resolver within a Traefik IngressRoute.
This example also shows you how to redirect the HTTP trafic to the HTTPS entry point using a Middleware:
# http: scheme route redirected to https: scheme.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: example
spec:
# http entry point
entryPoints:
- http
# route rules definition
routes:
# list of rules
- kind: Rule
match: Host(`test.example.com`)
# redirect middleware
middlewares:
- name: https-redirect
namespace: traefik
# backend Kubernetes service
services:
- name: my-service
port: 8080
---
# secured route (https scheme) with "default" certificate resolver
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: example-tls
spec:
# https entry point
entryPoints:
- https
routes:
- kind: Rule
match: Host(`test.example.com`)
# backend Kubernetes service
services:
- name: my-service
port: 8080
tls:
# TLS certificate resolver
certResolver: defaultThat’s it! Traefik is doing all the certificate generation and renewal processes internally.
the API Group will be changed in Traefik 3+ from
traefik.containo.us/v1alpha1totraefik.io/v1alpha1. You may start to use the new group but pay attention to theCustomResourceDefinitionwhen you retrieve your resources (twoIngressRoutedefinitions).
Best practices
To facilitate the TLS challenge and avoid the LetsEncrypt rate limits you should follow the following recommendations:
- (required) The backend service has to be up and running and able to answer the LetsEncrypt challenge with a 200 http status response code before to deploy the secured route (you could check your service is running by using
kubectl port-forward service...). - (mandatory) If you are using your own domain, make sure the routes are redirected to edge.h8l.io (CNAME record to edge.h8l.io or A record to the load balanced IP of edge.h8l.io) and the DNS propagation has been done (LetsEncrypt could perform the HTTP-01 challenge from the US)
- If your route rules are complex, you can help Traefik to resolve the hosts to challenge by specifying the tls domains
- You can group your routes in a single
IngressRouteand/or in a singlematch:withHost(`a.b.com`,...,`c.b.com`)to help Traefik to resolve the hosts and limit the number of challenge and
Cert-Manager
The h8lio integrates cert-manager to manage your certificates. It allows to get more control of your certificates and share them with multiple Kubernetes resources.
The cert-manager h8lio integration is quite recent (
alphastage). Every feedback are welcome.
🟢 Pros:
- Finely manage your certificates
- Provide your own certificate issuers or self-signed certificates
- Possibility to use the cert-manager command line tool
- Allow wildcard certificate management using the LetsEncrypt DNS-01 challenge and avoid the LetsEncrypt rate limits if you have a lot of secured routes to create (in case of migration for example)
- Easy integration within your Traefik
IngressRoutes
🔴 Cons:
- More complex to use compare to the integrated Traefik certificate resolver
- You become the manager of your certificates
- External management of the DNS-O1 Challenge Provider
For now, we deployed only the OVH Challenge Provider, if you need another supported provider or add your own provider let us know by opening a ticket or by emailed us at hello@h8l.io.
Usage
The following example shows how to create and use a wildcard certificate using cert-manager and LetsEncrypt DNS-O1 challenge on a OVH managed domain.
- Create a secret holding the OVH API credentials in the cluster where you want to use the certificate:
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: ovh-<domain>-api
data:
applicationKey: <base64 encoded application key>
applicationSecret: <base64 encoded application secret>
consumerKey: <base64 encoded consumer key>replace the
<...>by the value of your choice
you can use sealed-secret if you want to securely store the secret outside of the h8lio Kubernetes Cluster (example, in a Git repository)
- Create your cert-manager
Issuerusing LetsEncrypt and the OVH challenge provider:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ovh-<domain>
spec:
acme:
# LetsEncrypt production server
server: "https://acme-v02.api.letsencrypt.org/directory"
# email or mailing list used for the LetsEncrypt account
email: <my@email.com>
# reference to the secret holding your LetsEncrypt account key
# it will be created by cert-manager if it doesn't exist
privateKeySecretRef:
name: "ovh-<domain>-account-key"
solvers:
# DNS-01 challenge configuration
- dns01:
cnameStrategy: "None"
# OVH DNS-01 challenge webhook configuration
webhook:
solverName: ovh # do not change this value
groupName: acme.h8l.io # do not change this value
config:
# OVH zone
endpoint: ovh-eu
# OVH Authentication method (possible values: application or oauth2)
authenticationMethod: application
# OVH credentials from the secret
# adapts the name: and key: based of your configuration
applicationKeyRef:
name: ovh-<domain>-api
key: "applicationKey"
applicationSecretRef:
name: ovh-<domain>-api
key: "applicationSecret"
applicationConsumerKeyRef:
name: ovh-<domain>-api
key: "consumerKey"see webhook documentation configuration for more details
Once the Issuer manifest has been applied to your cluster. You can check the events and status: of the cert-manager.io/v1 Issuer CustomResourceDefinition to validate its configuration and its readiness.
It should look like:
status:
acme:
lastPrivateKeyHash: yTty...
lastRegisteredEmail: my@email.com
uri: https://acme-v02.api.letsencrypt.org/acme/acct/12345...
conditions:
- lastTransitionTime: '2023-08-05T13:58:40Z'
message: The ACME account was registered with the ACME server
observedGeneration: 2
reason: ACMEAccountRegistered
status: 'True'
type: Ready- Create the cert-manager
Certificate’s secret using the previousIssuerwhich will be used in theIngressRoutes
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ovh-<domain>
spec:
# replace with your domain
# it could be a second level subdomain (ie. "*.sub.domain.com")
dnsNames:
- "*.domain.com"
issuerRef:
group: cert-manager.io
kind: Issuer
name: ovh-<domain> # the issuer name
secretName: ovh-<domain>-cert # the name of the secret which will hold the certificateOnce the Certificate manifest has been applied to your cluster. You can check the events and status: of the cert-manager.io/v1 Certificate CustomResourceDefinition to validate its configuration and its readiness.
This operation could take few seconds while cert-manager is internally managing the creation of all the resources involved in the DNS-01 challenge process to create the secret containing the new Certificate. It should look like:
status:
conditions:
- lastTransitionTime: '2023-08-07T07:44:14Z'
message: Certificate is up to date and has not expired
observedGeneration: 1
reason: Ready
status: 'True'
type: Ready
notAfter: '2023-11-05T06:44:12Z'
notBefore: '2023-08-07T06:44:13Z'
renewalTime: '2023-10-06T06:44:12Z'
revision: 1If the certificate generation process is successful, you should see your ovh-<domain>-cert secret with the two tls file entries:
kind: Secret
apiVersion: v1
metadata:
name: ovh-<domain>-cert
annotations:
# cert-manager annotations
cert-manager.io/alt-names: ...
cert-manager.io/certificate-name: ...
cert-manager.io/common-name: ...
cert-manager.io/ip-sans: ...
cert-manager.io/issuer-group: ...
cert-manager.io/issuer-kind: ...
cert-manager.io/issuer-name: ...
cert-manager.io/uri-sans: ...
data:
tls.crt: >-
LS0t...
tls.key: >-
LS0t...
type: kubernetes.io/tls- Use your certificate secret in your Traefik
IngressRoutes(as many times you need):
# secured route (https scheme) with your certificate from a cert-manager secret
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: example-tls
spec:
# https entry point
entryPoints:
- https
routes:
- kind: Rule
# rule's match using subdomains of the generated wildcard certificate
match: Host(`test.domain.com`,`demo.domain.com`)
# backend Kubernetes service
services:
- name: my-service
port: 8080
tls:
# TLS certificate secret reference
secretName: ovh-<domain>-certNo LetsEncrypt challenge is done by Traefik when you deploy this secured route as it has already been done and managed by the cert-manager (avoiding also the LetsEncrypt Rate Limits).
*.namespace.h8l.io certificates
If not already present, you may want to create an h8lio-tls secret holding the certificate for the routes *.[domain-cluster].h8l.io:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: h8lio
namespace: <domain-cluster>
spec:
dnsNames:
# certificate common name and to avoid the TXT challenge issue:
# ⚠️ DNS TXT record challenge may break the wildcard domain config (OVH)
# see https://github.com/cert-manager/cert-manager/issues/806
- "<domain-cluster>.h8l.io"
# wildcard certificate (one per sub domain level)
- "*.<domain-cluster>.h8l.io"
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
# cluster wide h8l.io issuer using LetsEncrypt
# ⚠️ works only for the h8l.io subdomains
name: h8lio-issuer
# target secret name holding the
secretName: h8lio-tlsReplace <domain-cluster> with your namespace and apply this manifest.
After few seconds (checks the Certificate events/status), the h8lio-tls secret should be generated and can be used in you ingress routes tls: configuration:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
...
spec:
entryPoints:
- https
routes:
- ...
tls:
secretName: h8lio-tlsRemember to change your pipelines and/or helm chart to uses the new TLS configuration
If you are using the secret name, don’t mix your domain’s routes rules with the h8l.io ones. The generated certificate will only work for the specified h8l.io
dnsNames