Skip to content

Creating a Certification Authority

The instructions on this page will walk you through the process of creatng a local certification authority (CA) that you will then be able to use to create self-signed TLS certificates that can be used to implement secure HTTPS communications between client and server applications.

These instructions are for use on a Linux system. Log in to the system using a user account with admin (sudo) privileges.

Install OpenSSL

Many Linux systems will already have OpenSSL installed. You can check like this:

openssl version

OpenSSL is installed if you see version information displayed. If not, you can use the systems package manager to install it. For example:

For RHEL / Rocky / Fedora / Alma / CentOS / Oracle Linux:

sudo dnf install openssl openssl-devel -y

For Debian / Ubuntu / Linux Mint:

sudo apt update
sudo apt install openssl libssl-dev

For openSUSE:

sudo zypper install openssl openssl-devel

For Arch Linux / Manjaro

sudo pacman -S openssl

For older systems, try:

sudo yum install openssl openssl-devel

Create a Local CA Directory

mkdir local-ca
cd local-ca

Make a Certification Authority Configuration File

Use your text editor of choice to create a new file:

vi local-ca.cnf

Then add the following content:

[ ca ]
default_ca = CA_default

[ CA_default ]
database         = ./index.txt
new_certs_dir    = ./newcerts
certificate      = ./local-ca.crt
private_key      = ./local-ca.key
serial           = ./serial
crlnumber        = ./crlnumber
crl              = ./local-ca.crl
default_md       = sha256
default_days     = 825
default_crl_days = 3650
policy           = policy_loose
x509_extensions  = server_cert
copy_extensions  = copy

[ policy_loose ]
commonName       = supplied

[ req ]
distinguished_name = dn

[ dn ]

[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

# If you wish to include certificate revocation list (CRL) server info in
# generated server certificates, uncomment this line and ensure the URL
# points to a web server that hosts your CRL file:
#
# crlDistributionPoints = URI:http://sipvm/crl/local-ca.crl

# Optional OCSP if you actually run one:
#
# authorityInfoAccess = OCSP;URI:http://sipvm/ocsp

[ alt_names ]
DNS.1 = sipvm
DNS.2 = localhost
IP.1  = 192.168.200.2
IP.2  = 127.0.0.1

Before saving the file, decide if you want the server certificates that are generated later to support "certificate revocation", in chich case you should uncomment the line that starts with crlDistributionPoints and also esut the subsequent URL to be a correct URL to the web server that you will use to host and publish your CA's certificate revocation list.

Also, at the bottom of the file, change the value of DNS.1 to be the correct host name of the system, and change IP.1 to be the correct IP address of the system. If your system is referred to by other DNS names or IP addresses then you can add additional entries (e.g. DNS.3, DNS.4, IP.3, etc.)

Notice that default_days is set to 825, meaning that certificates generated by your CA will be valid for that many days from the day they are created. If you want to cycle your certificates more frequently than this then you may reduce the value, but do not increase the value beyond 825 as this is the maximum that is supported by most modern web browsers, inclugding Apple Safari, Google Chrome, Mozilla Firefox and Microsoft Edge. Most public CA's now issue certificates valid for 398 days.

Initialize CA Working Files

Before the CA can be used to create and digitally sign certificates, several local working files must be initialized:

mkdir -p newcerts
: > index.txt
echo 1000 > serial
echo 1000 > crlnumber

Make a CA Private Key

openssl ecparam -genkey -name prime256v1 -noout -out local-ca.key

The private key is the key that will be used to sign generated certificates, and should be kept secret. If the private key becomes exposed then any and all certificates that have been signed by the CA should be treated as compromized and shoudl be replaced. Further, if you have configured your CA to support certificate revocation, all issued certificates should be revoked as soon as possible.

Create a CA Root Certificate

The following command will create the main CA certificate, which will be valid for 10 years; private CAs are not bound by the public 398/825-day rules.

openssl req -x509 -new -nodes -sha256 -days 3650 \
  -key local-ca.key -out local-ca.crt \
  -subj "/CN=Local CA (System)"

Create a Certificate Revocation List (if necessary)

If earlier you configured your CA to support certificate revocation then you need to create an initial (empty) certificate revocation list.

openssl ca -config local-ca.cnf -gencrl -out local-ca.crl
openssl crl -in local-ca.crl -noout -text

Publish the CRL at the CDP URL (if necessary)

If you have already a web server that will host your CA's CRL then you can copy the initial (empty) CRL to the appropriate web server directory now.

cp local-ca.crl /var/www/crl

If not, you can follow the instructions in Hosting a Certificate Revocation List.

Ready to Certify

Your certification authority is now ready to be used to generate and sign server certificates.

Any self-signed certificates that are generated by your CA will not by default be trusted by other systems. To establish that trust on other systems those systems need to be modified in such a way that they trust your CA, and by inference, will trust any certificates issued by that CA as long as they have not expired, and have not been revoked (if supported).

Trust the CA on Linux

To establish CA and certificate trust on Linux systems, copy the CA certificate local-ca.crt to the system and then:

For RHEL / Rocky / Fedora / Alma / CentOS / Oracle Linux:

sudo cp local-ca.crt /etc/pki/ca-trust/source/anchors/local-ca.crt
sudo update-ca-trust

For Debian / Ubuntu / Linux Mint:

sudo cp local-ca.crt /usr/local/share/ca-certificates/local-ca.crt
sudo update-ca-certificates

For openSUSE:

sudo cp local-ca.crt /etc/pki/trust/anchors/local-ca.crt
sudo update-ca-certificates

For Arch Linux / Manjaro

sudo cp local-ca.crt /etc/ca-certificates/trust-source/anchors/local-ca.crt
sudo trust extract-compat

For Alpine Linux (common in containers):

sudo cp local-ca.crt /usr/local/share/ca-certificates/local-ca.crt
sudo update-ca-certificates

If update-ca-certificates is missing:

sudo apk add ca-certificates

Trust the CA on Windows

To establish CA and certificate trust on Windows systems, copy the CA certificate local-ca.crt to the system and then install the certificate in the Trusted Root Certification Authorities section of the System Certificate Store. To do this:

  1. Open File Explorer, locate the certificate file, right-click on the certificate file and select Install Certificate.
  2. Select Local Machine and click Next.
  3. You will see a User Account Control dialog. Authorize the elevated operation.
  4. Select Place all certificates in the following store, click the Browse button, pick Trusted Root Certification Authorities and click OK.
  5. Click the Next button then the Finish button; you should see a message The import was successful.

Your CA (and by inference any certificates issued by that CA) are now trusted by the Windows system and hosted applications that delegate that trust to Windows (most applications). Note however that any applications (e.g. web browsers) that are currently running may not show that trust until restarted.