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
To get started with Cloudflare’s Origin CA Issuer all you need is:
- a k8s-cluster with cert-manager deployed
- a Cloudflare account
Instructions for installing and source manifests can be found in GitHub repo github.com/cloudflare/origin-ca-issuer. As I prefer using Kustomize for managing k8s I’ve also raised a PR for adding a
kustomization.yaml to the repo. Until that gets added I am using my own fork to simplify deployment.
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.
Comments powered by Talkyard.