10.2.1.1. Public Key Infrastructure: easy-rsa
The RSA algorithm is widely used in public-key cryptography. It involves a “key pair”, comprised of a private and a public key. The two keys are closely linked to each other, and their mathematical properties are such that a message encrypted with the public key can only be decrypted by someone knowing the private key, which ensures confidentiality. In the opposite direction, a message encrypted with the private key can be decrypted by anyone knowing the public key, which allows authenticating the origin of a message since only someone with access to the private key could generate it. When associated with a digital hash function (MD5, SHA1, or a more recent variant), this leads to a signature mechanism that can be applied to any message.
However, anyone can create a key pair, store any identity on it, and pretend to be the identity of their choice. One solution involves the concept of a
Certification Authority (CA), formalized by the X.509 standard. This term covers an entity that holds a trusted key pair known as a
root certificate. This certificate is only used to sign other certificates (key pairs), after proper steps have been undertaken to check the identity stored on the key pair. Applications using X.509 can then check the certificates presented to them, if they know about the trusted root certificates.
OpenVPN follows this rule. Since public CAs only emit certificates in exchange for a (hefty) fee, it is also possible to create a private certification authority within the company. For that purpose, OpenVPN provides the
easy-rsa tool which serves as an X.509 certification infrastructure. Its implementation is a set of scripts using the
openssl
command; these scripts can be found under
/usr/share/doc/openvpn/examples/easy-rsa/2.0/
.
The Falcot Corp administrators use this tool to create the required certificates, both for the server and the clients. This allows the configuration of all clients to be similar since they will only have to be set up so as to trust certificates coming from Falcot's local CA. This CA is the first certificate to create; to this end, the administrators copy the directory containing
easy-rsa into a more appropriate location, preferably on a machine not connected to the network in order to mitigate the risk of the CA's private key being stolen.
$
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 pki-falcot
$
cd pki-falcot
They then store the required parameters into the
vars
file, especially those named with a
KEY_
prefix; these variables are then integrated into the environment:
$
vim vars
$
grep KEY_ vars
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export KEY_SIZE=1024
export KEY_EXPIRE=3650
export KEY_COUNTRY="FR"
export KEY_PROVINCE="Loire"
export KEY_CITY="Saint-Étienne"
export KEY_ORG="Falcot Corp"
export KEY_EMAIL="admin@falcot.com"
$
. ./vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/rhertzog/pki-falcot/keys
$
./clean-all
The next step is the creation of the CA's key pair itself (the two parts of the key pair will be stored under
keys/ca.crt
and
keys/ca.key
during this step):
$
./build-ca
Generating a 1024 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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [Falcot Corp CA]:
Name []:
Email Address [admin@falcot.com]:
The certificate for the VPN server can now be created, as well as the Diffie-Hellman parameters required for the server side of an SSL/TLS connection. The VPN server is identified by its DNS name
vpn.falcot.com
; this name is re-used for the generated key files (
keys/vpn.falcot.com.crt
for the public certificate,
keys/vpn.falcot.com.key
for the private key):
$
./build-key-server vpn.falcot.com
Generating a 1024 bit RSA private key
...............++++++
...........++++++
writing new private key to 'vpn.falcot.com.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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [vpn.falcot.com]:
Name []:
Email Address [admin@falcot.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /home/rhertzog/pki-falcot/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'FR'
stateOrProvinceName :PRINTABLE:'Loire'
localityName :T61STRING:'Saint-\0xFFFFFFC3\0xFFFFFF89tienne'
organizationName :PRINTABLE:'Falcot Corp'
commonName :PRINTABLE:'vpn.falcot.com'
emailAddress :IA5STRING:'admin@falcot.com'
Certificate is to be certified until Oct 9 13:57:42 2020 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
$
./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
..............+.......+.................................++*++*++*
The following step creates certificates for the VPN clients; one certificate is required for each computer or person allowed to use the VPN:
$
./build-key JoeSmith
Generating a 1024 bit RSA private key
................++++++
.............................++++++
writing new private key to 'JoeSmith.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) [FR]:
State or Province Name (full name) [Loire]:
Locality Name (eg, city) [Saint-Étienne]:
Organization Name (eg, company) [Falcot Corp]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [JoeSmith]:
Joe Smith
Name []:
Email Address [admin@falcot.com]:
joe@falcot.com
[…]
Now all certificates have been created, they need to be copied where appropriate: the root certificate's public key (
keys/ca.crt
) will be stored on all machines (both server and clients) as
/etc/ssl/certs/Falcot_CA.crt
. The server's certificate is installed only on the server (
keys/vpn.falcot.com.crt
goes to
/etc/ssl/vpn.falcot.com.crt
, and
keys/vpn.falcot.com.key
goes to
/etc/ssl/private/vpn.falcot.com.key
with restricted permissions so that only the administrator can read it), with the corresponding Diffie-Hellman parameters (
keys/dh1024.pem
) installed to
/etc/openvpn/dh1024.pem
. Client certificates are installed on the corresponding VPN client in a similar fashion.
10.2.1.2. Configuring the OpenVPN Server
By default, the OpenVPN initialization script tries starting all virtual private networks defined in
/etc/openvpn/*.conf
. Setting up a VPN server is therefore a matter of storing a corresponding configuration file in this directory. A good starting point is
/usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz
, which leads to a rather standard server. Of course, some parameters need to be adapted:
ca
,
cert
,
key
and
dh
need to describe the selected locations (respectively,
/etc/ssl/certs/Falcot_CA.crt
,
/etc/ssl/vpn.falcot.com.crt
,
/etc/ssl/private/vpn.falcot.com.key
and
/etc/openvpn/dh1024.pem
). The
server 10.8.0.0 255.255.255.0
directive defines the subnet to be used by the VPN; the server uses the first IP address in that range (
10.8.0.1
) and the rest of the addresses are allocated to clients.
With this configuration, starting OpenVPN creates the virtual network interface, usually under the
tun0
name. However, firewalls are often configured at the same time as the real network interfaces, which happens before OpenVPN starts. Good practice therefore recommends creating a persistent virtual network interface, and configuring OpenVPN to use this pre-existing interface. This further allows choosing the name for this interface. To this end,
openvpn --mktun --dev vpn --dev-type tun
creates a virtual network interface named
vpn
with type
tun
; this command can easily be integrated in the firewall configuration script, or in an
up
directive of the
/etc/network/interfaces
file. The OpenVPN configuration file must also be updated accordingly, with the
dev vpn
and
dev-type tun
directives.
Barring further action, VPN clients can only access the VPN server itself by way of the
10.8.0.1
address. Granting the clients access to the local network (192.168.0.0/24), requires adding a
push route 192.168.0.0 255.255.255.0
directive to the OpenVPN configuration so that VPN clients automatically get a network route telling them that this network is reachable by way of the VPN. Furthermore, machines on the local network also need to be informed that the route to the VPN goes through the VPN server (this automatically works when the VPN server is installed on the gateway). Alternatively, the VPN server can be configured to perform IP masquerading so that connections coming from VPN clients appear as if they are coming from the VPN server instead (see
Section 10.1, “Gateway”).