Certificate Authority is not Voodoo

Investigation of available options for running and operating a Certificate Authority for modern applications

Modern applications tend to get fairly complex pretty quick. A usual stack will consist of many moving parts. Starting from a cloud environment, maybe abstracted behind Kubernetes or Mesos, through multitude of web servers, GRPC services, to monitoring systems like Grafana, Jaeger, Prometheus, all fronted with load balancers or proxies like Traefik. Many of these components have fairly complex dependencies, ETCD or Zookeeper come to mind. All these power a highly dynamic environment where containers and virtual machines iterate and get replaced often. Some businesses operate multiple copies of stacks for development, staging and production environments.

With so many gizmos and the security breaches happening on a nearly daily basis, it’s important to ensure that the traffic between the individual systems can be traced, what is probably even more important: authenticated and encrypted.

In cloud environments, vendor provided tools help to a certain extent. For example, a common pattern in AWS is to use security groups or / and ACLs. As efficient as they are, one only gets so far. Security groups will not help with containerized workflows. An individual host can run containers for different workloads, maybe different customers. Maybe Kubernetes has some answers for some with its networking capabilities. For more advanced requirements, Project Calico [1] may come handy. But even then, certain workflows can’t be covered with any of that.

This is where many people will turn to TLS. Today, it is very difficult to find software that would not support TLS out of the box. With HTTP / public facing applications, things are pretty easy. Thanks to Let’s Encrypt[2], anybody can get TLS certificates for public facing systems for free. That is awesome. But what about internal infrastructure? Let’s Encrypt, even though the limits are generous, does not really work very well. Fair percentage of software integrates well with Let’s Encrypt. For example nginx, Traefik. But not everything. And what about the systems identified by IP addresses? What about internal DNS names?

Organizations end up shoehorning a custom TLS solution, very often disregarding the most reasonable answer: running a custom Certificate Authority.

To be honest, even a few years ago, running a custom PKI, Certificate Authority, beeing a part of it, was a hassle. Searching for ready recipes for how to set things up in order to get a root certificate, many tutorials glossing over the importance of intermediate certificates, certificate signing requests, … Ins and outs of configuring and running a CA seemed to be some secret, insider’s knowledge.

My personal perception is that the raise of Golang, with its unprecedented ease of crypto library use, broke this trend and brought TLS to the masses. There are many complete code examples in Golang tests. Even today, not taking away from the authors of BouncyCastle (which is really, really, really awesome when one knows the library), trying to do more complex things with TLS in Java can be mind boggling. Maybe the impulse came in 2013, with Ivan Ristić publishing the Bulletproof SSL and TLS [3] book, which is a immense resource for anybody trying to master SSL and TLS, I don’t know. Sorry, slight deviation, personal perception…

A software developer who is looking to implement TLS at some point is going to search for

how to generate an ssl certificate

Answers will turn up. Majority of these will show how to get a self-signed certificate. A self-signed certificate is generally okay, for example, in integration testing there is no real need for a CA. In tests, it does not matter who issued a certificate, what matters is that TLS works.

However, the problem with a self-signed certificate is that it is not signed by a Certificate Authority. So, yes, it does provide security in the sense that the traffic is TLS encrypted, but it does not tell anything about who generated and deployed the certificate. Anybody can issue a self-signed certificate for anything and it’s going to take some effort to figure out where it came from. A Certificate Authority with the correct set of intermediates is going to to provide a verification chain required to properly ensure the authenticity of a certificate.

It’s fair to say that a production system should not see a self-signed certificate in operation.

§What are the options

Below is a very brief overview of a few modern Certificate Authority options.

§OpenSSL Certificate Authority

Starting from the most widely available tool for creating a Certificate Authority: OpenSSL. The one and only resource I can recommend for anybody who would like to setup and operate a CA with OpenSSL is the OpenSSL Certificate Authority guide created by Jamie Nguyen. [4] The reader of the guide will find a very well documented step-by-step guide, where every step is easy to follow and well explained. An appendix to the the guide contains ready to use recipes.

All documents available on that website are licensed under Creative Commons Attribution-ShareAlike 4.0 International License.

For actual operating, a knowledge of OpenSSL will be required.

§CFSSL

A good alternative is CloudFlare’s PKI/TLS toolkit: CFSSL. [5] Written in Golang, available on GitHub. CFSSL offers a command line and a HTTP API for signing, verifying and bundling TLS certificates. With CFSSL, one can stand multiple Certificate Authorities within minutes. The readme offers a pretty good overview of the capabilities.

Available under BSD-2-Clause License.

§Square certstrap

Another tool written in Golang, this time from Square, the company providing financial and merchant services. Square certstrap is also available on GitHub. [6] This tool offers a very easy to use command line API for creating new Certificate Authorities, identities, certificate signing requests and generating and signing certificates. As with the previous solution, the readme gives a great overview or what’s possible.

Available under Apache 2.0 License.

§HashiCorp Vault

HashiCorp is a very prominent player in the modern infrastructure software. Known for tools like Vagrant, Packer, Terraform, Consul, and Vault. One of the features of Vault is the PKI. From all the tools mentioned here, HashiCorp Vault PKI [7] is by far most complete and the easiest to integrate into an existing infrastructure.

It comes packaged as a binary, there are Docker images available. Vault itself can be configured for high availability. It offers a command line API and a HTTP API. Vault can host multiple PKIs in a single installation. Access to each PKI can be controlled using Vault policies and the access is protected by tokens with configurable leases. It’s really good. By default, Vault PKI is configured with a root certificate generated by Vault. Alternatively, a root bundle can be imported. There is a very good guide on setting up a fresh PKI with Vault: Build Your Own Certificate Authority (CA).

§Conclusion: lower bar of entry

No matter which tool is the tool of choice, there are still challenges in operating a Certificate Authority. Root and intermediate certificates have to be stored secure, they need to be rotated. Preparing an underlying, bulletproof infrastructure for reliably relaunching a Certificate Authority is not a walk in the park. Certificate Revocation Lists are still difficult. In certain environments, certificate distribution is a challenge.

On a positive note: the bar of running a CA is today much lower.