Deploying your Certificate Authority
Posted on: 2025-02-03
SSL certificates used to be a big business, with every organization having to pay money to a handful of companies to obtain a certificate signed by a trusted Certificate Authority (CA). The Let's Encrypt project was a great benefit for the Internet at large, bringing free and easy to deploy certificates to everybody. Today, the need for you to deploy your own CA is much less, and if you have a public web site I highly encourage you to use the Let's Encrypt system to get a valid certificate. However, there are still use cases for deploying your own CA. One example is for internal sites, where both the HTTP and DNS endpoints aren't available for validation. Another example is an air-gapped network. Whatever the case, it's never a good idea to rely on self-signed certificates, so here I will show you how you can easily deploy your own CA, create a wildcard certificate for all your sites, and then add the certificate to your devices trust stores.
Before we write our first script, it's important to speak about security. In an organization, your CA is one of the most important pieces of your digital infrastructure. It allows people to impersonate your digital assets. So it's important that you create these assets on a secure system. This means you should have an air-gapped computer (or at least virtual machine) that you keep offline except when you need to create a certificate.
The first script we'll write is make_ca_cert.sh
and it will be used to create the CA key and certificate:
#!/bin/bash
openssl genrsa -aes256 -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt -subj "/C=CA/ST=QC/L=City/O=Example/OU=IT/CN=My Example Root CA"
openssl x509 -outform pem -in rootCA.crt -out rootCA.pem
echo "CA Certificate (unix): rootCA.crt"
echo "CA Certificate (pem): rootCA.pem"
This script will create three files. First, a private key for the root CA. Then, the actual certificate will be created in 2 different formats. Note that this key should never leave your air-gapped server. The certificate files can be distributed to any device that needs to trust your new CA. This CA will last for 10 years.
The next step is to create extended.cfg
which will contain some configuration values for our end certificate:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.example.com
DNS.2 = example.com
DNS.3 = test.example.com
This is where you define which hostnames should be covered by the certificate. You can also use a wildcard for the certificate to apply to any subdomain.
Finally, let's create make_wildcard_cert.sh
to craft your certificate:
#!/bin/bash
openssl genrsa -out wildcard.example.com.key 2048
openssl req -new -key wildcard.example.com.key -out wildcard.example.com.csr -subj "/C=CA/ST=QC/L=City/O=Example/OU=IT/CN=My Example Root CA"
openssl x509 -req -in wildcard.example.com.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out wildcard.example.com.crt -days 380 -sha256 -extfile extended.cfg
openssl x509 -in wildcard.example.com.crt -text -noout
echo "Key: wildcard.example.com.key"
echo "Certficiate: wildcard.example.com.crt"
This will create two files, a private key and a certificate. Both files should be stored on any host that will need to use them, such as web hosts. You can simply copy them to /etc/certs
and then use them with Nginx, Apache, etc. The certificate will last for a year, which means you need to create a new one each year on the anniversary date.
The last step is to add your CA to the trusted list on client devices:
- Microsoft Windows: Copy the rootCA.pem file to the Windows device then double click on it. Select Install, and make sure you select a custom certificate store. In the list of stores, select Trusted Root Certificate Authorities.
- Firefox: The Firefox browser doesn't use the OS's certificate store. You need to go to Settings -> Certificates -> View Certificates then click on Import and select rootCA.pem.
- Linux: On Linux systems, copy the rootCA.crt file to /usr/local/share/ca-certificates then run the
update-ca-certificates
command. - Apple iOS: On iPhone or iPad, copy the rootCA.pem file and double click on it. Then go to Settings -> General -> VPN and Devices to install the CA. Then, go to Settings -> General -> About -> Certificate Trust Settings and enable the installed certificate.