How to use cfssl to create self signed certificates

There are man articles on CloudFlare’s PKI toolkit, but no single article had all the tasks detailed for the pattern I use, so I thought I’d put them here.

Installation on Linux

Unfortunately, at the time of writing, the latest packaged version (1.2) contains a bug that makes it impossible to create certificates with hosts, so the software must be installed with Go.

The Pattern

The root of all the certificates is a certificate authority (or “CA”) from which all other certificates are signed. Typically this is used to create one or more intermediate certificate authorities. These intermediates are used to sign certificates for clients, servers and peers (a host that can act as both a client and a server).

The Certificate Authority

To create a self signed certificate authority for a company called “Custom Widgets” based in London, England, Great Britain, create the following config file “ca.json”.

The following command creates “ca.pem” and “ca-key.pem”


The next steps require a profile config file. The profile describes general details about the certificate. For example it’s duration, and usages.

Create the following file “cfssl.json”.

We can see how the “client” profile specifies “client auth” in its usages, while the “server” profile specifies “server auth”.

The Intermediate CA

To create an intermediate certificate authority create the following config file “intermediate-ca.json”.

The following commands creates “intermediate_ca.pem”, “intermediate_ca.csr” and “intermediate_ca-key.pem” and signs the certificate.

Note the second “sign” command uses the CA produced previously to sign the intermediate CA. It also uses the “cfssl.json” profile and specifies the “intermediate_ca” profile.

Host Certificates

Here is an example host certificate config file “host1.json”.

There are some choices to be made here that depend on what the server and client software expect. Some software just checks the common name “CN” and doesn’t need a hosts section. Some software requires the IP address in the hosts section.

To generate the certificates with the above config do the following:

Typically we just require a server certificate. Some systems also support client authentication, and clusters often require peer certificates to allow the servers to communicate with each other.

Installing The Certificates

Typically the public certificates are stored somewhere public, while the private keys are “locked away”; in particular the CA’s. We’re creating certificates for a development environment, but it simplifies things to put the certificates in expected places.

On Ubuntu 18.04 with the “ssl-cert” package installed, I put the public certificates in “/etc/ssl/certs” and the private certificates in “/etc/ssl/private”. The “ssl-cert” package creates a group “ssl-cert” which has ownership of the private folder. Apps which need access to private keys can be added to this group.

Update: 2019–11–08

I’ve created a makefile to automate this process here.