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.yaml
and 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 origin-ca-issuer
.
- 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,
origin-ca-issuer.yaml
:
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 thestatus
part 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
origin-cert.yaml
:
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
. ColumnREADY
should 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.