Become A Certificate Authority with Easy-RSA 3
Easy-RSA 3 makes it… easy… to set up a custom Certificate Authority (CA). I used this procedure to set up a CA and certificates for my OpenVPN system. I used zsh
on Ubuntu 19.10. I chose to generate my CA and all certificates on my development laptop instead of my router where my OpenVPN server will live for a couple reasons. Firstly, my laptop has magnitudes more power than my router and will make generating the Diffie-Hellman key much faster. Also, I want to keep my private keys off the router just in case the router is compromised.
To make this process easier to follow, let’s set up some assumptions. Let’s assume we want a single OpenVPN server and two clients. The server will be named eric
. We’ll have two clients named stephanie
and bill
.
Creating the CA and Certificates
First up, make sure Easy-RSA is installed.
sudo apt update
sudo apt install easy-rsa
Now, let’s set up a new CA directory and build the CA certificate and key.
make-cadir my-new-ca
cd my-new-ca
./easyrsa clean-all
./easyrsa build-ca nopass
I decided to use the parameter nopass
so I don’t have to manage passwords. For my system, having the certificate is enough security for me.
To harden the system a bit more, I generated a Diffie-Hellman key and a control list key. The Diffie-Hellman key (aka Diffie-Hellman-Merkle) allows two computers to setup a shared secret so a public tunnel, like the internet, can be used for secret communication. The control list makes it easy to revoke certificates and have the vpn server reject users with those revoked certificates.
./easyrsa gen-dh
./easyrsa gen-crl
I’ll need a server certificate, signed by this CA, for the server eric
. Once again, I’m using the parameter nopass
because I don’t want to manage extra passwords. The last line uses openssl
to verify that eric’s certificate is correctly signed and compatible with the CA certificate.
./easyrsa gen-req eric nopass
./easyrsa sign-req server eric
openssl verify -CAfile pki/ca.crt pki/issued/eric.crt
Now the clients stephanie
and bill
need client certificates to exchange with eric
when they authenticate. As you could probably guess, I’ll use nopass
again. I’ll also use openssl
to verify the certificates again.
./easyrsa gen-req stephanie nopass
./easyrsa sign-req client stephanie
openssl verify -CAfile pki/ca.crt pki/issued/stephanie.crt
./easyrsa gen-req bill nopass
./easyrsa sign-req client bill
openssl verify -CAfile pki/ca.crt pki/issued/bill.crt
Now that we have all the certificates created, it’s time to send them to the systems that will use them. The server will need the following files:
- pki/ca.crt
- pki/issued/eric.crt
- pki/private/eric.key
- pki/dh.pem
- pki/crl.pem
Each client will need their files. Stephanie needs:
- pki/ca.crt
- pki/issued/stephanie.crt
- pki/private/stephanie.key
Bill needs:
- pki/ca.crt
- pki/issued/bill.crt
- pki/private/bill.crt
Revoking a Certificate
Bill’s certificate has been compromised and now we need to revoke his certificate to protect our system. Easy-RSA makes it… easy… (even I groaned for that one). In our my-new-ca
directory, execute the following commands.
./easyrsa revoke bill
./easyrsa gen-crl
Now all we have to do is copy the file pki/crl.pem
to our OpenVPN server and restart the system. Bill’s certificate will no longer be accepted.
Going Further
Now that the system is created, we’ll need to be able to manage it. As with all things, if it’s important it should be under source control. We can add the entire my-new-ca
directory we created with make-cadir
into git with a few exceptions.
First, there is a config file that has hard-coded paths specific to the machine that is executing Easy-RSA commands, pki/safessl-easyrsa.cnf
. Fortunately, this file is generated by Easy-RSA and we can safely ignore it. Easy-RSA will regenerate the file as necessary.
Second, there are two symbolic links that were created to the easyrsa
executable and the x509-types
directory. If we add those two to the .gitignore
file and create a simple script to create those symbolic links when we checkout the system for the first time, we’ll be in business.
Here’s the .gitignore
file
easyrsa
x509-types
pki/safessl-easyrsa.cnf
…and now the script. It first checks to see if the Easy-RSA directory is installed as expected. Then creates the symbolic links as necessary.
#!/bin/bash
[ ! -d "/usr/share/easy-rsa" ] && { echo "Install Easy-RSA and try again."; exit 1; }
[ ! -f "./easyrsa" ] && ln -s /usr/share/easy-rsa/easyrsa easyrsa;
[ ! -d "./x509-types" ] && ln -s /usr/share/easy-rsa/x509-types x509-types;
2020-01-12