Paranoid Penguin - Linux VPNs with OpenVPN, Part IV

Next, there are five directives related to helper files that OpenVPN will need
to read in order to build a tunnel. ca specifies a file containing at
least one Certificate Authority certificate, specifically, the certificate
of whatever CA will have signed the OpenVPN's server certificate. If you
try to connect to a server whose server certificate was
not signed by
a CA key/certificate specified here, your OpenVPN client process will
terminate the connection.

cert specifies a file containing a client certificate for your OpenVPN
client process to present to the OpenVPN server. This certificate needs to
have been signed by a CA whose certificate resides in the
server's
ca file, or the server will reject connections from you.

In many if not most cases, the simplest way to handle these certificates is
to use the same CA to create and sign both server and client certificates.
In fact, if you remember Part II in this series
(LJ, March 2010), I
already created a client certificate and key, right after
I created
the server credentials.

Because this process is both important and simple, let's take a minute to
review it. I'm skipping the process of setting up and creating the Certificate
Authority itself, as that applies only to server setup (you should
do that only once, on the server). So, assuming you've got a working CA
set up on your OpenVPN server as described in Part II of this article, follow these
steps to use OpenVPN's pkitool script to create a new client certificate:

In step 4, the string minion is the name (the
“common name”, in x.509
parlance) of the host or user whose certificate you're creating. After
issuing this command, you'll be prompted twice to type the certificate's
passphrase.

The output of this command takes the form of three files:
./keys/minion.csr, ./keys/minion.crt and ./keys/minion.key. Only the last
two are important for the purposes of this article: the new client certificate and
client key, respectively.

Of the helper files related to crypto that were created when you set up the
OpenVPN server, your client certificate and key are the only two unique to
the client; ca.crt and ta.key are used on the server and on all clients
that connect to it. Note also that although the client certificate
(minion.crt) contains no private data, the client key minion.key and
the TLS authentication key ta.key both should be kept secret through
local file permissions and by handling them carefully.

For example, you should never e-mail any client key or TA key in clear text
(note that using an https:// URL for Webmail access doesn't count as
message encryption). You should use S/MIME or PGP e-mail encryption if you
need to mail keys to users.

If you use a USB drive or other physical media to distribute keys, you
should either deliver it in person or use a trusted courier to deliver it,
and users should be instructed either to destroy or erase the media after
installing their keys, or keep the media under lock and key. Although having a
passphrase-protected client key should make it hard for an attacker
to use an intercepted key file, it's no guarantee! Under no circumstances
should you issue blank-passphrase client certificates for any VPN
scenario.

Speaking of the client key's passphrase, you also should take care in
how you transmit that passphrase to the key's user. Because it isn't good
policy for any system administrator to know users' passphrases in any
context, users may afterward want to change the key's passphrase. The
simplest way for users to do so is via the openssl command, like so:

bash-$ openssl rsa -in minion.key -out minion.key -aes192

The user does not need to be root to do this, provided the proper
file permissions are set on minion.key (users should have read/write
access on their own keys). After entering this command, users will be
prompted for the key file's old passphrase and then twice for the new
passphrase.

Once users have copied the files ca.crt, client.crt, client.key
and ta.key over to their client system's /etc/openvpn/ directory, they
should make sure they have the correct file permissions set. The two .crt
files should be world-readable, but only owner-writable (that is,
-rw-r--r--). The two .key files, however, should be only
owner-readable/writable (that is, -rw-------).

All four files should be owned by root, assuming your users have root on
their own Linux systems. (Setting up OpenVPN for nonroot users and the
security challenges of doing so are beyond this article's scope.)

Now that you're clear on how to generate and manage client certificate/key
pairs, let's continue working our way down Listing 2. The
ca, cert and
key directives specify the paths of your CA key file, client certificate
file and client key file, respectively. In Listing 2 the values for these
parameters are all just filenames, without their full paths specified. This
implies that those three files are in the same directory as the client
configuration file itself.

So, unlike on the server, where I left all the certificates and keys in
/etc/openvpn/2.0/keys and, therefore, specified a CA certificate path of
2.0/keys/ca.crt, on the client system, you can get by with simply
ca.crt
if the file ca.crt, like the configuration file client.ovpn, is kept in the
directory /etc/openvpn/.

The ns-cert-type server directive says what type of certificate your
client should accept. Because in this example I'm dealing with multiple
clients connecting back to a server, in Listing 2, it's set to
server.
This will prevent some other client from impersonating the server in a
man-in-the-middle attack; the server's certificate, while signed by the
same CA as its clients, has attributes that identify it as a server
certificate, not another client certificate.

The last directive in the certificate/key-file portion of Listing 2 is
tls-auth ta.key 1, which tells OpenVPN to use the file ta.key to add an
extra layer of authentication on your VPN tunnel by requiring all packets
in the TLS handshake phase at the beginning of each tunnel session to be
signed with the specified TLS Authentication key. After the name of the TLS
Authentication key (ta.key), specify a number telling in which
“direction” to use this file: “0” for the server and
“1” for clients.