To make a DNS challenge work, you’ll need one big pre-requisite:
In this article, we will:
A DNS Challenge is where you tell Let’s Encrypt, “I would like a certificate that covers my entire domain”. And Let’s Encrypt says, “Here’s a big text file to stick in your DNS registrar for us to read and validate your domain”. Once you do that, and once they read it, they give you a certificate that covers your entire domain (referred to as a wildcard certificate) for 3 months.
A DNS challenge is really the best option if you have the right pre-requisites. You don’t have to expose any services at all for it to work, which is especially important if you are stuck without a public IPv4 address. You also only need to request one certificate, and you can reuse that certificate for all of your services.
Where we left off, we had just installed cert-manager. Now we have to register a key from our DNS provider. For this guide we will be using cloudflare, following this guide.
Create an opaque secret for the cert-manager namespace. Fill out the token with a name of cloudflare-api-token-secret, a key of api-token, and the token you copied from cloudflare
Rancher does not have fillable forms for cert-manager based instructions. Instead, we will fall back to the default way of applying settings: Kubernetes Manifests!
Different providers have different structures for Kubernetes Manifests. You can read the documentation for cert-manager manifests on their documentation.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory email: firstname.lastname@example.org privateKeySecretRef: name: letsencrypt-staging solvers: - dns01: cloudflare: apiTokenSecretRef: key: api-token name: cloudflare-api-token-secret email: email@example.com
Once you have done that, you can clear your namespace filters, and find the status of our manifest in more resources→cert-manager→ClusterIssuers. You should see a registered status for your issuer:
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: mydomain-staging namespace: homelab spec: secretName: mydomain-staging issuerRef: name: letsencrypt-staging kind: ClusterIssuer dnsNames: - '*.mydomain.com.au'
Alright! If all goes well, that’s enough to generate your certificate. You should get a nice active under more resources→cert manager→certificates after a while (give it up to 10 minutes, but typically within 30 seconds).
if you do not get active for your certificate, you can investigate what went wrong by looking up certificaterequests on the side panel.
Change to that and hit Save. Check your site, and you should be getting a new certificate from R3! It will still be invalid, which is fine: we start with staging to make sure our config is right and we don’t get ratelimited by Let’s Encrypt.
Now that we have configured a functional workflow, we can move from staging to production.
Head back to issuers on the sidebar and clone the staging issuer:
Set the name and privateKeySecretRef name to letsencrypt-production. Set the server URL to
Do the same thing for certificates
Once the production certificate becomes active, we can go back to Ingresses and swap out for the production certificate. Then we can test and see if we are getting a wildcard certificate! You can see me do this below:
Hooray! We can now use this certificate for any subdomain of the same domain. If you wish, you can also go delete the staging certificate from certficates, the staging issuer from ClusterIssuers, and the staging secret from secrets.
We can also set up additional issuers (or use a single issuer with selectors) to certify other domains. Cert-manager will automatically monitor the certificates and renew them, nothing to be done on your end. Fantastic!
We can also create a valid certificate for our rancher installation. This is especially important if our rancher install is using the same domain as our let’s encrypt wildcard. Chrome will install stricter SSL enforcement (known as HSTS) which will break rancher’s self signed certificate after visiting a site using our let’s encrypt certificate.
you can temporarily get around this problem by using an incognito or guest profile in chrome
ingress: tls: source: secret extraAnnotations: nginx.ingress.kubernetes.io/whitelist-source-range: "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
The extraAnnotations section is optional, but useful if you want to restrict who can access your rancher web interface. You may even want to lock down the interface to a smaller subnet.
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: tls-rancher-ingress namespace: cattle-system spec: secretName: tls-rancher-ingress commonName: kub01.mydomain.com.au dnsNames: - kub01.mydomain.com.au issuerRef: name: letsencrypt-production kind: ClusterIssuer
As a side benefit, you have also added additional security measures for accessing your rancher web interface via the IP whitelist!