Step 2 : Create your own PKI

Properly creating the PKI is the fundamental anchor of your setup's security !

A number of files we'll create in this section will have to be named starting with the "configuration name" we chose in Step 0 : my-fg-ovpn in this demo.

Duplicate from the new-PKI

As first step we'll duplicate the whole contents of our new-PKI folder into our own PKI sub-folder named MY-FG-OVPN-PKI : select all files, then Copy, go to the target folder then Paste

We'll now more or less follow the instructions you can read in the README.txt file, except that :

  • we'll adapt to the "autonomous" PKI location

  • we'll add some safeguards to the most dangerous command scripts

Create the keys sub-folder

Let's create a sub-folder into our own PKI folder, to store this particular PKI's "database" of certificates and keys, that we'll call MY-FG-OVPN-PKI-KEYS :

Run init-config.bat, then rename it to avoid re-using it

You can double-click init-config.bat in MY-FG-OVPN-PKI to run this command, and that will initialize the new vars.bat command script file from a sample file.

The init-config.bat command should not be re-used later on, as it would ERASE the customizations we are about to do in the vars.bat file.

So we'll rename init-config.bat to DONE-DANGER-init-config.bat and FORGET about it.

Edit vars.bat

We now have to edit the vars.bat file for it to meet our requirements :

  • we comment out (or delete) the lines playing with the PATH to ensure the commands use the version of executable binary programs that we have in our PKI folder, and none other (lines 7 and 10 below; only line 7 needs editing since line 10 is already commented out with "rem ")

  • we set HOME to the full path of the root folder for our PKI; everything the Easy-RSA commands will do later on will happen from that location : this is the T:\fg-ovpn\MY-FG_OVPN\MY_FG_OVPN_PKI folder (line 12 below) for our sample

  • we set KEY_DIR to the name of the sub-folder where we want our certificates and keys to be stored : this is the MY-FG-OVPN-PKI-KEYS we created earlier

  • we give some default values for our future certificates in the list of set KEY_xxxx commands at the end of the file.

To avoid accidentally keeping a (wrong) default value for 2 important fields of our certificates, we'll put a prompt for action as their default value : KEY_CN and KEY_NAME

  • we can keep or delete all the commented lines (= lines starting with "rem ")

So we edit vars.bat in a text editor (even Right click + Edit with the very limited Windows Notepad is sufficient for good old .bat windows-only command files) as follows.

Supposing you start from the original content below (sample as of OpenVPN v2.4.7),

Original vars.bat BEFORE we edit it
@echo off
rem Edit this variable to point to
rem the openssl.cnf file included
rem with easy-rsa.

rem Automatically set PATH to openssl.exe
FOR /F "tokens=2*" %%a IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN"') DO set "PATH=%PATH%;%%b\bin"

rem Alternatively define the PATH to openssl.exe manually
rem set "PATH=%PATH%;C:\Program Files\OpenVPN\bin"

set HOME=%ProgramFiles%\OpenVPN\easy-rsa
set KEY_CONFIG=openssl-1.0.0.cnf

rem Edit this variable to point to
rem your soon-to-be-created key
rem directory.
rem
rem WARNING: clean-all will do
rem a rm -rf on this directory
rem so make sure you define
rem it correctly!
set KEY_DIR=keys

rem Increase this if you
rem are paranoid.  This will slow
rem down TLS negotiation performance
rem as well as the one-time DH parms
rem generation process.
set DH_KEY_SIZE=2048

rem Private key size
set KEY_SIZE=4096

rem These are the default values for fields
rem which will be placed in the certificate.
rem Change these to reflect your site.
rem Don't leave any of these parms blank.

set KEY_COUNTRY=US
set KEY_PROVINCE=CA
set KEY_CITY=SanFrancisco
set KEY_ORG=OpenVPN
set KEY_EMAIL=mail@host.domain
set KEY_CN=changeme
set KEY_NAME=changeme
set KEY_OU=changeme
set PKCS11_MODULE_PATH=changeme
set PKCS11_PIN=1234

...then you should end up with this kind of minimal final result :

ALL the other lines you may want to keep for reference in the vars.bat file should be commented out with "rem " as seen above.

Here, i chose to delete them.

Valid minimalist content for vars.bat
@echo off

set HOME=T:\fg-ovpn\MY-FG-OVPN\MY-FG-OVPN-PKI
set KEY_CONFIG=openssl-1.0.0.cnf
set KEY_DIR=MY-FG-OVPN-PKI-KEYS
set DH_KEY_SIZE=2048
set KEY_SIZE=4096

set KEY_COUNTRY=FR
set KEY_PROVINCE=FR
set KEY_CITY=MyCity
set KEY_ORG=MyOrg
set KEY_EMAIL=no-mail@no-domain.com
set KEY_CN=CHANGE-ME-MANDATORILY
set KEY_NAME=CHANGE-ME-MANDATORILY
set KEY_OU=MyOrgUnit
set PKCS11_MODULE_PATH=unused
set PKCS11_PIN=1234

Edit and rename ⚠️ clean-all.bat ⚠️ to avoid killing our PKI

The clean-all.bat command script ERASES the whole PKI "database" including all certificates and keys. It must be used ONLY ONCE to initialize the database and NEVER AGAIN !

So we'll first edit it to add these 2 lines between original lines 1 and 2 :

choice /C YN /T 10 /D n /M "This will ERASE THE PKI AT %HOME% ...Still want to do this ??"
IF ERRORLEVEL 2 GOTO End

And we'll add this last line at the end of the file :

:End

The resulting clean-all.bat file should be :

Edited clean-all.bat
@echo off
choice /C YN /T 10 /D n /M "This will ERASE THE PKI AT %HOME% ...Still want to do this ??"
IF ERRORLEVEL 2 GOTO End
rem move to the HOME directory specified in VARS script
cd %HOME%
rem set a temporary KEY_DIR variable
set d=%KEY_DIR%
rem delete the KEY_DIR and any subdirs quietly
rmdir /s /q %d%
rem make a new KEY_DIR
mkdir %d%
rem copy in a fesh index file so we begin with an empty database
copy index.txt.start %d%\index.txt
rem copy in a fresh serial file so we begin generating keys at index 01
copy serial.start %d%\serial.
:End

This way, when we run this "killer" command script file, we'll have a warning and Y/N choice, with the "No I don't want to kill my own innocent PKI" answer selected by default after 10 seconds...

...and just to be safe, we'll rename clean-all.bat to NEVER-AGAIN-DANGER-clean-all.bat !

OF COURSE NOT !!!

...Well...maybe once but i don't really remember, you see, so : let's move on !

Going to command line mode

From now on, we'll use a single command line prompt window to type all the commands.

We'll ABSOLUTELY NOT double-click command files !!!

=> Last reference to "Check that you know/learn" in Step 0 !

So we open a command line prompt window and we position ourselves in the right folder for our PKI. In my demo this is :T:\fg-ovpn\MY-FG_OVPN\MY_FG_OVPN_PKI

Reposition to our own PKI
T:
CD \fg-ovpn\MY-FG_OVPN\MY-FG-OVPN-PKI

A quick check to verify this is the right place :

Verify the contents of the folder
dir

Then once we know we have arrived at the right place, the VERY FIRST COMMAND we'll type is :

VERY FIRST COMMAND
.\vars.bat

This will setup the "environment variables" that you specified earlier, and these will remain available for other commands until you close that specific command line prompt window.

If you need to open a new command prompt window, remember to re-position to the right folder and use ".\vars.bat" command FIRST !

Remember that, when you come back days or months later, to add a new client certificate or revoke an existing one.

Try to build up your keyboard "muscle memory" with the following tip :

The vars.bat command script can be run multiple times without any issue.

Actually, we'll re-run it before every other command in this example.

A clean starting point - ONCE AND FOR ALL

Let's use the "killer" command script, give the Y answer THIS ONE TIME, and then let's forget about it...

.\vars.bat
.\NEVER-AGAIN-DANGER-clean-all.bat

This DELETES any pre-existing data in your PKI keys folder and initializes the PKI "database" :

Build the CA Certificate+Key

Easy !

.\vars.bat
.\build-ca.bat

Answer the prompts, just hitting "Enter/Return" to keep default values EXCEPT FOR Common Name and Name. Use the SAME simple name without spaces for the 2 fields.

Let's call our CA : my-fg-ovpn-ca, keeping our good prefixing habit.

This creates the PKI Certificate Authority's own self-signed certificate (ca.crt) and private key (ca.key) in the MY-FG-OVPN-PKI-KEYS sub-folder.

Since we are here within our own PKI, we only have one CA so these simple filenames are fine. But :

Our server will need to have the CA certificate named as "configuration name"-ca.crt

("configuration name" = my-fg-ovpn in this demo)

=> We'll copy+paste+rename these 2 files to have proper names :

  • ca.crt copied to my-fg-ovpn-ca.crt

  • ca.key copied to my-fg-ovpn-ca.key

Do NOT rename the original files directly, but keep properly named copies !

Build the DH file

Easy, but may take a long time depending on your computer !

.\vars.bat
.\build-dh.bat

...time passes...finally :

This has generated the Diffie-Hellman-Merkle key exchange parameter file that will be used to initiate encryption sessions.

Our server will need to have our DH file named as "configuration name"-dh2048.pem

("configuration name" = my-fg-ovpn in this demo)

=> We'll also keep a copy of dh2048.pem named my-fg-ovpn-dh2048.pem

Build OpenVPN Server Certificate+Key

Easy again !

Our server will need to have it's certificate file named "configuration name"-srv.crt (and similarly for the key and certificate request)

("configuration name" = my-fg-ovpn in this demo)

Answer the prompts, just hitting "Enter/Return" to keep default values EXCEPT FOR Common Name and Name. Use the SAME simple name without spaces for the 2 fields.

So let's call our OpenVPN server : my-fg-ovpn-srv, to satisfy the above requirement.

.\vars.bat
.\build-key-server.bat my-fg-ovpn-srv

Since our server should boot up in unattended mode (without anyone to enter a password) :

Do NOT enter a challenge password

(don't mind the error about "index.txt.attr", the file will be created by the process)

Answer y for Yes to the last 2 questions :

  • sign the certificate ? ==> YES !

  • commit ? ==> YES !

This creates 3 files in your keys folder, with the name you typed on the command line :

  • my-fg-ovpn-srv.crt : the server public certificate

  • my-fg-ovpn-srv.key : the server private key

  • my-fg-ovpn-srv.csr : the "certificate signing request" used during the process

These files should already be properly named, so we'll keep them as they are:

"configuration-name"-srv.crt, .csr and .key => my-fg-ovpn-srv.crt, .csr and .key

Build 2 clients (GMs) Certificate+Key

Being used to D&D, i already called my clients subfolders my-fg-ovpn-dm01/02, so let's stick to that.

.\vars.bat
.\build-key.bat my-fg-ovpn-dm01

Do the same thing with my-fg-ovpn-dm02...

You should now have :

Revoke (invalidate) DM02's certificate

Our next step will be to initialize a Certificate Revocation List (CRL) for our OpenVPN server to systematically check before authorizing a connection.

The CRL will be your way of ensuring that older certificates, that you may have distributed in the past and revoked/invalidated at some point in time, are really blocked.

But to create that CRL, we need one client certificate to be revoked, so "DM02" is our victim ! 🔫 🗡️

.\vars.bat
.\revoke-full.bat my-fg-ovpn-dm02

You can see on the above screenshot :

  • why we kept the original ca.crt and ca.key files, visibly used there... 👀

  • the Easy-RSA utility checks that a session negociation initiated on behalf of my-fg-ovpn-dm02 actually fails because the certificate is revoked, which is what we want ! 👍

This process does not delete files : it marks them as revoked (= invalid) in the PKI "database", and includes them in the immediately (re-)generated CRL (Certificate Revocation List).

So : R.I.P. my-fg-ovpn-dm02... ⚰️ 💀 ☠️

After all, DM01 was here first, and he's not a sharer...

Your initial Certification Revocation List

As soon as you have revoked the (probably innocent) my-fg-ovpn-dm02 during the previous step, your PKI (re-)generated the CRL=Certificate Revocation List with the basic name of crl.pem :

Our server will need to have the CRL named as "configuration name"-crl.pem

("configuration name" = my-fg-ovpn in this demo)

=> We'll copy+paste/rename the CRL from crl.pem to my-fg-ovpn-crl.pem :

PKI ready !

Congratulations !

Your own PKI is now complete, with clear enough filenames so that you know who is what, in case they happen to be used on OpenVPN servers/clients managing/using multiple independent VPNs.

We'll see in the following sections how these files are put to use, first on the OpenVPN client, then on the server.

One more key for OpenVPN tls-auth

While we are in our PKI root folder (T:\fg-ovpn\MY-FG_OVPN\MY_FG_OVPN_PKI) at the command prompt, let's have OpenVPN generate a static secret key.

That key will be used by OpenVPN "TLS Authentication" feature to protect initial key negociations when OpenVPN clients connect to the server. You can read about tls-auth here.

Our server will need to have the TLS-Auth file named as "configuration name"-ta.key

("configuration name" = my-fg-ovpn in this demo)

We'll create this key with the right filename, in our keys sub-folder :

openvpn.exe --genkey --secret MY-FG-OVPN-PKI-KEYS\my-fg-ovpn-ta.key

Nothing fancy, it just creates the last key file we were missing in our security arsenal. Here is the complete list of files in our keys sub-folder :

Last updated