Let's Embark! Securing our Internet Treasures (Part 3)
Tags: devops, tutorial, kubernetes, security
Published: 2020-01-30 16:22:28

_Today we secure our Ingress! Security is one of the most important parts of any modern software installation. Let's see how easy it is to get 'er done on Kubernetes._

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](https://letsencrypt.org/).

![Let's Encrypt](https://dev-to-uploads.s3.amazonaws.com/i/3kmp7ggialxqrw885ry5.png)

## But what is Let's Encrypt?

If you've read my [Article on TLS](https://engi.fyi/establishing-trust-why-tls-should-be-important-to-you/) (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](https://www.abetterinternet.org/). 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](https://www.jetstack.io/). 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](https://www.digitalocean.com/docs/api/create-personal-access-token/) (here's a [referral link](https://m.do.co/c/f250f695871e), although DNS is free with Digital Ocean). Once this is done, let's create the Secret:

```
# dns_secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: digitalocean-dns
  namespace: cert-manger-issuer
data:
  access-token: <DIGITAL_OCEAN_API_KEY>
```

```
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!

```
# production_do_dns_issuer.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: do-issuer-production
  namespace: cert-manger-issuer
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: <YOUR_EMAIL_ADDRESS>
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-production
    # Enable the DNS-01 challenge provider
    solvers:
    - dns01:
        digitalocean:
          tokenSecretRef:
            name: digitalocean-dns
            key: access-token
```

```
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:
1. Adding a `cert-manager.io/cluster-issuer` annotation which tells `cert-manager` that we want a Certificate issued by the listed ClusterIssuer.
2. Add `tls` block 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:
1. a TXT record will be placed into your DNS Zone by the dns01 solver.
2. 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](https://letsencrypt.org/donate/), or you could just follow me on Twitter [@stophammotime](https://twitter.com/stophammotime). Thanks for reading, and see you for the next installment where we setup backups on our Cluster.