I finally decideed to clean up my act and migrate from easyrsa2 to easyrsa3. I started out with easyrsa2 because that’s what comes with VyOS, which I’ve previously written about. It doesn’t seem to be maintained anymore though, and exhibits some dated behaviors which I wanted to be rid of in the most futureproof way possible.

I decided to migrate from 2 to 3 since I didn’t want to have a flag day and redo everything from scratch. My reasoning was that I had a perfectly good 2048 bit CA cert lying around. In my travels I discovered that there’s a case to be made for reissuing both the server and client certs (see below), but that’s something I can do incrementally without breaking my running vpn server rather than having to do all in one go.

Besides being currently developed and the crypto behavior part, another thing easyrsa3 has going for it is a much more sane layout for the pki (formerly known as keys) subdirectory where all the good stuff is stashed. That directory had been getting awfully messy over time in my easyrsa2 CA.

Starting out with my old easyrsa2 configuration in a directory called ./easy-rsa2 Here are the steps. Note that after git cloning easyrsa3, I now have a subdirectory called easy-rsa with a subdirectory, easyrsa3, which is where all the action takes place.

git clone https://github.com/OpenVPN/easy-rsa.git
cd easy-rsa/easyrsa3
./easyrsa init-pki

Don’t worry about the values you provide for the CA information. You’re just going to be overwriting your new certs with the old ones out of easyrsa2.

Now, back up to the top level (where you have both ./easy-rsa2 and ./easyrsa…

scp -p easy-rsa2/keys/ca.crt easy-rsa/easyrsa3/pki/
cp -p easy-rsa2/keys/ca.key easy-rsa/easyrsa3/pki/private

cp -p easy-rsa2/keys/serial easy-rsa/easyrsa3/pki/
cp -p easy-rsa2/keys/serial.old easy-rsa/easyrsa3/pki/

cp -p easy-rsa2/keys/[0-f][0-f].pem easy-rsa/easyrsa3/pki/certs_by_serial/

cp -p easy-rsa2/keys/index.* easy-rsa/easyrsa3/pki/

cp -p easy-rsa2/keys/*.key easy-rsa/easyrsa3/pki/private
cp -p easy-rsa2/keys/*.crt easy-rsa/easyrsa3/pki/issued

## copy, but rename all to .req
for i in `ls easy-rsa2/keys/*.csr`
  j=`basename $i csr`
  cp -p $i easy-rsa/easyrsa3/pki/reqs/"$j"req

Don’t sweat moving the CRL, the revocation state is in index.txt and friends. Just recreate it…

cd easy-rsa/easyrsa3
./easyrsa gen-crl

Some things have changed in easyrsa3. Here are my (certainly non-exhaustive) observations:

The most conspicuous change is that the commands are all in one big shell script, “easyrsa”. No more ./build-ca, ./build-key, ./sign-req, etc.

maddog:easyrsa3 rs$ ./easyrsa --help

Easy-RSA 3 usage and overview

USAGE: easyrsa [options] COMMAND [command-options]

A list of commands is shown below. To get detailed usage and help for a
command, run:
  ./easyrsa help COMMAND

For a listing of options that can be supplied before the command, use:
  ./easyrsa help options

Here is the list of commands available with a short syntax reminder. Use the
'help' command above to get full usage details.

  build-ca [ cmd-opts ]
  gen-req <filename_base> [ cmd-opts ]
  sign-req <type> <filename_base>
  build-client-full <filename_base> [ cmd-opts ]
  build-server-full <filename_base> [ cmd-opts ]
  revoke <filename_base>
  show-req <filename_base> [ cmd-opts ]
  show-cert <filename_base> [ cmd-opts ]
  import-req <request_file_path> <short_basename>
  export-p7 <filename_base> [ cmd-opts ]
  export-p12 <filename_base> [ cmd-opts ]
  set-rsa-pass <filename_base> [ cmd-opts ]
  set-ec-pass <filename_base> [ cmd-opts ]

DIRECTORY STATUS (commands would take effect on these locations)
  EASYRSA: /Users/rs/CA/coolkids-ca/easy-rsa/easyrsa3
  PKI:  /Users/rs/CA/coolkids-ca/easy-rsa/easyrsa3/pki

maddog:easyrsa3 rs$ 

Note that the serial numbers are no longer monotonically increasing integers starting with 0x01, but instead are 128 bit random numbers. Guess someone was worried about potentially leaking information about how small their organization is. Note though that easyrsa still checks for the presence of the “serial” file, it still contains the value of the most recently issued cert, and serial.old still contains a value that is 1 less.

Newly issued certs now default to a signature algorithm of sha256WithRSAEncryption rather than sha1WithRSAEncryption. You may wish to reissue your client and server certs, though this in and of itself is no reason to toss everything and start afresh with a new CA cert (even though since you migrated it from easyrsa2, the signature on your CA cert is sha1WithRSAEncryption). The reason? The signature on a certificate is used for confirming the trust relationship between that certificate and its parent. In the case of a CA cert, there is no parent. The trust for that certificate (from which one derives trust for its children) stems from the fact that it came to you physically or electronically from a trusted source - either in the form of a .crt or .pem file which you imported, a .ovpn file, or something similar. In short, the signature on the root certificate does not matter (but the number of bits do). Only the signatures on the child certificates matter.

Another interesting change is the fact that the DN defaults to CN only, with no org information (i.e., that “Subject: C=US, ST=VA, L=Leesburg, O=Seastrom Consulting OpenVPN, CN=Seastrom Consulting OpenVPN CA/emailAddress=sslcert@seastrom.com” line is going to instead be something like “Subject: CN=Cool Kids CA”). Since you’re recycling the old self-signed CA certificate, that will pertain to the CN for the certs that it signs (Subject:), but not to the issuer information (Issuer:).

Other behavior that changes - see easyrsa/easyrsa3/doc/EasyRSA-Upgrade-Notes.md