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
helloworld

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'
-----BEGIN CERTIFICATE-----
MIICmDCCAfmgAwIBAgIFEjRWeJAwCgYIKoZIzj0EAwQwNDEVMBMGA1UEChMMY2Vy
dC1tYW5hZ2VyMRswGQYDVQQDExJjZXJ0LW1hbmFnZXIubG9jYWwwHhcNMTkwNjEx
MDA0MzEwWhcNMTkwOTA5MDA0MzEwWjArMRUwEwYDVQQKEwxjZXJ0LW1hbmFnZXIx
EjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAK8WsXnkzvn495bgsoPzgfMWUR+Oc/XZfVH1t4xmN9brpGgleWpgyFwLLXBC
kwPW+APSdoT/m3onegTqjYl66M0rkm2Xmr19o6NFEtWN4JuIV2xKtYAd7q9jymyM
b354joiv/fRveXFsR5Uvl4r/FrlLm5xjrY7ltv6j/nVx4mkMDaKH9YSsIftw2OiW
V9lrXWo9midpi7YFmCtO1xDSa/o6nI3WBFnveK/49A9PrKwtJ81LStREORuu3lQ+
Id9xDkrIPFi/uzBqV7vYoU+gh0i4Ix2y8O1y/OtPdZ1P0u2yq5p9nk2j5Segb89C
kxWgPopX5seY7Y1VJ6q5PKg2s2sCAwEAAaM2MDQwDgYDVR0PAQH/BAQDAgWgMAwG
A1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJbG9jYWxob3N0MAoGCCqGSM49BAMEA4GM
ADCBiAJCAOPIV74NoCPbhoW3nkTLYV40bt8DaE6U+x3FvGZkWY+8bP4bkSAMKO6a
U+N5bPcSFoRPfn8ItkIdM3UNemxd5+wFAkIB+Gy7ie8FXVgraZdYVSiqttxhI4ne
j7xuiaJtMjMcQduQGmTvJKaWmwB0YJkhC5qCvuXKFRxdhSyk7XAZM1XmdV8=
-----END CERTIFICATE-----

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: