Creating Certificates and Keys for pfSense 1.2 Series OpenVPN Servers and Clients

Notable changes to this document

21 February 2012 - Changed client certificate keylength from 1024 to 4096, and I'm questioning whether the certificate authority and server certificate should do the same.

2 February 2011 - Added 'Further Certificate and Key Operations' section with 'Renewing Certificates'.

1.0 Introduction

This is a guide to using TinyCA on Unix operating systems (such as Linux) to create a certificate authority (CA), then certificates and keys for using a pfSense-based OpenVPN. pfSense requires you provide it with certificates and keys, rather than having its own built-in interface to create them. We setup the CA on a different computer to pfSense and from there make the certificates and keys required by both pfSense and client computers.

The pfSense web site has two guides that cover similar ground to this guide but I found them to be insufficient for my needs: 'VPN Capability OpenVPN' (is Gentoo-specific and uses the command-line rather than a GUI) and 'Pfsense and OpenVPN for new users' (uses Windows to create the CA and also uses the command-line).

2.0 TinyCA

tinyca (tinyca.sm-zone.net) is a very simple Certification Authority. It features a graphical interface to create Certificate Requests, sign them with the key of the Certificate Authority and export the signed certificate and the corresponding keys in various formats.

In Debian or Ubuntu install the package 'tinyca'.

This is the file and directory structure used by TinyCA to store the certificates and keys, in ~/.TinyCA/, for each CA:

|-- <organisation>-CA
|   |-- cacert.key
|   |-- cacert.pem
|   |-- certs
|   |   |-- dGVzdDI6IDogOnRlc3Q6IDp1azpVSw==.pem
|   |   `-- dGVzdDM6IDogOnRlc3Q6IDp1azpVSw==.pem
|   |-- crl
|   |   `-- crl.pem
|   |-- index.txt
|   |-- index.txt.attr
|   |-- keys
|   |   |-- dGVzdDI6IDogOnRlc3Q6IDp1azpVSw==.pem
|   |   `-- dGVzdDM6IDogOnRlc3Q6IDp1azpVSw==.pem
|   |-- newcerts
|   |   |-- 01.pem
|   |   `-- 02.pem
|   |-- openssl.cnf
|   |-- req
|   |   |-- dGVzdDI6IDogOnRlc3Q6IDp1azpVSw==.pem
|   |   `-- dGVzdDM6IDogOnRlc3Q6IDp1azpVSw==.pem
|   |-- serial

You need to preserve the integrity of these files because therein lie the certificate authority, server and client certificates and keys.

3.0 The Certificate Authority & CA certificate For This VPN Server

Create a dedicated CA for each organisation. Client access is based on the CA so don't use the same CA for different organisations else clients from each organisation can connect to the other organisations with that same CA.

3.1 Build the Certificate Authority

The CA / CA certificate is used for certificate signing.

Run TinyCA. In Debian use: Applications → Other → TinyCA; In Ubuntu there's no menu item so from the command-line use: $ tinyca2

If this is your first time running the program you'll automatically be prompted to setup a new Certificate Authority; if it's not you'll be prompted to open an existing CA, Cancel that dialog and choose 'New CA'.

(Note that TinyCA only deals with one CA at a time. If you create a new one any previous one and its associated certificates and keys will disappear from view. You can return to others using 'Open CA'.)

Name (for local storage): <organisation>-CA (no spaces allowed as this is used for a filename)
Common Name (for the CA): use system hostname of the machine you're creating this on? [I'm not sure about this naming scheme]
Country Name (2 letter code): UK
Password (needed for signing): you use this to sign server and client keys when you create them
Password (confirmation):
Organization Name (eg. company): <organisation>
eMail Address: <your organisation email address>
Keylength: 1024 [or 4096 now?]
valid for (days): 3650 (ten years)

Use the defaults for everything else unless you know what you're doing.

Choose → OKCA ConfigurationOK

You can henceforth use this for creating certificates/keys for all this organisation's VPN servers, but not another organisation's.

3.2 Export the CA certificate to enter into the VPN server and into Network Manager for each client

Choose CA tab → Export CAchoose where to save itSave.

This saves a .PEM format certificate as <'Name (for local storage)' from above>-cacert.pem.

pfSense says it wants it in X.509 format. TinyCA offers "PEM", "DER" and "TXT" which are all different formats of X.509 certificate. It is the .PEM format that pfSense actually wants.

4.0 The Server Certificate and Key for the VPN Server

4.1 Create the server certificate and private key for the specific VPN server

Choose Certificates tab → NewCreate Key and Certificate (Server).

Common Name (eg. your Name, your eMail Address or the Server's Name): firewall (if this differs from the machine hostname it's OK)
eMail Address: <your organisation email address> - so you don't export files later on with the same names for server certs and keys as for client certs and keys, don't use an email address here that you'll also use for a client certificate and key
Password (protect your private Key): ...
Password (confirmation): ...
Country Name (2 letter code): UK (should be the default)
Organization Name (eg. company): <organisation> (should be the default)
Keylength: 1024 [or 4096 now?]

Use the defaults for everything else unless you know what you're doing.

Choose OKSign Request

CA Password: ...
Valid for (Days): 730 (or 1825 days, 5 years maybe) (should be the same or less than the CA)
Add eMail Address to Subject DN: yes? the default

4.2 Export the server certificate for the VPN Server

Choose Certificates tab → choose particular server certificateExport.

Export Format: PEM (Certificate) (the default)
Include Key (PEM): No (the default)
Include fingerprint (PEM): No (the default)

Saves as <'eMail Address' from above>-cert.pem.

4.3 Export the server key / server private key for the VPN Server

Choose Keys tab → choose particular server keyExport.

Export Format: PEM (Key) (the default)
Without Passphrase (PEM/PKCS#12): Yes (if you choose 'yes' it doesn't require a passphrase to open it, if you choose 'no' it does require a passphrase to open it - we choose to have it without a password to open it because it lives on the server, used by software rather than interactively, without the ability to prompt for the password)
Include Certificate (PEM): No (we get it on its own above) (the default)

[Note: I'm not sure how but it is possible to get this error message from misconfiguring something here: "openvpn[281]: Cannot load private key file /var/etc/openvpn_server0.key: error:0906A068:PEM routines:PEM_do_header:bad password read: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib]"

You'll be asked for this server private key password / passphrase in order to decrypt the key.

It saves as something like <'eMail Address' from above>-key.pem.

4.4 Diffie-Hellman parameters

"Key establishment parameters - The specification of a cyclic group p and a generator g for that group. These parameters may be public. Menezes, et al. (1997) note that for additional security each party may supply its own parameters." - http://en.wikipedia.org/wiki/Station-to-Station_protocol

See also http://www.rsa.com/rsalabs/node.asp?id=2248.

To make a file with 1024 PKCS#3 format Diffie-Hellman parameters (change accordingly for other key lengths):
$ openssl dhparam -2 -out diffie-hellman-parameters.pem 1024

You only need to do this once and you can use it across all certificates/keys [I presume?].

5.0 Client Certificates and Keys

Note that anyone with a client certificate signed by the same CA has access through the VPN.

5.1 Create a client certificate and key for each user

Run TinyCA. In Debian use: Applications → Other → TinyCA; In Ubuntu there's no menu item so from the command-line use: $ tinyca2

Choose Certificates tab → NewCreate Key and Certificate (Client).

Common Name (eg. your Name, your eMail Address or the Servers Name): e.g. person's-name or persons-name-<organisation>)
eMail Address: <person's email address>
Password (protect your private Key): ...
Password (confirmation): ...
Country Name (2 letter code): UK (should be the default)
Organization Name (eg. company): the organisation of the person (it defaults to the organisation of the CA)
Keylength: 4096

Use the defaults for everything else unless you know what you're doing.

Choose OK → Sign Request →

CA Password: ...
Valid for (Days): 730 (2 years)
Add eMail address to Subject DN: Yes? (the default)

Choose OK

5.2 Export the client certificate and key and CA certificate

This exports in .P12 format which is suitable for use with OpenVPN on Windows, or Linux NetworkManager and command-line.

Choose Certificates tab → choose particular client certificateExport

Export Format: PKCS#12 (Certificate & Key)
Include Key (PEM): Yes
Include Fingerprint: No (the default)

Choose Save.

Export to PKCS#12

Key Password: this is the particular client key password you gave it earlier to encrypt it, because you're now exporting the key from within TinyCA; this password is used to decrypt the key again now; the server isn't concerned with this; if you get this password wrong you'd be told just at the time of export from TinyCA.

Export Password: the 'PKCS12 File Password' that guards the key itself; you are prompted for this when you try to use it; the server isn't concerned with this, it's just a matter between entering it now and entering it when you use the file; if you got this password wrong you'd be told at the time of using it with OpenVPN or NetworkManager.

Friendly Name: person's full name
Without Passphrase: No (the default)
Add CA Certificate to PKCS#12 structure: Yes (the default)

Choose → OK

It saves as something like <'eMail Address' from above>-cert.p12.

Give it the correct permissions.

6.0 Usage From A Client Computer

See OpenVPN Client.

7.0 Renewing Expired Certificates

7.1 Client Certificates

In TinyCA: right-click on a client certificate → renew certificate (client) → enter the CA password → enter a numnber of days until expiry (making sure it doesn't out live the CA → OK → choose to overwrite the certificate ("There seems to be a certificate with the same Subject already. Creating a new one (overwrite) will fail if it's not revoked or expired!") → OK.

Export this certificate from TinyCA in the usual way and replace the expired certificate on the client computer with this one.

7.1 Server Certificates

If the firewall server certificate has expired you will see something like this in the OpenVPN log:
VERIFY ERROR: depth=0, error=certificate has expired: C=UK, O=ORGANISATION NAME, CN=firewall, emailAddress=...
TLS_ERROR: BIO read tls_read_plaintext error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
TLS Error: TLS object -> incoming plaintext read error
TLS Error: TLS handshake failed

In TinyCA: right-click on the server certificate 'firewall' → renew certificate (server) → enter the CA password → enter a numnber of days until expiry (making sure it doesn't out live the CA → OK → choose to overwrite the certificate ("There seems to be a certificate with the same Subject already. Creating a new one (overwrite) will fail if it's not revoked or expired!") → OK.

Export this certificate from TinyCA in the usual way.

Export the existing key from TinyCA in the usual way.

Go into pfSense's certificate manager: System → Cert Manager → Certificates.

Add a new certificate using '+', paste the new certificate into 'Certificate data', paste the key into 'Private key data' and give it a 'Descriptive name'.

Tell the OpenVPN server to use the new certificate and key: VPN → OpenVPN → e → Server Certificate → select the new OpenVPN Server Certificate from the drop-down list.

Delete the unused 'OpenVPN Server Certificate #1' from System → Cert Manager.

8.0 Revoking Certificates

In TinyCA: Right-click on a certificate and select Revoke Certificate → enter the CA password → enter a Revocation Reason.

In TinyCA: Export the CRL from the CA tab using the far right icon in the toolbar. You will need the CA password. Save . PEM format. (How many days should it be valid for?)

In pfSense: System → Cert Manager → Certificate Revocation → + paste in the CRL. It will say "In Use: NO" until you have completed the next step.

In pfSense: VPN → OpeNVPN - server → Edit → Cryptographic Settings → Peer Certificate Revocation List - select the CRL. The effect is instant and includes clients already using the VPN.