Setup HTTPS certificated¶
Wildcard certificate with LetsEncrypt¶
Goal is to have all the url's encryptes with a SSL certificate by LetsEncrypt. I don't want to open http incoming traffic into my homelab from outside, so i will be using the DNS01 challenge type, using Cloudflare as DNS control.
DNS01 challenge
This challenge asks you to prove that you control the DNS for your domain name by putting a specific value in a TXT record under that domain name. It is harder to configure than HTTP-01, but can work in scenarios that HTTP-01 can’t. It also allows you to issue wildcard certificates. After Let’s Encrypt gives your ACME client a token, your client will create a TXT record derived from that token and your account key, and put that record at _acme-challenge.
For all the following steps to work you must first comply to the following pre-requisites:
- domain name managed through Cloudflare
- cert-manager installed
If these pre-requisites are met, the following steps are needed:
- get cloudflare API token
- setup cluster issuer
- setup wildcard certificate
- forward all incoming http traffic to https
Get cloudflare API-token¶
From the Cert-manager docs:
Tokens can be created at User Profile > API Tokens > API Tokens. The following settings are recommended:
Permissions:
Zone - DNS - Edit
Zone - Zone - Read
Zone Resources:
Include - All Zones
Now make a Kubernetes secret containing your new API token. This secret will be referenced in the cluster issuer that is created in the next step.
Create a yaml file containing the secret information called cloudflare-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
type: Opaque
stringData:
api-token: <API Token>
and apply:
or just use:
Setup clusterIssuer¶
An issuer is a resource that represents a certificate authority.
ClusterIssuer from cert-manager
docs
Issuers, and ClusterIssuers, are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests.
If you want to create a single Issuer that can be consumed in multiple namespaces, you should consider creating a ClusterIssuer resource. This is almost identical to the Issuer resource, however is non-namespaced so it can be used to issue Certificates across all namespaces.
Since i want to have all certificates issued by LetsEncrypt, a ClusterIssuer is the best to go with.
Create the clusterissuer.yaml
file.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: <YOUR_EMAIL>
privateKeySecretRef:
name: letsencrypt-prod
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
key: api-token
name: cloudflare-api-token-secret
and apply
Check if the registration is succesfull by describing the clusterIssuer
Especially the last part is interesting
Message: The ACME account was registered with the ACME server
Observed Generation: 2
Reason: ACMEAccountRegistered
Status: True
Type: Ready
Setup wildcard certificate¶
Now the CertificateIssuer is up and running, it's time to get a wildcard certificate up. A certificate is always scoped to a certain namespace. In this case it will be assigned to the kube-system
namespace. Since this is a wildcard certificate I want to use for multiple apps in different namespaces, Reflector will take care of copy-ing this certificate to different namespaces. The annotations for this will be added later on.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-fromej
namespace: kube-system
spec:
dnsNames:
- fromej.nl
- '*.fromej.nl'
issuerRef:
kind: ClusterIssuer
name: letsencrypt-prod
secretName: wildcard-k3s-fromej-tls
Warning
Make sure to replace the values in the dnsNames
to your own domain.
It might take a minute for the process to finish. Check the status like
root@cluster-master:~# kubectl get certificate -n kube-system
NAME READY SECRET AGE
wildcard-fromej True wildcard-k3s-fromej-tls 31d
Standard forward HTTP to HTTPS with traefik¶
Since i want all traffic reaching the Traefik ingress to be rerouted to HTTPS, the traefik chart should be adjusted. The best way to do this, and make sure changes are perserved (also when reboots are done) is via a HelmChartConfig.