Introduction to creating a CA on Debian 11

If you need to create and use self-signed certificates, you will need to create your own Certificate Authority. This article describes how this can be done on Debian 11.

Martin Hodges
13 min readDec 6, 2023
Using a Certificate Authority

If you are not sure what a Certificate Authority or CA is, you can read my article on Public Key Infrastructure here.

In this article I will be explaining how to set up your own CA on Debian 11 to use self-signed certificates. Once this is done, we will be looking at how you then use your CA to sign a Certificate Signing Request (CRL). Finally, we revoke our certificate using the CA.

Whilst this focuses on Debian, the principles still apply to other Operating Systems.

Note on Debian 12

At the time of writing there is a problem with the openssl and easy-rsa versions on Debian 12.

For now, if possible, I recommend sticking with Debian 11 a little longer. This article uses Debian 11, easy-rsa 3.0.8 and openssl 1.1.1.

If you wish to lok at a solution for Debian 12, see my latest article.

Use Case

Before we create a Certificate Authority (CA), it is useful to describe a use case where we would use a CA that removes the abstraction.

Let’s take the scenario where we have two servers, as shown in the diagram above. Now I know a lot of people prefer to talk about a server and a browser but it is rare that people use self-signed certificates with a browser. It can be done but it is more typical that you want to use them in the communications between two servers.

We will call them Server 1 and Server 2.

Not very imaginative but it will do for this article.

Let’s say we want Server 2 to securely talk to Server 1. Any communications should be secured with digital certificates over Transport Layer Security (TLS) connections.

A public/private key pair will be created on Server 1 and the public key transferred to Server 2 to secure the TLS connection. Server 2 also needs to be able to validate the public key it receives is associated with Server 1.

Why create your own CA?

Ok, now we have a scenario, we need to ask why we do not simply use a certificate from a trusted CA and instead create our own CA, which is not trusted by anyone but ourselves!

There are several reasons:

  1. May be your network is not connected to the Internet (such as with a private subnet)
  2. The cost of a 3rd party certificate may be prohibitive
  3. You may not want to give out details of your network to a 3rd party
  4. It is not possible to verify your identity to the CA

Whatever your reason, for this article we will assume that you need to create your own CA.

Where do I create my CA?

Your CA will need to be very secure. Anyone with access to your CA may be able to create certificates that pretend to be you and therefore be able to intercept, modify or fake your communications.

Most CAs will create their CA on an air-gapped computer that is powered down and/or not connected to the Internet. You could even create it on something like a Raspberry Pi and lock it away in a safe.

The idea is you only power it up and connect to it when you need to create a signed certificate and then power it down.

Of course, this can be very inconvenient. You could decide to create an intermediate CA to help alleviate this problem but that is beyond the scope of this article.

For now, as we are only learning about how to create a CA, you can use any Debian 11 machine. This can be your own computer or a cloud computer. You just need command line access to it.

Steps to create the CA

There are 3 steps to creating a CA:

  1. Set up your CA host
  2. Set up your CA folder structure
  3. Set up your PKI keys

Step 1. Set up your CA host with user to act as your CA admin

I am assuming you have found a suitable Debian 11 computer to use to host your CA and that you have root access. Ensure it‘s Operating System is up to date:

sudo apt update
sudo apt upgrade -y

Now create a non-root user (in this case we will create ca-admin):

sudo adduser ca-admin

Give it a secure password. If you are accessing your host using SSH you should consider using digital certificates rather than passwords to secure the account.

Add it to the sudo group:

sudo usermod -aG sudo ca-admin

I use the easy-rsa utility as it takes some of the complexity out of the openssl command line.

sudo apt update
sudo apt install easy-rsa -y

Now log in as the ca-admin user.

Step 2. Set up your CA folder structure

You can choose where to set up the folders that will hold the details of your CA. In this article it is assumed to be in your ca-admin user’s home folder (~ca-admin/) and that you are logged in as ca-admin.

Create a folder to hold your CA details:

mkdir ~/my-ca

You need to make sure that only you can access this folder as it will contain very important data that must be kept secure to keep your CA secure.

chmod 700 ~/my-ca

Rather than use easy-rsa directly, we will use it via symbolic links so that if the utility is updated, it does not affect your configuration.

ln -s /usr/share/easy-rsa/* ~/my-ca/

Now you are ready to set up your PKI keys.

Step 3. Set up your PKI keys

Before you can start signing certificates, you need to initialise your system. You can do this within your my-ca folder:

cd ~/my-ca
./easyrsa init-pki

This will then tell you that your PKI is setup in a pki subfolder and that you may now create a CA or requests.

ls ~/my-ca/pki

You will see there are a number of configuration files and two folders, private and reqs.

Now you have set up your pki system.

Step 4. Create your CA

To create your CA, you need to set up the config file called vars.

cd ~/my-ca
nano pki/vars

Now find the following lines and uncomment them. Then enter the information about your CA. Here is my example:

set_var EASYRSA_REQ_COUNTRY    "AU"
set_var EASYRSA_REQ_PROVINCE "NSW"
set_var EASYRSA_REQ_CITY "Sydney"
set_var EASYRSA_REQ_ORG "RequillionSolutions"
set_var EASYRSA_REQ_EMAIL "youremail"
set_var EASYRSA_REQ_OU "Community"
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"

Once you have set up this file, you can now set up your CA with:

./easyrsa build-ca

This will ask you for a passphrase, which you should make strong. Re-enter when requested. You will need this password to work with your CA.

It will then ask you for your Common Name. You can choose your own or simply press enter for the default. This name will be used in certificates so that you can see which CA was used to sign it.

Now your CA is up and ready. You will find the various files you need in the in the ~/my-ca/pki folder:

-rw------- 1 ca-admin ca-admin 1204 Dec  5 22:33 ca.crt
drwx------ 2 ca-admin ca-admin 4096 Dec 5 22:31 certs_by_serial
-rw------- 1 ca-admin ca-admin 0 Dec 5 22:31 index.txt
-rw------- 1 ca-admin ca-admin 0 Dec 5 22:31 index.txt.attr
drwx------ 2 ca-admin ca-admin 4096 Dec 5 22:31 issued
-rw------- 1 ca-admin ca-admin 4616 Dec 5 22:31 openssl-easyrsa.cnf
drwx------ 2 ca-admin ca-admin 4096 Dec 5 22:33 private
drwx------ 5 ca-admin ca-admin 4096 Dec 5 22:31 renewed
drwx------ 2 ca-admin ca-admin 4096 Dec 5 22:31 reqs
drwx------ 5 ca-admin ca-admin 4096 Dec 5 22:31 revoked
-rw------- 1 ca-admin ca-admin 4630 Dec 5 22:31 safessl-easyrsa.cnf
-rw------- 1 ca-admin ca-admin 3 Dec 5 22:31 serial

You will see a number of folders that hold information about your CA and the certificates it has signed and/or revoked.

There are two important files that you must handle correctly.

~/my-ca/pki/private/ca.key is your CA private key that must not leave the system. Treat it as the most valuable file on the server.

~/my-ca/pki/ca.crt is your public CA certificate which must be installed on every browser or operating system that you want to trust your CA.

We will look at other files and folders later.

Using your CA

Now you have your CA set up, you will want to use it to secure your communications.

There are three main things you will want to do with your CA:

  1. Distribute your CA public key in the form of a signed certificate
  2. Sign a server certificate using your CA so users of the server can trust it
  3. Revoke a certificate

These uses are described in detail below.

Distributing your CA public key

Your CA is useless unless you can tell the ‘client’ (eg: Server 2) of your server (eg: Server 1) that it should trust Server 1 as it is presenting a certificate signed by your CA.

You can tell Server 2 to trust Server 1 by adding the ~/my-ca/pki/ca.crt file from your CA into the trust store of Server 2.

It is likely that you will want to copy this file to multiple servers. Rather than opening up your CA to the Internet each time, you can safely transfer it to a computer and then distribute it from that computer. This certificate is not a secret but to limit attack surfaces, you may only want servers you know to have it.

The file is in text format so you can cut and paste it to your target machine. If you copy it like this, make sure you include the BEGIN and END tags.

-----BEGIN CERTIFICATE-----
Ax7SGH...
...
...
-----END CERTIFICATE-----

Installing it on the target machine and/or application is dependent on how you want to use it. For example, you may want to add it to the Operating System’s (OS) trust store, which is OS specific. Many applications do not use the OS trust store and you may need to install it into the application itself (eg: postgres, nginx, java etc).

As there are so many different uses, I am not going to go through them here. I may add articles for some of the common ones later, so look out for those.

Signing a Certificate Signing Request (CSR)

Once you have installed your CA certificate on Server 2 you now need to sign a certificate on Server 1 so that Server 2 will trust it.

To create the certificate, you need to send a Certificate Signing Request (CSR) to the CA. It will check the details, sign it and return it. By signing the certificate, Server 2 can use it to check that it is the same certificate as created by the CA and that it has not been tampered with. It can check this as it has the CA certificate from the previous step.

Ok, so we understand that the CA signs the certificate it creates, but how does it know that the CSR is from Server 1 and has not been changed?

Well, the CSR is signed by the private key of Server 1 and this can be checked as the CSR includes the public key. You may now be asking how the CA trusts that the CSR is from Server 1. In the automated world of CAs, they do things like making a request to the server or fetching details from its DNS entry and validating the result. In our case though, we do not have that luxury.

Is this a problem? Not really. As we are the CA and we control it and we are manually copying the CSR to the CA, we can be assured that the CSR of Server 1 is from Server 1. If you need to automate this, then you need to consider how you will automate this check.

Now, I have been talking about a CSR but what is it and how is it created.

We already know it contains the public key of Server 1 and that it is signed. The key and the signature are two of the three things it contains. The other is metadata about Server 1.

This metadata might include information such as:

  • Location (including country, state, city)
  • Organisation details
  • Server common name (ie: the host name of the server) — mandatory
  • Your email address so people can contact you if there is a problem with the certificate

Now we know what is in the CSR, how do we create one?

Because it is to be signed, you need private and public keys for Server 1. Here I assume that Server 1 is also a Debian 11 machine. You can do this in the same way as you did to set up the CA:

sudo apt update
sudo apt upgrade -y
sudo apt install easy-rsa -y
sudo adduser server-admin
sudo usermod -aG sudo server-admin

(login as server-admin)

mkdir ~/my-server
chmod 700 ~/my-server
ln -s /usr/share/easy-rsa/* ~/my-server/
cd ~/my-server
./easyrsa init-pki

Note I have used a different name for the user and for the easy-rsa folder.

Now create server (rather than CA) keys with:

./easyrsa gen-req server nopass

It will prompt you for information about your server, specifically the common name. The common name will be used by the CA to identify and sign your certificate. Server 2 may use it to make sure someone else is not using a copy of your certificate. Typically, you can use the hostname or Fully Qualified Domain Name (FQDN) of the server. This also helps you know which key belongs to which server. In this case, we entered server1.

Note: if you wish your CSR to include the other fields, such as country name, organisation etc, you need to set up a vars configuration file and then modify it:

cp vars.example pki/vars
nano vars

You will see that the majority of this file is commented out with #.

  1. Uncomment the additional fields, such as
    set_var EASYRSA_REQ_COUNTRY “US"
    and set them to values you want to use as defaults
  2. Uncomment the field
    set_var EASYRSA_DN “cn_only”
    and change the value to org

Now, when you create a CSR using the earlier command, it will ask you for the additional fields and will also default them to the values you set.

At this point you will now have a private key (pki/private/server.key) and a CSR (pki/reqs/server.req). The server filename is used regardless of your common name.

Any application that is going to use the signed certificate from the CA needs to be given access to your private key. This is a secret and should be treated as such so be careful where you copy it. You should never copy it off the original machine (other machines should have their own keys). Each application that needs it may be able to be configured to point to the ~/my-server/pki/private folder but, if not, you will need to copy it. Some applications require the file permissions to be set to specific values for this file.

You now need to copy the CSR file (which is also a text file) to a folder on your CA server. Let’s assume you copy this into a file called server1.req in the ~ca-admin/ home folder.

On your CA machine, log in as ca-admin and go into your my-ca folder. Then process the request with:

./easyrsa import-req ~/my-ca/server1.csr server1_sn

server1_sn is the short name that easy-rsa will use to reference this CSR. I have appended the _sn so you can tell what matches what in the following commands.

Now sign the request as the CA. You do this with:

./easyrsa sign-req server server1_sn

You will then be asked to confirm the details of the CSR by typing yes and enter. You will be asked for your passphrase you entered when setting up the CA.

Now you will find your signed certificate in pki/issued/server1_sn.crt. You can view the contents of this certificate with the following:

./easyrsa show-cert server1_sn

In the output you will see a number of important fields:

  • Issuer / commonName identifies which server requested the certificate
  • Subject / commonName identifies which server this certifies
  • Validity / Not After identifies when the certificate will expire
  • X509v3 Authority Key Identifier identifies the CA that signed the certificate
  • X509v3 Key Usage identifies what the certificate should be used for
  • X509v3 Subject Alternative Name / DNS identifies the domain name that Server 2 should use to validate the certificate corresponds to the server it is communicating with via its FQDN

The pki/issued/server1_sn.crt file is the one you now need to copy back to Server 1 into the application specific location so your application can find it and use it to communicate with Server 2. Again, this is a text file and so it can be cut and pasted.

Server 1 and Server 2 should now be able to securely connect and communicate with each other.

For an example of this, I will have an upcoming article on how to create a Virtual Private Network (VPN) into your Virtual Private Cloud (VPC) using self-signed certificates.

Revoking certificates

Before we finish, there is one more important topic to discuss — the revocation of certificates.

Certificates will typically have a validity period after which it will no longer work but you may find that you need to revoke the certificate earlier than that. This is particularly true if you believe the server the certificate belongs to has been compromised.

To revoke a certificate, go to the CA and go to the my-ca folder.

./easyrsa revoke server1_sn

Confirm revocation by typing yes. Enter the passphrase for the CA.

You will now find that the certificate has been removed from your pki/issued folder.

Just because the CA knows your certificate has been revoked, this does not mean that Server 2 knows. To tell Server 2 (and any other server), you must update the CA’s Certificate Revocation List (CRL) and distribute it to other servers.

This is how you update the CRL:

./easyrsa gen-crl

Again, you will need the CA passphrase. This will generate a signed CRL, which means that servers will know this came from the CA and has not been tampered with. You will find the signed CRL under pki/crl.pem.

If you wish to view the contents of your crl.pem file, you can use:

openssl crl -inform PEM -text -noout -in pki/crl.pem

You now need to copy the crl.pem file to all servers that may be processing your certificate. What you do with the file on the target server will depend on the OS and the application you are using.

Summary

We have now created our own CA on a Debian 11 server to allow us to sign our own certificates. We saw how to use the easy-rsa utility to create all the relevant PKI keys and certificates.

After creating the CA, we then used it to sign a Certificate Signing Request (CSR). Following this, we then revoked the certificate.

Whilst we have not used our certificate, you have seen how the process works. In my next article I will use a CA to create a self-signed certificate to secure an OpenVPN connection to a Virtual Private Cloud (VPC).

--

--