Create a WORKING Private Certificate Authority FREE with Openssl

Hello and welcome back! In this post we are going to address how to create a private Certificate Authority (CA) with opensource tools, mainly Openssl. Having a private certificate authority allows you to trust private sites, for example: a private https server serving content in a private network can be trusted by the browser so you don’t get the annoying security problem.

Let examine the requirements, you will need:

  • Basic knowledge of Linux (opening a terminal session, setting permission, and execution)
  • Basic knowledge of file editing, you will need to edit a script and assign some configuration variables
  • Basic knowledge of how Certificate Authorities and certificates work, you will have to add the CA certificate to the trust store you decide to use. This post has a few example, but I cannot cover all trust store databases

Now that we have outlined  the requirements, let’s start to create the certificate authority. I developed a script to facilitate the process. All the script really need is openssl libraries installed. In modern Linux systems, openssl is installed by default. The script is available here. Go a head and download it, copy it to a Linux server somewhere in the PATH, like /usr/local/bin, and assign execution permissions with the chmod 755 /usr/local/bin/ca-ops.sh. Now that the script is installed and ready to go, let’s start using it.

Open a terminal session and type the following command:

ca-ops.sh -h

The script should display the help screen, if not, make sire the steps above are followed. The help output should be similar to:

usage: ca-ops.sh [options]
   -h display this help message
   -a create CA Key and Certificate
   -g generate a certificate signing request (must be used with -n)
   -n common name for the certificate signing request (must be used with -g)
   -s sign a certificate request
   -v view content of certificate (must be used with -r)
   -f the file to use with sign, or view operations
   Example: ca-o.sh -a # Create CA root key and certificate
   Example: ca-o.sh -g -n myserver.local # Generate a certificate signing request for myserver.local
   Example: ca-o.sh -s -f myserver.local.csr.pem # Sign the certificate request and create myserver.local.cert.pem
   Example: ca-o.sh -v -f myserver.local.cert.pem # View the content of the certificate

If you get the output above, we are in good shape; now it’s time to edit the script to change a few variables for proper execution. More precisely, you need to edit the following block:

CA_DIR="$HOME/ca-private"
CA_PRIVATE_DIR="$CA_DIR/private"
CA_NEWCERTS_DIR="$CA_DIR/newcerts"
CA_CERTS_DIR="$CA_DIR/certs"
CA_CRL_DIR="$CA_DIR/crl"
ORGNAME="The Org Name"
COUNTRY="THE TWO LETTER COUNTRY EXAMPLE (US)"
STATE="THE TWO LETTER STATE"
CITY="THE CITY"

ORGNAME, COUNTRY, STATE, and CITY should be set based on your location. You can also change the location of the CA_ variables to better suit your needs. Once you are done with that, let’s now generate the root CA key and certificate. This is a very important step and the CA certificate is the one that you need to import in all the clients that will communicate with the HTTPS servers with the certificates that we are going to generate later will serve. Let’s now execute the following command:

ca-ops.sh -a

If all goes well, the script will prompt you for two passwords, one for the key and one for the PEM. For simplicity, this post assumes you use the same password for both. The passwords unlock the CA private keys, so use something not easy to guess. If everything goes well, you should get output similar to:

Creating directory: /home/user/ca-private/private
Creating directory: /home/user/ca-private/newcerts
Creating directory: /home/user/ca-private/certs
Creating directory: /home/user/ca-private/crl
Creating Initial Root CA key and certificate...
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
Enter pass phrase for /home/user/ca-private/private/cakey.pem:
CA key and certificate created in /home/user/ca-private.
Secure the CA key and certificate, and do not share the CA key with anyone.

Great! Now you have the root CA key and Certificate. Go a head and import the following file /home/user/ca-private/cacert.pem in the trust store you will use to verify the signature, this can be a browser (Firefox, Chrome, Edge, etc) or a system (Windows, MacOS, Linux). Refer to the documentation for the appropriate system how to import the certificate.

NOTE: you might need to rename the pem file to crt for some systems.

Let’s now move on to create a signed certificate for an endpoint, like a website, let’s assume the website common name (CN) is site.example.com, this of course will change depending on what/where you are configuring.

The two steps are: generate a CSR (Certificate Request), you could do this with another system, many systems have CSR generation built-in, but in case you need it follow the step below, if not skip to the sign part.

The generate a CSR for a domain called site.example.com, type the following command:

ca-ops.sh -g -n site.example.com

If everything goes well, you will see an output similar to:

Generating certificate signing request for common name: site.example.com
...+..+....+......+...+............+........+.+.....+.+.....+..........+...........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...........+..+.............+...........+......+.+...............+..+.+.....+....+.................+.+...+.........+...+..+...+.......+..+...+......+....+...+........+......+...+............+......+.......+.....+...+.......+..+.+...+..+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.........+....+..+.........+....+....................+.......+..................+..+..........+........+......+.........+...+....+...................................+...+.+......+...+............+...+..+....+...............+......+...+..................+...+..............+................+......+........+.......+......+.........+......+..+.+.....+......+.+..+...+...+......+......+.......+...+...+..+.......+..+.........+............+....+....................+.+..+..........+........+...+......+....+.........+...+..+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.+...+....+..+.+.........+.....+...+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+......+.+.........+.....+.+........+......+.+..+...+....+...+.....+.+.................+...+......+.+..+.......+.....+...+...+....+........+...+....+...+......+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+.+..+.............+.........+...+.....+.............+...+..+...+..........+...........+................+..+.......+.....+.+.........+.....+.+..+.+......+...........+..........+............+........+...............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
Certificate signing request generated: /home/user/ca-private/certs/site.example.com.csr

If you did thie step on a separate system, for the sign part to work, you will have to copy manually the file into the CA_DIR/certs (/home/user/ca-private/certs) directory and call it site.example.com.csr, now let’s sign the certificate, in order to do that, type:

ca-o.sh -s -n site.example.com

The script will prompt you for the CA password you set above, you only have one time to type it, if you make a mistake, simply re-execute the command. If everything goes well, you will have a signed certificate in the CA_DIR/certs directory called site.example.com_signed.crt which together with the key file: site.example.com.key will make the files necessary to serve the certificate, depending on the product used, you might have to also load the CA certificate to be served. In the directory, there is also a chain file that can be useful for some products. I’ve included all the combinations I am aware of.

At this point, if you loaded the CA certificate in the trust store of the client (Browser) and the signed certificate on the server for example: nginx, when you reach the site and the doman match the certificate, you will not get a security warning.

The CA_DIR directory contains all the certificates generated, so backup this directory, if you lose it, you will have to start from scratch.

I hope this article was useful and that will help you setup a CA and use it.

Leave a Reply