Export certificates and keys from Kubernetes

One of the things I really believe in is a layered security approach, if one of the layers fail you will have other layers still providing protection. One of the first layers is often the network. However even if you have a “next-gen” / layer-7 firewall, it is only fully utilized when the traffic is “readable” and therefore not encrypted. Think of protection against SQLi, XSS, etc.

Nowadays it is very easy (and free) to protect your services with TLS, think of services like Let’s Encrypt. With Kubernetes it is even easier, as you can use the cert-manager to automatically request and renew certificates.

These certficates and keys are stored in Kubernetes as secrets. When you want your firewall to decrypt the traffic, you need to export the certificates and keys from Kubernetes and import them to your firewall, in my case a Palo Alto Networks firewall. This is called SSL Inbound decryption, since we own the certificate and private key, the firewall can simply read along. Just to note, this is different with SSL Outbound (Forward Proxy) decryption, wich is a bit more complex or at least it involves additional components.

To list all the certificates on your Kubernetes cluster run the following command:

> k get certificates -A
NAMESPACE       NAME                              READY   SECRET                               AGE
website         blog.breekeenbeen.nl              True    blog.breekeenbeen.nl                 110d

The output is slightly modified to not expose all applications and URLs.

Now that we now the namespace and the name of the secret we can export the certificate and key to a file, this however has a few caveats. The secret, basically consistes of two entries, the certificate and the key. Secondly the certificate and key are base64 encoded. So we need to decode the base64 encoded certificate and key and write them to a file.

The easiest way is to print the output to json format and use jq to export the specific field, this output can then be base64 decoded and written to a file.

k get secrets -n website blog.breekeenbeen.nl -o json | jq -r '.data."tls.crt"' | base64 -d > blog.breekeenbeen.nl.crt
k get secrets -n website blog.breekeenbeen.nl -o json | jq -r '.data."tls.key"' | base64 -d > blog.breekeenbeen.nl.key

Now that we have the files, we can normally import them into our firewall. In my case I use a Palo Alto Networks firewall, which won’t accept the key file without a passphrase set (when using the WUI import). So I need to add a passphrase to the key file.

openssl rsa -aes256 -in blog.breekeenbeen.nl.key -out blog.breekeenbeen.nl.key

Now we can import the certificate and key into the firewall and create a decryption rule.

See the column on the right, this is indicates that the traffic is decrypted.

This work great, however since (Let’s Encrypt) certificates will renew every 90 days (not the private key), it would make sense to automate this process.

Rob Maas
Rob Maas
Technical Challanger at ON2IT

If it is broken, fix it! If it ain’t broken, make it better!

Related