Easy-RSA v3 OpenVPN Howto
This Howto walks through the use of Easy-RSA v3 with OpenVPN.
The best way to create a PKI for OpenVPN is to separate your CA duty from each server & client. The CA should ideally be on a secure environment (whatever that means to you.) Loss/theft of the CA key destroys the security of the entire PKI.
To use Easy-RSA to set up a new OpenVPN PKI, you will:
- Set up a CA PKI and build a root CA
- Configure secondary PKI environments on your server and each client and generate a keypair & request on them
- Send the certificate requests to the CA, where the CA signs and returns a valid certificate
- On your OpenVPN server, generate DH parameters (see the DH Generation section of this Howto)
Easy-RSA and MITM protection with OpenVPN
Important note: some OpenVPN configs rely on the deprecated "Netscape" cert attribute called nsCertType. This is deprecated behavior, and Easy-RSA 3 does not enable this by default like v2 did. Please use the --remote-cert-tls directive in your OpenVPN config files for MITM protection.
If you really need the old, deprecated behavior, enable the Netscape extensions by reading vars.example before signing certs with your CA. This will allow you to use --ns-cert-type with OpenVPN.
PKI procedure: using a separate CA system
Pick locations for the CA and each entity that will be assigned certs. All keypair/request generation should occur on the target system that will use them; put another way, generate a server request on the actual server system, and your client requests on each client.
You will end up with the following locations used in the steps below:
- your secured CA environment; this will be on a separate system, or at least a separate directory from anything else
- each server has a unique directory for its own key & request (on the actual server system)
- each client has a unique directory for its own key & request (on the actual client system)
- On the CA, start a new PKI and build a CA keypair/cert:
./easyrsa init-pki ./easyrsa build-ca
- On each server system, generate a keypair and request. Normally these are left unencrypted by using the "nopass" argument since servers usually start up without any password input. This generates an unencrypted key, so protect its access and file permissions carefully.
./easyrsa init-pki ./easyrsa gen-req UNIQUE_SERVER_SHORT_NAME nopass
- On each client, generate a keypair and request. The name selected must be unique across the PKI and is otherwise arbitrary. Create a new PKI and request on each client as follows:
./easyrsa init-pki ./easyrsa gen-req UNIQUE_CLIENT_SHORT_NAME
- Optionally, the private key can be left unencrypted on-disk with the additional nopass option after the name. This is not recommended unless automated VPN startup is required. Unencrypted private keys can be used by anyone who obtains a copy of the file. Encrypted keys offer stronger protection, but will require the passphrase on initial use.
- Send the request files from each entity to the CA system. This is not security sensitive, though it is wise to verify the received file matches the sender's copy if the transport is untrusted.
- On the CA, import each entity request file, giving it an arbitrary "short name" as follows. This basically just copies the request file into reqs/ under the PKI dir to prepare it for review and signing.
./easyrsa import-req /path/to/received.req UNIQUE_SHORT_FILE_NAME
- Review each request's details if you wish, then sign it as one of the types: server or client.
- (optional) review the request:
./easyrsa show-req UNIQUE_SHORT_FILE_NAME
- If you are signing as a client:
./easyrsa sign client UNIQUE_SHORT_FILE_NAME
- If you are signing as a server:
./easyrsa sign server UNIQUE_SHORT_FILE_NAME
- (optional) review the request:
- The CA returns the signed certificate produced in the above step, and includes the CA certificate (ca.crt) unless the client already has it. This can be done over an insecure channel, though the client is encouraged to confirm the received CA cert is valid if the transport is untrusted.
On the PKI for the OpenVPN server, this command will generate DH parameters used during the TLS handshake with connecting clients. The DH params are not security sensitive and are used only by an OpenVPN server.