Using "fake" certificates for development on OSX with Cert Manager, Let's Encrypt Staging, and Kubernetes Helm

Using "fake" certificates for development on OSX with Cert Manager, Let's Encrypt Staging, and Kubernetes Helm

I am planning on using Kubernetes and Cert Manager along with Docker for Desktop locally for development.

Cert Manager provides a "staging" certificate authority that creates free, "fake" certificates using Let's Encrypt for development purposes.

The reason for using the staging certificates as opposed to the production certificates is that the production certificate authority 1) takes longer to provision certificates, and; 2) is rate limited; 3) you can only make 5 mistakes when provisioning certificates with the production environment.

There is a Failed Validation limit of 5 failures per account, per hostname, per hour. This limit is higher on our staging environment, so you can use that environment to debug connectivity problems.

The staging certificate authority has a higher rate limit, allowing you to say, requests more "fake" certificates for a bunch of apps you're creating locally.

The downside is that you get a nasty error saying that "the site can't be trusted" in the web browser, something I'll address at the end of this post.

So I was wondering if there was a way to download the certificates created by cert-manager in a local Kubernetes cluster into the local operating system and install them or "trust" them to avoid the "untrusted site" message.

So after a short Google search, I concluded that you can:

  • 1) Download any online certificate (including from localhost) with openssl s_client -showcerts.
  • 2) Convert the output from the first command into a certificate file via openssl x509 -outform PEM.
  • 3) On OSX, use security add-trusted-cert to add the newly minted certificate into the local trust chain.

So, without further ado:

Let's make sure our target environment is running:

curl https://localhost --insecure

Then, this openssl command shows us the certificate

openssl s_client -showcerts -connect localhost:443 -servername localhost </dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

If you don't add 2>/dev/null, any errors that appear before BEING and END will show up, which in turn will prevent us from piping the output to create a new certificate file.

Add the command to create the certificate file using the output from the previous command: openssl x509 -outform PEM >cert-manager.local:

openssl s_client -showcerts -connect localhost:443 -servername localhost </dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'|openssl x509 -outform PEM >cert-manager.local

After that is done, you can add the certificate to the OSX list of trusted root certificates.

sudo security add-trusted-cert -d -r trustAsRoot -k /Library/Keychains/System.keychain cert-manager.local

Two important things to note:

  • When using Helm cert-manager, and the Let's Encrypt staging certificate provisioner, use the option -r trustAsRoot.
  • When I used -r trustRoot instead of -r trustAsRoot, I still got the invalid certificate error in Chrome. DO NOT USE trustRoot.

The proof is in the pudding:

Connection is secure, Certificate is Valid
This certificate is marked as trusted for all users

Good job!

Inspiration for this post: