Difference between revisions of "Easy-rsa"

From ArchWiki
Jump to: navigation, search
(Added sample command to generate encrypted .p12 certificate files)
m (Creating certificates on the server: clarification - added word "file" because you are not generating secret. It's file anyway. Avoid confusion)
 
(25 intermediate revisions by 15 users not shown)
Line 1: Line 1:
 
[[Category:Virtual Private Network]]
 
[[Category:Virtual Private Network]]
 
+
The first step when setting up [[OpenVPN]] is to create a [[Wikipedia:Public key infrastructure|Public Key Infrastructure (PKI)]].  The PKI consists of:
The first step when setting up OpenVPN is to create a [[Wikipedia:Public key infrastructure|Public Key Infrastructure (PKI)]].  The PKI consists of:
+
  
 
* A public master [[Wikipedia:Certificate Authority|Certificate Authority (CA)]] certificate and a private key.
 
* A public master [[Wikipedia:Certificate Authority|Certificate Authority (CA)]] certificate and a private key.
Line 14: Line 13:
 
{{Note|The certificates can be created on any machine.  For the highest security, generate the certificates on a physically secure machine disconnected from any network, and make sure that the generated ca.key private key is backed up and never accessible to anyone.}}
 
{{Note|The certificates can be created on any machine.  For the highest security, generate the certificates on a physically secure machine disconnected from any network, and make sure that the generated ca.key private key is backed up and never accessible to anyone.}}
  
{{Warning|Make sure that the generated files are backed up, especially the ca.key and ca.crt files, since if lost you will not be able to create any new, nor revoke any comprised certificates, thus requiring the generation of a new [[Wikipedia:Certificate Authority|Certificate Authority (CA)]] certificate, invalidating the entire PKI infrastructure.}}
+
{{Warning|Make sure that the generated files are backed up, especially the ca.key and ca.crt files, since if lost you will not be able to create any new, nor revoke any compromised certificates, thus requiring the generation of a new [[Wikipedia:Certificate Authority|Certificate Authority (CA)]] certificate, invalidating the entire PKI infrastructure.}}
  
 
===Installing the easy-rsa scripts===
 
===Installing the easy-rsa scripts===
  
Install the scripts by doing the following:
+
First, install {{pkg|easy-rsa}} package and copy files as shown:
 
+
{{bc|# cp -r /usr/share/easy-rsa /root}}
{{bc|# cp -r /usr/share/openvpn/easy-rsa /root}}
+
  
===Creating certificates===
+
===Creating certificates on the server===
  
 
Change to the directory where you installed the scripts.
 
Change to the directory where you installed the scripts.
Line 192: Line 190:
 
</nowiki>}}
 
</nowiki>}}
  
The build-dh script generates the [http://www.rsa.com/rsalabs/node.asp?id=2248 Diffie-Hellman parameters] .pem file needed by the server.
+
The build-dh script generates the [https://web.archive.org/web/20130701090246/https://www.rsa.com/rsalabs/node.asp?id=2248 Diffie-Hellman parameters] .pem file needed by the server. This command will take some time, possibly around from 1 to 5 minutes.
  
 
{{Note|It would be better to generate a new one for each server, but you can use the same one if you want to.}}
 
{{Note|It would be better to generate a new one for each server, but you can use the same one if you want to.}}
Line 205: Line 203:
 
............+...............+...................................................
 
............+...............+...................................................
 
..................................................................++*++*}}
 
..................................................................++*++*}}
 +
 +
To generate the client(s) key(s), one can either do so on the server side directly using the {{ic|./build-key}} script, or generate the key entirely on the client side and then ask the CA authority to sign it. The first method is simpler and quicker, but the second method doesn't require the client private key to leave its machine and is therefore slightly more secure. (see [[#Creating certificates on the client]] for an outline of the second method)
  
 
The build-key script {{ic|# ./build-key <client name>}} generates a client certificate. Make sure that the client name (Common Name when running the script) is unique.
 
The build-key script {{ic|# ./build-key <client name>}} generates a client certificate. Make sure that the client name (Common Name when running the script) is unique.
Line 254: Line 254:
 
Data Base Updated
 
Data Base Updated
 
</nowiki>}}
 
</nowiki>}}
 +
This generates a client certificate ({{ic|bugs.crt}}) and a client private key ({{ic|bugs.key}}) which need to be transferred to the client through a secure channel.
 +
 +
Generate a secret [[Wikipedia:HMAC|Hash-based Message Authentication Code (HMAC)]] file by running:
  
Generate a secret [[Wikipedia:HMAC|Hash-based Message Authentication Code (HMAC)]] by running:
+
# openvpn --genkey --secret /root/easy-rsa/keys/ta.key
{{ic|# openvpn --genkey --secret /root/easy-rsa/keys/ta.key}}
+
  
This will be used to add an additional HMAC signature to all SSL/TLS handshake packets.  In addition any UDP packet not having the correct HMAC signature will be immidiately dropped, protecting against:
+
This will be used to add an additional HMAC signature to all SSL/TLS handshake packets.  In addition any UDP packet not having the correct HMAC signature will be immediately dropped, protecting against:
  
 
* Portscanning.
 
* Portscanning.
Line 268: Line 270:
  
 
{{Warning|This will delete any previously generated certificates stored in /root/easy-rsa/keys, including the [[Wikipedia:Certificate Authority|Certificate Authority (CA)]] certificate.}}
 
{{Warning|This will delete any previously generated certificates stored in /root/easy-rsa/keys, including the [[Wikipedia:Certificate Authority|Certificate Authority (CA)]] certificate.}}
 +
 +
===Creating certificates on the client===
 +
 +
It might be desirable for the clients to generate their private keys on their own machine, removing the need to trust that the CA operator not keep the client's private key stored remotely (or other nefarious intentions). To do so, the client needs to create the private key locally, and create a [[wikipedia:Certificate_signing_request|certificate signing request]] (which is a {{ic|.csr}} file) to the key-signing machine, run by the CA. The operator will then sign the request and return a signed certificate (a {{ic|.crt}} file) which is then transferred back to the client.
 +
 +
====Creating a certificate signing request====
 +
 +
An outline of the required steps follows, assuming "bugs" is the client name:
 +
# Transfer the {{ic|ca.crt}} file from the CA to the client. The {{ic|ca.crt}} file is public information, and thus this transfer can be done over an insecure channel. The file should be stored in {{ic|/root/easy-rsa/keys/ca.crt}}
 +
# Check that the {{ic|ca.crt}} file has not been tampered with by either:
 +
## Having the file be signed by the CA and verified by the client using the CA's public key. Note that this is referring to standard [[GnuPG#Signatures|GnuPG]]-style signature verification: {{ic|gpg --verify doc.sig}}
 +
## Checking the hash of the file (e.g. using {{ic|sha1sum ca.crt}}) and verifying that it matches the expected hash, provided you trust the "expected hash".
 +
## Simply transferring ca.crt over a trusted channel.
 +
## Some other mechanism that the reader sees fit.
 +
# Run {{ic|./build-req bugs}} which is analogous to running  {{ic|./build-key bugs}} in the server section above. The same warning, that the Common Name should be unique, still stands.
 +
# Leave all password field blank. If you'd like to protect your private key with a password, use {{ic|./build-req-pass}} instead. Note that this will require you to input the password whenever the key needs to be unlocked.
 +
# You now have the {{ic|bugs.csr}} and {{ic|bugs.key}} files. Send your certificate signing request to the CA, e.g. by emailing your {{ic|bugs.csr}} file. Keep your {{ic|bugs.key}} file secret, this is your private key.
 +
# Wait until you receive your signed certificate from the CA, which will be a file named {{ic|bugs.crt}}.
 +
 +
====Signing a certificate signing request====
 +
 +
To sign a certificate signing request, the CA simply needs to run {{ic|./sign-req bugs}} after placing {{ic|bugs.csr}} into {{ic|/root/easy-rsa/keys/bugs.csr}}. The CA can then transfer the resulting {{ic|bugs.crt}} file back the client using an insecure channel (e.g. via email)
 +
{{Note| When running the command, the error {{ic|chmod: cannot access `bugs.key': No such file or directory}} will show up. This is expected, and is safe to ignore [https://forums.openvpn.net/topic13418.html]}}
  
 
===Converting certificates to encrypted .p12 format===
 
===Converting certificates to encrypted .p12 format===
Line 273: Line 298:
 
Some software (such as Android) will only read VPN certificates that are stored in a password-encrypted .p12 file. These can be generated with the following command:
 
Some software (such as Android) will only read VPN certificates that are stored in a password-encrypted .p12 file. These can be generated with the following command:
 
{{bc|# openssl pkcs12 -export -inkey keys/bugs.key -in keys/bugs.crt -certfile keys/ca.crt -out keys/bugs.p12}}
 
{{bc|# openssl pkcs12 -export -inkey keys/bugs.key -in keys/bugs.crt -certfile keys/ca.crt -out keys/bugs.p12}}
 +
 +
== See also ==
 +
 +
* [https://openvpn.net/index.php/open-source/documentation/miscellaneous/rsa-key-management.html Official EasyRSA instructions]

Latest revision as of 09:02, 17 April 2016

The first step when setting up OpenVPN is to create a Public Key Infrastructure (PKI). The PKI consists of:

  • A public master Certificate Authority (CA) certificate and a private key.
  • A separate public certificate and private key pair (hereafter referred to as a certificate) for each server and each client.

To facilitate the certificate creation process, OpenVPN comes with a collection of RSA key manangement scripts (based on the openssl command line tool) known as easy-rsa.

Note: Only .key files need to be kept secret, .crt and .csr files can be sent over insecure channels such as plaintext email.

In this article the needed certificates are created by root in root's home directory. This ensures that the generated files have the right ownership and permissions, and are safe from other users.

Note: The certificates can be created on any machine. For the highest security, generate the certificates on a physically secure machine disconnected from any network, and make sure that the generated ca.key private key is backed up and never accessible to anyone.
Warning: Make sure that the generated files are backed up, especially the ca.key and ca.crt files, since if lost you will not be able to create any new, nor revoke any compromised certificates, thus requiring the generation of a new Certificate Authority (CA) certificate, invalidating the entire PKI infrastructure.

Installing the easy-rsa scripts

First, install easy-rsa package and copy files as shown:

# cp -r /usr/share/easy-rsa /root

Creating certificates on the server

Change to the directory where you installed the scripts.

# cd /root/easy-rsa

To ensure the consistent use of values when generating the PKI, set default values to be used by the PKI generating scripts. Edit /root/easy-rsa/vars and at a minimum set the KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL parameters (do not leave any of these parameters blank). Change the KEY_SIZE parameter to 2048 for the SSL/TLS to use 2048bit RSA keys for authentication.

/root/easy-rsa/vars
# easy-rsa parameter settings

# NOTE: If you installed from an RPM,
# do not edit this file in place in
# /usr/share/openvpn/easy-rsa --
# instead, you should copy the whole
# easy-rsa directory to another location
# (such as /etc/openvpn) so that your
# edits will not be wiped out by a future
# OpenVPN package upgrade.

# This variable should point to
# the top level of the easy-rsa
# tree.
export EASY_RSA="`pwd`"

#
# This variable should point to
# the requested executables
#
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"

# This variable should point to
# the openssl.cnf file included
# with easy-rsa.
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`

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

# Issue rm -rf warning
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR

# PKCS11 fixes
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"

# Increase this to 2048 if you
# are paranoid.  This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=2048

# In how many days should the root CA key expire?
export CA_EXPIRE=3650

# In how many days should certificates expire?
export KEY_EXPIRE=3650

# These are the default values for fields
# which will be placed in the certificate.
# Do not leave any of these fields blank.


export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="Acme Acres"
export KEY_ORG="Acme"
export KEY_EMAIL="roadrunner@acmecorp.org"
#export KEY_EMAIL=mail@host.domain
export KEY_CN=Acme-CA
export KEY_NAME=Acme-CA
export KEY_OU=""
export PKCS11_MODULE_PATH=changeme
export PKCS11_PIN=1234

Export the environment variables.

# source ./vars

Delete any previously created certificates.

# ./clean-all
Note: Entering a . (dot) when prompted for a value, blanks out the parameter.

The build-ca script generates the Certificate Authority (CA) certificate.

# ./build-ca
Generating a 2048 bit RSA private key
..............++++++
...++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [Acme Acres]:
Organization Name (eg, company) [Acme]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [Acme-CA]:
Name [Acme-CA]:
Email Address [roadrunner@acmecorp.org]:

The build-key-server script # ./build-key-server <server name> generates a server certificate. Make sure that the server name (Common Name when running the script) is unique.

Note: Do not enter a challenge password or company name when the script prompts you for one.
# ./build-key-server elmer
Generating a 2048 bit RSA private key
.....................++++++
.......................................................++++++
writing new private key to 'elmer.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [Acme Acres]:
Organization Name (eg, company) [Acme]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [elmer]:
Name [Acme-CA]:
Email Address [roadrunner@acmecorp.org]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /root/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :PRINTABLE:'CA'
localityName          :PRINTABLE:'Acme Acres'
organizationName      :PRINTABLE:'Acme'
commonName            :PRINTABLE:'elmer'
name                  :PRINTABLE:'Acme-CA'
emailAddress          :IA5STRING:'roadrunner@acmecorp.org'
Certificate is to be certified until Dec 27 19:11:59 2021 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

The build-dh script generates the Diffie-Hellman parameters .pem file needed by the server. This command will take some time, possibly around from 1 to 5 minutes.

Note: It would be better to generate a new one for each server, but you can use the same one if you want to.
# ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
..+.............................................................................
.
.
.
............+...............+...................................................
..................................................................++*++*

To generate the client(s) key(s), one can either do so on the server side directly using the ./build-key script, or generate the key entirely on the client side and then ask the CA authority to sign it. The first method is simpler and quicker, but the second method doesn't require the client private key to leave its machine and is therefore slightly more secure. (see #Creating certificates on the client for an outline of the second method)

The build-key script # ./build-key <client name> generates a client certificate. Make sure that the client name (Common Name when running the script) is unique.

Note: Do not enter a challenge password or company name when the script prompts you for one.
# ./build-key bugs
Generating a 2048 bit RSA private key
....++++++
.............................................................++++++
writing new private key to 'bugs.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [Acme Acres]:
Organization Name (eg, company) [Acme]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [bugs]:
Name [Acme-CA]:
Email Address [roadrunner@acmecorp.org]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /root/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'US'
stateOrProvinceName   :PRINTABLE:'CA'
localityName          :PRINTABLE:'Acme Acres'
organizationName      :PRINTABLE:'Acme'
commonName            :PRINTABLE:'bugs'
name                  :PRINTABLE:'Acme-CA'
emailAddress          :IA5STRING:'roadrunner@acmecorp.org'
Certificate is to be certified until Dec 27 19:18:27 2021 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

This generates a client certificate (bugs.crt) and a client private key (bugs.key) which need to be transferred to the client through a secure channel.

Generate a secret Hash-based Message Authentication Code (HMAC) file by running:

# openvpn --genkey --secret /root/easy-rsa/keys/ta.key

This will be used to add an additional HMAC signature to all SSL/TLS handshake packets. In addition any UDP packet not having the correct HMAC signature will be immediately dropped, protecting against:

  • Portscanning.
  • DOS attacks on the OpenVPN UDP port.
  • SSL/TLS handshake initiations from unauthorized machines.
  • Any eventual buffer overflow vulnerabilities in the SSL/TLS implementation.

All the created keys and certificates have been stored in /root/easy-rsa/keys. If you make a mistake, you can start over by running the clean-all script again.

Warning: This will delete any previously generated certificates stored in /root/easy-rsa/keys, including the Certificate Authority (CA) certificate.

Creating certificates on the client

It might be desirable for the clients to generate their private keys on their own machine, removing the need to trust that the CA operator not keep the client's private key stored remotely (or other nefarious intentions). To do so, the client needs to create the private key locally, and create a certificate signing request (which is a .csr file) to the key-signing machine, run by the CA. The operator will then sign the request and return a signed certificate (a .crt file) which is then transferred back to the client.

Creating a certificate signing request

An outline of the required steps follows, assuming "bugs" is the client name:

  1. Transfer the ca.crt file from the CA to the client. The ca.crt file is public information, and thus this transfer can be done over an insecure channel. The file should be stored in /root/easy-rsa/keys/ca.crt
  2. Check that the ca.crt file has not been tampered with by either:
    1. Having the file be signed by the CA and verified by the client using the CA's public key. Note that this is referring to standard GnuPG-style signature verification: gpg --verify doc.sig
    2. Checking the hash of the file (e.g. using sha1sum ca.crt) and verifying that it matches the expected hash, provided you trust the "expected hash".
    3. Simply transferring ca.crt over a trusted channel.
    4. Some other mechanism that the reader sees fit.
  3. Run ./build-req bugs which is analogous to running ./build-key bugs in the server section above. The same warning, that the Common Name should be unique, still stands.
  4. Leave all password field blank. If you'd like to protect your private key with a password, use ./build-req-pass instead. Note that this will require you to input the password whenever the key needs to be unlocked.
  5. You now have the bugs.csr and bugs.key files. Send your certificate signing request to the CA, e.g. by emailing your bugs.csr file. Keep your bugs.key file secret, this is your private key.
  6. Wait until you receive your signed certificate from the CA, which will be a file named bugs.crt.

Signing a certificate signing request

To sign a certificate signing request, the CA simply needs to run ./sign-req bugs after placing bugs.csr into /root/easy-rsa/keys/bugs.csr. The CA can then transfer the resulting bugs.crt file back the client using an insecure channel (e.g. via email)

Note: When running the command, the error chmod: cannot access `bugs.key': No such file or directory will show up. This is expected, and is safe to ignore [1]

Converting certificates to encrypted .p12 format

Some software (such as Android) will only read VPN certificates that are stored in a password-encrypted .p12 file. These can be generated with the following command:

# openssl pkcs12 -export -inkey keys/bugs.key -in keys/bugs.crt -certfile keys/ca.crt -out keys/bugs.p12

See also