It's that time of the day... You sit down at your computer to access your application you're running on Kubernetes. You navigate to your site, and what's this!? Someone has defaced it! Oh no, looks like you didn't have your ingress secured and someone has sniffed all your traffic and gotten your admin password. This of course, is what could happen, but we're smart SysAdmins - we're going to secure our ingress controllers using Let's Encrypt.
But what is Let's Encrypt?
If you've read my Article on TLS (which you should), you know that securing a website is important because it allows each party to trust that they are the only ones participating in their conversation. A few years ago, the ability to provide encryption on a website was hampered by the fact all Certificate Authorities (CAs) issued SSL Certificates for cash. This meant that for most hobbyists or smaller websites, securing their stuff was expensive. Enter Let's Encrypt, a service run by the non-profit Internet Security Research Group. Let's Encrypt effectively has democratised access to secure communications by maintaining a CA that issues Certificates for free. That's right, free as in free beer. This means that you can setup TLS on your website for free, and anyone who access your site does so with the knowledge and comfort that your communication is secure. A vitally important, yet criminally underrated privilege that a lot of people take for granted.
Building the Door
This process for configuring Let's Encrypt is relatively straight forward thanks to
cert-manager, a project by Jetstack. We're going to use
cert-manager and Digital Ocean DNS to provision our certificates. Let's get started by jumping into
kubectl and installing our components.
# Creates Namespace kubectl create namespace cert-manager # Installs Custom Resource Definitions and the cert-manager Services kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.12.0/cert-manager.yaml
This setups up the basic pods and configuration required to run
cert-manager. The main configuration items we need to take care of, is setting up our Digital Ocean API Key, and creating our Cluster Issuers. Before we creating our Digital Ocean Secret, we need to go to the Digital Ocean Control Panel and Generate an API Key. Once this is done, let's create the Secret:
kubectl apply -f dns_secret.yaml
Now we've got all our configuration in place, we just need to tell
cert-manager how to issue certificates for our Cluster. We do this using ClusterIssuers which can issue Certificates across all Ingress in our Cluster. The cluster issuer consists of two pieces of configuration: your email address (for notifications) and solver configuration (so that Let's Encrypt can prove you own your domain). With these in place, we can get to the part where we actually secure our Ingress!
kubectl apply -f production_do_dns_issuer.yaml
Installing the Lock
We're finally on the home stretch! The final step is to apply our TLS configuration to our Ingress. This involves:
- Adding a
cert-manager.io/cluster-issuerannotation which tells
cert-managerthat we want a Certificate issued by the listed ClusterIssuer.
tlsblock under the spec that lists the host names we want the Certificate to provide TLS for, as well as the name of the Secret where the Certificate should be stored.
# production_ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: [...] annotations: # Add our annotation cert-manager.io/cluster-issuer: letsencrypt-production spec: # Add our host and Secret configuration tls: - hosts: - www.example.com - example.com secretName: wp-example-com-tls-production [...]
kubectl apply -f production_ingress.yaml
Once this changes have been applied to the ingress, the following will occur:
- a TXT record will be placed into your DNS Zone by the
- a secret will be created in the same namespace as the ingress with the name listed at
spec > tls > secretName.
Within about five minutes, your Certificate will be issued and if you refresh your site it will now be secured.
See, Totally Easy!
As you can see, it is very easy to setup TLS on our Ingress on Kubernetes. No one could possibly have any excuse to let their own and their customers private communications be snooped on by third party actors. I love TLS and this is probably my favourite article of the series. Security is really important, and it is easy to forget that given how ubiquitous and easy it is to use in our modern day. However, we can't let our guard down because threats and bad actors take a high baseline of security into account. Don't be easy pickings.
If you liked this article, consider giving Let's Encrypt a donation, or you could just follow me on Twitter @stophammotime. Thanks for reading, and see you for the next installment where we setup backups on our Cluster.