Cloudflare's Origin CA Issuer on k8s
If you are using Cloudflare in front of a web service you somehow need to secure the traffic between Cloudflare and your origin. Typical options for achieving this has been issuing a certificate with Let’s Encrypt or using a Cloudflare Origin CA certificate.
A great option for k8s specific use cases is the recently added Origin CA Issuer controller. Used together with cert-manager CertificateRequest feature it enables a fully automatic workflow for both issuing and renewal of Origin CA certificates.
Table of contents
- Deploy Origin CA Controller with Kustomize
- Configure Origin CA API Key
- Deploy Origin CA Issuer
- Issue a certificate
- Use with Traefik IngressRoute
Deploy Origin CA Controller with Kustomize
- To deploy with kustomize first create the
kustomization.yamland add the repository as a resource:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - https://github.com/ChrisEke/origin-ca-issuer/deploy
By default the Origin CA issuer will be deployed to namespace
- To verify what will be deployed run command
kustomize build .
- When ready to deploy to the cluster run the same command, but with a pipe to kubectl for actually applying the config:
kustomize build . | kubectl apply -f -
Configure Origin CA API Key
For the Origin CA issuer to be able to issue and renew certificates it needs to be authenticated towards Cloudflare. This is done by adding a special APK key called
Origin CA Key as a secret to the k8s-cluster.
- To retrieve the API key go to dash.cloudflare.com/profile/api-tokens and in the row for Origin CA Key select View to display the key.
- Copy the API key and then add it as a k8s secret:
kubectl create secret -n default generic \ origin-ca-service-key \ --from-literal=key='v1.0-...'
Deploy Origin CA Issuer
- Create a new file to use as manifest for the Origin CA Issuer,
apiVersion: cert-manager.k8s.cloudflare.com/v1 kind: OriginIssuer metadata: name: origin-issuer spec: requestType: OriginECC auth: serviceKeyRef: name: origin-ca-service-key key: key
- Deploy the issuer:
kubectl apply -n default -f origin-ca-issuer.yaml
- To verify that the issuer is ready run command
kubectl get originissuer.cert-manager.k8s.cloudflare.com origin-issuer-production -o yaml. Look for the
statuspart of the output, which should look like this if successful:
status: conditions: - lastTransitionTime: '2021-03-13T14:28:16Z' message: OriginIssuer verified and ready to sign certificates reason: Verified status: 'True' type: Ready
Issue a certificate
Now with the Origin CA issuer ready it’s time to create an actual certificate.
- Create a new file
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: origin-cert spec: secretName: origin-cert dnsNames: - www.example.org duration: 168h renewBefore: 24h issuerRef: group: cert-manager.k8s.cloudflare.com kind: OriginIssuer name: origin-issuer
- Deploy the certificate:
kubectl apply -n default -f origin-cert.yaml
- Check if the certificate request is successful with command
kubectl -n default get certificate origin-cert. Column
READYshould be True:
NAME READY SECRET AGE origin-cert True origin-cert 10m
Use with Traefik IngressRoute
With the Origin CA issuer configured we’re now able to use the certificate with any Ingress Controller. I’m currently using Traefik and its
IngressObject CRD. Below is an example on how I would configure the certificate that was issued in previous step:
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: example-ingressroute spec: entryPoints: - websecure routes: - match: Host(`www.example.org`) kind: Rule services: - name: example-web-service port: 80 tls: secretName: origin-cert
cert-manager, with the help of the Origin CA Issuer, will now automatically keep this certificate renewed.