Setting Up OpenVPN with X509 Certificates

Markus Feilner

December 2007

Creating Certificates

One method could be setting up tunnels using pre-shared keys with static encryption, however, X509 certificates provide a much better level of security than pre-shared keys do. There is, however, slightly more work to be done to set up and connect two systems with certificate-based authentication. The following five steps have to be accomplished:

  1. Create a CA certificate for your CA with which we will sign and revoke client certificates.

  3. Create a key and a certificate request for the clients.

  5. Sign the request using the CA certificate and thereby making it valid.

  7. Provide keys and certificates to the VPN partners.

  9. Change the OpenVPN configuration so that OpenVPN will use the certificates and keys, and restart OpenVPN.

There are a number of ways to accomplish these steps. easy-rsa is a command-line tool that comes with OpenVPN, and exists both on Linux and Windows. On Windows systems you could create certificates by clicking on the batch files in the Windows Explorer, but starting the batch files at the command-line prompt should be the better solution. On Linux you type the full path of the scripts, which share the same name as on Windows, simply without the extension .bat.

Certificate Generation on Windows XP with easy-rsa

Open the Windows Explorer and change to the directory C:Program Files OpenVPNeasy-rsa. The Windows version of easy-rsa consists of thirteen files. On Linux systems you will have to check your package management tools to find the right path to the easy-rsa scripts. On Debian Linux you will find them in /usr/share/doc/openvpn/examples/easy-rsa/.

Setting Up OpenVPN with X509 Certificates

You find there are eight batch files, four configuration files, and a README (which is actually not really helpful). However, we must now create a directory called keys, copy the files serial.start and index.txt.start into it, and rename them to serial and index.txt respectively. The keys and certificates created by easy-rsa will be stored in this directory. These files are used as a database for certificate generation.

Setting Up OpenVPN with X509 Certificates

Now we let easy-rsa prepare the standard configuration for our certificates. Double-click on the file C:Program FilesOpenVPNeasy-rsainit-config.bat or start this batch file at a command-line prompt. It simply copies the template files vars.bat.sample to vars.bat and openssl.cnf.sample to openvpn.ssl. While the file openssl is a standard OpenSSL configuration, the file vars.bat contains variables used by OpenVPN's scripts to create our certificates, and needs some editing in the next step.

Setting Variables—Editing vars.bat

Right-click on the vars.bat file's icon and select from the menu.

Setting Up OpenVPN with X509 Certificates

In this file, several parameters are set that are used by the certificate generation scripts later. The following table gives a quick overview of the entries in the file:

Entry in vars.bat


set HOME=%ProgramFiles%OpenVPN easy-rsa

The path to the directory where easy-rsa resides.

set KEY_CONFIG=openssl.cnf

The name of the OpenSSL configuration file.

set KEY_DIR=keys

The path to the directory where the newly generated keys are stored-relative to $HOME as set above.

set KEY_SIZE=1024

The length of the SSL key. This parameter should be increased to 2048.

set KEY_CITY=SanFrancisco
set KEY_ORG=FortFunston
set KEY_EMAIL=mail@host.domain

These five values are used as suggestions whenever you start a script and generate certificates with the easy-rsa software.

Only the entry KEY_SIZE must be changed (unless you don't care much about security), but setting the last five entries to your needs might be very helpful later. Every time we generate a certificate, easy-rsa will ask (among others) for these five parameters, and give a suggestion that could be accepted simply by pressing Enter. The better the default values set here in vars.bat fit our needs, the less typing work we will have later. I leave it up to you to change these settings here.

The next step is easy. Run vars.bat to set the variables. Even though you could simply double-click on its explorer icon, I recommend that you run it in a shell window. Select the entry Run from Windows' main menu, type cmd.exe, and change to the easy-rsa directory by typing cd "C:Program FilesOpenVPNeasy-rsa" and pressing Enter. By doing so, we will proceed in exactly the same way as we would do on a Linux system (except for the .bat extensions).

Creating the Diffie-Hellman Key

Now it is time to create the keys that will be used for encryption, authentication, and key exchange. For the latter, a Diffie-Hellman key is used by OpenVPN. The Diffie-Hellman key agreement protocol enables two communication partners to exchange a secret key safely. No prior secrets or safe lines are needed; a special mathematical algorithm guarantees that only the two partners know the used shared key. If you would like to know exactly what this algebra is about, have a look at this website:

easy-rsa provides a script (batch) file that generates the key for you: C:Program FilesOpenVPNeasy-rsabuild-dh.bat. Start it by typing build-dh.bat. A Diffie-Hellman key is being generated. The batch file tells you, This is going to take a long time, which is only true if your system is really old or if you are not patient enough. However, on modern systems some minutes may be a time span horribly long!

Setting Up OpenVPN with X509 Certificates

Building the Certificate Authority

OK, now it's time to generate our first CA.

Enter build-ca.bat. This script generates a self-signed certificate for a CA. Such a certificate can be used to create and sign client certificates and thereby authenticate other machines.

Setting Up OpenVPN with X509 Certificates

Depending on the data you entered in your vars.bat file, build-ca.bat will suggest different default parameters during the process of generating this certificate. Five of the last seven lines are taken from the variables set in vars.bat. If you edited these parameters, a simple return will do here and the certificate for the CA is generated in the keys directory.

Let's now have a look in this directory. Point your Windows Explorer to it, and you will see that the following files have been created:

Setting Up OpenVPN with X509 Certificates

easy-rsa's build-ca.bat script has created a certificate file ca.crt and a CA key file ca.key. The build-dh.bat script has built a dh2048.pem Diffie-Hellman key file, where the length of this key is part of the filename — if you use 1024-bit keys, this file will be named dh1024.pem. Really paranoid (but patient) readers may find a dh4096.pem file.

The file ca.crt is needed by all machines that are supposed to connect to your server, whereas the dh2048.pem file must only be available on the server.

Please note that whoever owns the file ca.key (and ca.crt) is able to sign requests for your CA. Therefore, this file must be kept absolutely secret and should never leave the CA server. This file is essential and is the central key to your VPN. It should be kept protected on one computer strictly. Many experts advise you to use a dedicated machine without network connection (local login only) and strict access rules for this purpose.

Generating Server and Client Keys

Our next step is to provide a VPN server certificate and a key, and have it signed from the CA. Or, to be more precise, we will create a certificate request that will be signed by the CA. An unsigned request cannot be used. Like a passport not stamped or unsigned by your local authority, no one will trust an unsigned certificate (request). Again, batch files are provided to fulfill this task. Start build-key-server.bat VPN-Server at your command-line prompt. The parameter you give to this script is the template name used for the files. In this example, we will use VPN-Server as an example.

A 2048-bit private RSA key is generated. Again, the values derived from the parameters in your vars.bat are provided as default and can be accepted by simply pressing Enter. Only in the field Common Name, you should be very specific and enter a distinguished name for your VPN server. Every time you generate a certificate/key pair, you should enter the name for the machine you want to use this certificate/key pair on. I suggest that you use the same name you chose as command-line argument. As we will see later in this book, OpenVPN can have different configurations based on and distinguished by the value that you enter here, and choosing names skillfully here can save a lot of work later.

Setting Up OpenVPN with X509 Certificates

If you want, you can also enter some extra attributes, like a password that needs to be entered every time the certificate is used or an optional company name. However, if you enter a password here, no one (including no service) can set up a connection without this password. I leave it up to you to decide if this makes sense; if you are a little inclined to paranoia it will.

After the certificate request is generated, the batch script asks you if you want to have it signed by the CA. Simply enter Y twice, and the request is signed.

Let's again have a look at the keys directory. Three files whose name starts with VPN-Server have been generated: VPN-Server.key, VPN-Server.crt, and VPN-Server.csr. The file with the extension is the server key, the file with the extension .key.crt contains the server certificate, and the file VPN-Server.csr holds the certificate signing request signed in the step before.

Setting Up OpenVPN with X509 Certificates

What does that mean now? Right, we have a certificate/key pair for our VPN server that tells everybody that the machine owning and using this pair is (or was) trusted by the CA we created before. What a pity, that nobody else knows this authority up to now. Let's hurry to change this and create a certificate for a client:

Not very surprisingly, another batch file will help us here. It's called build-key.bat and you should give the name of the VPN client as a command-line parameter. I chose VPN-client just to have a simple, recognizable name.

Setting Up OpenVPN with X509 Certificates

Create another (or many) signed certificate(s) for the other tunnel partner(s) with the batch script build-key-server.bat.


Distributing the Files to the VPN Partners

Again, in your keys directory you will find three new files VPN-client.csr, VPN-client.key, and VPN-client.crt, two of which need to be transferred to the VPN partner. Do you know which ones, already? The following table gives an overview of the files we have created up to now and the ones that have to be transferred to our client.


Location and purpose


Signed certificate of the VPN-Server, must be on VPN-Server


Private RSA key of the VPN-Server, must be on VPN-Server


Certificate signing request of VPN-Server, can be deleted


Signed certificate of the VPN-client, must be on VPN-client


Private RSA key of the VPN-client, must be on VPN-client


Certificate Signing request of VPN-Client, can be deleted


CA certificate, must be available on both machines


The key to the CA, must be kept only on CA; must be kept very secret


The Diffie-Hellman key, must only be available on VPN-Server

OK, we must transfer three files, VPN-client.crt, VPN-client.key, and ca.crt to our VPN client. Remember that we have to use a secure transfer method to do so. If the client is a Linux machine, we will use WinSCP to accomplish that. Start WinSCP and change to the remote directory /etc/openvpn on the Linux machine. Create a directory /etc/openvpn/keys. Although this is not really necessary, a reasonable directory structure is very helpful and makes administration much easier.

Copy the three files by drag-and-drop to the remote directory.

Setting Up OpenVPN with X509 Certificates

Then create a directory called keys under C:Program FilesOpenVPN and copy the three files VPN-Server.crt, VPN-Server.key, and ca.crt into this directory. These are the files needed on the VPN server.

As a last step, we must adapt our configuration files so that OpenVPN uses X509 certificates and knows where to find them.

Configuring OpenVPN to Use Certificates

Open the configuration file in your favorite editor; of course you may also use Notepad:

Setting Up OpenVPN with X509 Certificates

All you have to do here is put # in front of the entry secret key.txt, and add the following five entries:

Entry in config file



OpenVPN will run in TLS-server mode (on a client you will have to add TLS-client)

dh keys/dh2048.pem

Use the Diffie-Hellman key stored in keys/dh2048.pem

ca keys/ca.crt

Use the CA certificate in keys/ca.crt

cert keys/VPN-Server.crt

Use my certificate in keys/VPN-Server.crt

key keys/VPN-Server.key

Use my key in keys/VPN-Server.key

In my test-bed network, where the local net is, and the tunnel network is, the simplest possible configuration file (C:Program FilesOpenVPNconfigsample.ovpn on Windows) for an X509-enabled OpenVPN server is:

    dev tap
    dh keys/dh2048.pem
    ca keys/ca.crt
    cert keys/VPN-Server.crt
    key keys/VPN-Server.key

And the simplest possible configuration file for a client is:

    dev tap
    dh keys/dh2048.pem
    ca keys/ca.crt
    cert keys/VPN-Client.crt
    key keys/VPN-Client.key

Change the OpenVPN configuration on the two systems to the values above.

It's as simple as that. And the best thing is that this configuration is the same on all platforms. Simply edit your openvpn configuration file on the Linux machine as in the previous example, restart your openvpn services, and the tunnels will come up, but this time safe and secure with X509 certificates.

    debian01:/etc/openvpn/keys# openvpn --config /etc/openvpn/sample.ovpn
    Sun Nov 6 06:34:02 2005 OpenVPN 2.0.2 i486-pc-linux-gnu [SSL] [LZO] [EPOLL]
    built on Oct 9 2005
    Sun Nov 6 06:34:02 2005 IMPORTANT: OpenVPN's default port number is now 1194,
    based on an official port number assignment by IANA. OpenVPN 2.0-beta16 and earlier
    used 5000 as the default port.
    Sun Nov 6 06:34:02 2005 WARNING: No server certificate verification method
    has been enabled. See for more info.
    Sun Nov 6 06:34:02 2005 WARNING: file '/etc/openvpn/keys/VPN-Client.key' is
    group or others accessible
    Sun Nov 6 06:34:02 2005 TUN/TAP device tap0 opened
    Sun Nov 6 06:34:02 2005 /sbin/ifconfig tap0 netmask
    mtu 1500 broadcast
    Sun Nov 6 06:34:02 2005 UDPv4 link local (bound): [undef]:1194
    Sun Nov 6 06:34:02 2005 UDPv4 link remote:
    Sun Nov 6 06:34:03 2005 [VPN-Server] Peer Connection Initiated with
    Sun Nov 6 06:34:04 2005 Initialization Sequence Completed

If you do not believe, check it by ping on either side of the tunnel:

Setting Up OpenVPN with X509 Certificates

Use ping to test the tunnel once OpenVPN reports "Peer Connection Initiated".

Using easy-rsa on Linux

We have learned earlier that easy-rsa is a part of OpenVPN and available on all platforms. Because we have worked through the generation of certificates on Windows, we will now have a look at the same process on a Linux system. On Debian Linux, easy-rsa can be found in the directory /usr/share/doc/openvpn/examples/easy-rsa. Start a root shell and change to this directory:

    debian01:/# cd /usr/share/doc/openvpn/examples/easy-rsa
    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ls -l
    total 80
    drwxr-xr-x 2 root root 4096 2005-11-19 09:31 2.0
    -rwxr-xr-x 1 root root 242 2005-11-01 12:06 build-ca
    -rwxr-xr-x 1 root root 228 2005-11-01 12:06 build-dh
    -rwxr-xr-x 1 root root 529 2005-11-01 12:06 build-inter
    -rwxr-xr-x 1 root root 516 2005-11-01 12:06 build-key
    -rwxr-xr-x 1 root root 424 2005-11-01 12:06 build-key-pass
    -rwxr-xr-x 1 root root 695 2005-11-01 12:06 build-key-pkcs12
    -rwxr-xr-x 1 root root 662 2005-11-01 12:06 build-key-server
    -rwxr-xr-x 1 root root 466 2005-11-01 12:06 build-req
    -rwxr-xr-x 1 root root 402 2005-11-01 12:06 build-req-pass
    -rwxr-xr-x 1 root root 280 2005-11-01 12:06 clean-all
    -rw-r--r-- 1 root root 264 2005-11-01 12:06 list-crl
    -rw-r--r-- 1 root root 268 2005-11-01 12:06 make-crl
    -rw-r--r-- 1 root root 7487 2005-11-01 12:06 openssl.cnf
    -rw-r--r-- 1 root root 2619 2005-11-01 12:06 README.gz
    -rw-r--r-- 1 root root 268 2005-11-01 12:06 revoke-crt
    -rwxr-xr-x 1 root root 593 2005-11-01 12:06 revoke-full
    -rwxr-xr-x 1 root root 411 2005-11-01 12:06 sign-req
    -rw-r--r-- 1 root root 1266 2005-11-01 12:06 vars

As you can see, this directory contains all the scripts we have used on Windows, and some more too. On Linux, there is a file called vars, which is a shell script that contains all the information and variables like its Windows counterpart, vars.bat.

On Linux, easy-rsa is located in /usr/share/doc/openvpn/examples/easy-rsa. Start a root shell and change to this directory.

Preparing Variables in vars

Open vars with your favorite editor and change the certificate values to fit your needs. Don't forget to point the entry export KEY_DIR to an existing directory or create the directory /usr/share/doc/openvpn/examples/easy-rsa/keys. Create the two files index.txt and serial in this directory before proceeding.

On Windows, vars.bat is a batch file that simply is executed; on Linux it is sourced, which means that the shell reads this file and sets the environment variables you defined in it—a very common way to read configuration files on Linux. The command for this purpose is called source, and its abbreviation is simply a dot.

Now type source vars or simply . vars to have your shell read the configuration variables you edited:

    debian01:/usr/share/doc/openvpn/examples/easy-rsa# . vars
    NOTE: when you run ./clean-all, I will be doing a rm -rf on

The note you receive is important. In this directory, there is a script called clean-all, which removes all old configurations and keys you created previously from the keys directory you enter in vars. If you want to execute clean-all, be sure to back up all files you might need later on. Normally there should be no need to run clean-all.

Creating the Diffie-Hellman Key and the Certificate Authority

As our next step we will create a Diffie-Hellman key with the script build-dh. On most Linux systems, the working directory is not in the path of the user root, so you have to invoke it with ./build-dh:

    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ./build-dh
    Generating DH parameters, 1024 bit long safe prime, generator 2
    This is going to take a long time

Now your system might be occupied for some time, busily calculating a 1024-bit prime number. If you want to set the key size to 2048, have a look in /usr/share/doc/openvpn/examples/easy-rsa/vars -like we did on Windows. And once we're ready again, create the certificate for the CA:

    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ./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) [DE]:
    State or Province Name (full name) [BY]:
    Locality Name (eg, city) [Regensburg]:
    Organization Name (eg, company) [Feilner-IT]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) []:CA-Server
    Email Address []:
    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ls -l keys
    total 12
    -rw-r--r-- 1 root root 1245 2005-11-20 00:17 ca.crt
    -rw------- 1 root root 887 2005-11-20 00:17 ca.key
    -rw-r--r-- 1 root root 245 2005-11-20 00:14 dh1024.pem

Certificate and key have been created in the directory /usr/share/doc/openvpn/examples/easy-rsa/keys.

Creating the First Server Certificate/Key Pair

Now we can create the first certificate/key pair for our first VPN server. Remember, that the Common Name can be used to recognize a client authenticating with this certificate, so choose a distinguishing name here. After generation of the certificate, we are prompted if we want to sign the certificate using the CA's certificate.

Start creation of a certificate/key pair called VPN-Server with the command ./build-key-server : VPN-Server:

    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ./build-key-server VPN-Server
    Generating a 1024 bit RSA private key
    writing new private key to 'VPN-Server.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) [DE]:
    State or Province Name (full name) [BY]:
    Locality Name (eg, city) [Regensburg]:
    Organization Name (eg, company) [Feilner-IT]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) []:VPN-
    Email Address []:
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/openssl.cnf
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName :PRINTABLE:'DE'
    stateOrProvinceName :PRINTABLE:'BY'
    localityName :PRINTABLE:'Regensburg'
    organizationName :PRINTABLE:'Feilner-IT'
    commonName :PRINTABLE:'VPN-Server'
    emailAddress :IA5STRING:''
    Certificate is to be certified until Nov 17 23:40:04 2015 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

Enter a distinguishing Common Name and enter Y twice to have the certificate signed. The certificate and key file are created in /usr/share/doc/openvpn/examples/easy-rsa/keys:

    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ls -l keys/
    total 44
    -rw-r--r-- 1 root root 3653 2005-11-20 00:40 01.pem
    -rw-r--r-- 1 root root 1233 2005-11-20 00:39 ca.crt
    -rw------- 1 root root 887 2005-11-20 00:39 ca.key
    -rw-r--r-- 1 root root 245 2005-11-20 00:37 dh1024.pem
    -rw-r--r-- 1 root root 104 2005-11-20 00:40 index.txt
    -rw-r--r-- 1 root root 21 2005-11-20 00:40 index.txt.attr
    -rw-r--r-- 1 root root 0 2005-11-20 00:31 index.txt.old
    -rw-r--r-- 1 root root 3 2005-11-20 00:40 serial
    -rw-r--r-- 1 root root 3 2005-11-20 00:31 serial.old
    -rw-r--r-- 1 root root 3653 2005-11-20 00:40 VPN-Server.crt
    -rw-r--r-- 1 root root 688 2005-11-20 00:40 VPN-Server.csr
    -rw------- 1 root root 887 2005-11-20 00:40 VPN-Server.key

Now we have the certificate for the CA and a certificate and key for the first OpenVPN machine.

Creating Further Certificates and Keys

Let's repeat the last step for a second machine, which is called VPN-client:

    debian01:/usr/share/doc/openvpn/examples/easy-rsa# ./build-key-server VPN-Client
    Generating a 1024 bit RSA private key

That's it. Repeat the last command for every machine you want to equip with a certificate. You will find the certificate, key, and CA certificate in /usr/share/doc/openvpn/examples/easy-rsa/keys (or the path you specified in the file vars). Transfer these files to the machines involved in your VPN using a secure method. WinSCP works perfectly here, if you have Windows clients, the command-line tool scp (from the sshd package) is the best choice for data exchange between systems with SSH servers (most Linux/UNIX systems).


If you run into problems, check the following:

  • Ensure basic network connectivity between the two systems. Can they ping each other without problems? Are there firewalls involved between them?
  • Disable all firewalls on both systems during testing the tunnels. We will later set them up properly. Remember that both Windows XP and SuSE activate their firewall solutions by default.
  • OpenVPN and X509 certificates need synchronized time on both systems. For testing purposes you can set the time by hand. On Linux, the commands date and hwclock will help you, for the production environment a time server client should be set up. On Linux, Xntp is probably the most common one; its homepage offers documentation:
  • If you copy the files from a Windows machine to a Linux machine, remember to have dos2unix run and convert the end-of-line characters. The same applies to configuration files, certificates, and keys created on Linux and transferred to Windows — apply unix2dos before transfer. Depending on your Linux system and OpenVPN version, it may be necessary to change the file access permissions in the keys directory as follows:
        debian01:~# cd /etc/openvpn/keys
        debian01:/etc/openvpn/keys# ls -l
        total 16
        -rw------- 1 root root 1606 2005-11-05 09:54 ca.crt
        -rw------- 1 root root 4948 2005-11-05 09:55 VPN-Client.crt
        -rw------- 1 root root 1679 2005-11-05 09:55 VPN-Client.key
  • If file permissions are set less restrictively, some OpenVPN versions may refuse to start.
  • Check the data you enter during the process of creating the certificates. Ensure that you have not misspelled anything and that there are no typos. Any character different in the certificates can cause the process of connecting the systems to fail.

If you have checked this, repeat the process of certificate generation with easy-rsa and enter your data carefully. Analyze the log file entries in the Windows main menu and context menu of the OpenVPN GUI or have a look at the output of openvpn at the command line when invoked manually.


In this article we have used the scripts in the easy-rsa directory, provided with OpenVPN, to create a CA, a Diffie-Hellman key, and both keys, certificate requests, and keys for the two VPN partners. The client and server certificates were automatically signed during creation. After having them transferred to the VPN partner (Windows or Linux), we started the new, secure tunnel.

Further resources on this subject:

You've been reading an excerpt of:

OpenVPN: Building and Integrating Virtual Private Networks

Explore Title