If you have not read my previous post on How do SSL certificates work?, go read it first!
Moving on, this post is about setting up an certificate authority for company-internal use.
Most CA setups are for company-internal usage, unless you are planning on starting multi-million dollar CA business by investing years and some serious cash to get through start-of-operation audits, periodical audits, setting up hardcore secure infrastructure with tight access controls, TPM modules and such. :)
Company-internal essentially means that we use a self-signed root certificate to provide certificates only internal to our company. That means that because we don’t have to (or want to) fill all the requirements of those above mentioned public CA’s, we can easily use all the benefits (like client certificate authentication) of public key infrastructure to our advantage.
We use this to provide authentication and TLS-encryption for internal (“backoffice”) applications.
Even though this is for internal usage, our CA is used to authenticate into mission critical internal services that must not be compromised. Thus, the encryption keys backing the certificates must be protected really well. In addition to that, one should think of:
- Set up the root CA to be in an offline and air-gapped setup (think Raspberry Pi without network).
- Use multi-level CA (online or offline, depending on needs) architecture (“intermediate CA”), so intermediate CAs can be revoked.
- Implement an online certificate revocation list, possibly hosted on AWS S3.
- Have the CA’s private key stored in a TPM (or equivalent) module.
We don’t currently implement the above points, but we should look into that in the future.
This sounds hard - why do it?
Good question! Not all companies use SSL certificates - probably because it’s hard to set up and manage. But the tooling is getting better and easier, so I hope client cert authentication is here to stay. Here are a few benefits:
Once the CA is set up, configuring server apps to use it is usually pretty damn easy.
Client certificate authentication is implemented in pretty much every programming language and HTTP server library there is. You don’t have to reinvent the authentication/authorization layers, and thus they are probably more secure than anything else you or anyone else would write.
If you have 10 services where the user can log in and you hire a new employee, granting access does not have to mean adding the user manually to those 10 services. If those services use client cert authentication, all you have to do is issue the certificate to the user and not touch those services. Certificate authentication is effectively offline access control, as the server does not have to contact the CA to ask if this certificate has authorization to this service. The CA signs this authorization once, and the user effectively delivers this signature herself to the service.
Since you’re implementing authentication on top of TLS, you get guaranteed encryption for free. This means that even if your employess log in from an unsecured network from a coffee shop, your data is safe.
Client certificate authentication protects you from keyloggers, as you don’t have to type in a username and password. Though this fact can be diluted by the fact that if a keylogger compromises your computer, another malicious program could as well steal your private keys related to your client certs (unless you use a hardware security module).
How do I use the certificates issued by a CA?
For concrete usage, see our loadbalancer configuration.
Choosing a toolkit for CA management
Choosing a toolkit for this task was not easy. I was not fond of using OpenSSL, since it requires keeping more state than should be required: verbose and complex config files and counters which more modern toolkits statelessly implement with randomization. OpenSSL did not felt modern and as automation friendly as I had hoped.
Ultimately, Cloudflare’s cfssl fit this task rather nicely. It supports automation out of the box very nicely via JSON and it doesn’t require any configuration, if all you want to do is call if via command line. And it’s a nice bonus that I already trust Cloudflare as their long-time customer.
However, their documentation was really lacking (thanks CoreOS for having a better tutorial!), and the
compiled binaries on their official website were outdated and there was bug or feature lacking in
feature that did not respect the expiration date in the certificate signing request. I had to
statically compile the binaries myself.
Why statically? So they work on Alpine linux that has a different standard library.
More alternatives and research is documented on the below mentioned repository!
How do I set up a CA?
Since I had to take notes while setting up a CA anyway, I figured I’d open source my research in the form of an example CA (pretty much 1:1 our production setup): github.com/function61/certificate-authority
If you’re reading this far, you are probably interested of this subject. Check out that repo to learn more!