Encrypting traffic between Cloudflare and Kubernetes cluster

I noticed that some Kubernetes admins/developers do not configure encrypted communication between Cloudflare and their Kubernetes cluster because they consider that as not necessary. But I wouldn’t take Cloudflare’s proxy for granted, it always better to secure as much as you can. So I have written this article to guide you to encrypt the communication between Cloudflare and your Kubernetes cluster and also make it simpler.

Objective

We are going to take the following setup, where traffic between the Cloudflare and the cluster is unencrypted.

localhost

And implement the following setup, where the traffic is encrypted between the Cloudflare and the cluster.

localhost

Steps to do it

  1. Login to your Cloudflare Dashboard. Select a domain; this domain name will be the primary domain to communicate between Cloudflare and your cluster. Click on SSL/TLS Icon and the select origin server. Choose the following parameters:

    localhost

  2. Once done click next; on the next page, you will see the private and public key. Save the origin-certificate with a name of your choice. I chose site.cert and Private key as site.key.

  3. Create a TLS secret on your cluster using the following command.

    kubectl create secret tls my-site-cert –key site.key –cert site.cert

  4. Create config in traefik to use this cert.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: site-a
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`gokulakrishna.com`)
kind: Rule
services:
- name: mysite
port: 80
tls:
secretName: my-site-cert

Extending to other domain names

Now with this setup, you can handle multiple domain names. Let’s say you now have a site with sample.com. You add it as a CNAME record to the above endpoint that you have set.

  1. Switch to another domain on Cloudflare.

  2. Add a record with target as the record that you have set previously. In my case (cluster-loadbalancer.gokulakrishna.com).

  3. Make sure encryption mode is full.

    localhost

    Note that if any part of the communication is not encrypted the request might fail