Thursday, July 7, 2011

The OpenVPN Odd-venture

Virtual Private Network (VPN) is Local Area Network (LAN) on steroids powered by the internet, and also more complex to setup. I was tasked at work to setup an OpenVPN server to a client that already has an existing connection to another OpenVPN server, so my task is to add this other server to the client while ensuring the current VPN connection won't be disrupted.

Thanks to this blog, the OpenVPN documentation, and this blog (albeit focused on OpenBSD), I was able to figure out how to setup the VPN, but not without some trial and error adventure along the way.

Originally I thought that tun would be a built-in feature of the setup, running ifconfig on the server didn't bear this, but checking /dev/net/ listed tun as one of the device, so I created my own tun1 with this command:

sudo mknod /dev/net/tun1 c 10 200

Be warned though that this isn't necessary, once OpenVPN session is started, the system should create tun devices automagically. On the server, execute this command line sequence:

sudo openvpn --dev tun1 --port 1194

While on the client, executed this:

sudo openvpn --dev tun --port 1194 --remote <some domain, say, edgekit.com>

Once the server and the client both display the message "Initialization Sequence Completed", it means your VPN was successfully initiated and ready for use. However, the steps I discussed above is just red herring, why would I write this as documentation to the OpenVPN setup if it's a walk in the park? Below is the cautionary tale and adventure how to setup, configure and verify that your VPN built on OpenVPN is working properly.

The OpenVPN Modus Operandi
It should basically involve these steps:
1) Connect to server to create security certificate for server and client
2) Configure server to include the certificate and initialize the server
3) Copy client security certificate to client
4) Start both server and client and they should communicate

OpenVPN Quest and Casualties
As in the steps outlined above, we have to connect to server, this usually involves accessing through SSH. To ensure you can access all the files and properly execute the scripts and commands, I have to have root access, using sudo -s, otherwise, you won't see the error and the keys to be generated in the security certificate folder, in my case it's in /etc/openvpn/easy-rsa/2.0/keys/.

Once we have successfully accessed the server, go to the OpenVPM configuration and certificate file folder, in my case it's in /etc/openvpn/easy-rsa/2.0/ and this may already be different in your setup. We have to make sure OpenVPN isn't running so using the CLI or lovingly called the command line commando (which we'll use throughout this article to execute the commands to configure OpenVPN), we type and hope the OpenVPN daemon is off:

ps aux | grep vpn

Remember the path /etc/openvpn/easy-rsa/2.0/keys/ to hold the certificates? It should have no certificate related files. To make sure we start on clean slate, we type the following to clear any files in the keys/ folder:

cd /etc/openvpn/easy-rsa/2.0/;
./clean-all

There are some references that ask you to run init-config, in my case, there's no such script so no need to run it, after we cleared any certificate-related files in the /etc/openvpn/easy-rsa/2.0/keys/ folder, we type as below to verify that all parameters and programs needed to generate the certificate are in the proper order expected by the system:

source ./vars

For added security and benefit of the paranoid, you can edit vars (since it and the rest of the commands we'll execute later are just editable text scripts), and edit the following parameters:

EASY_RSA - this may by default point to /etc/openvpn/easy-rsa, note no slash (/) at the end.

KEY_DIR - this may by default point to $EASY_RSA/keys, in my case, since our cert folder is /etc/openvpn/easy-rsa/2.0; particular to my case, KEY_DIR should be tweaked to $EASY_RSA/2.0/keys

KEY_SIZE - default value is 1024, we can make it 2048 for added security, but comment about this param in vars warn that replacing it with 2048 will slow down TLS negotiation performance and DH parameter generation process

KEY_COUNTRY - set to PH, in this case I'm doing this for the Philippines

KEY_PROVINCE - set to NCR

KEY_CITY - set to Taguig

KEY_ORG - my company and I guess you shouldn't know about it

KEY_EMAIL - set to a tried address like guesswho@guesswhere.net but should be a real email address if you follow these steps.

I needed to edit the following files to suit the configuration of the deployment of OpenVPN:
build-ca, updated to "$EASY_RSA/2.0/pkitool" on line 8
build-key-server, updated to "$EASY_RSA/2.0/pkitool" on line 10
build-key, updated to "$EASY_RSA/2.0/pkitool" on line 7

Unfortunately, some script, and doubly unfortunate I can't recall which, is hardwired to find openssl.cnf on /etc/openvpn/easy-rsa folder, while it's located on /etc/openvpn/easy-rsa/2.0/; as workaround, made softlink to it as below:

ln -s /etc/openvpn/easy-rsa/2.0/openssl.cnf /etc/openvpn/easy-rsa/openssl.cnf

When all is properly setup, you can execute the commands as follows:

./vars
./build-ca

Next we run the command below, you may opt to leave the challenge password blank for the following commands, we self-sign our certificate:

./build-key-server server
./build-key client
./build-dh

Next we move all *.crt, *.key and *.csr files into /etc/openvpn/ and configure the OpenVPN server.

The OpenVPN Server Saga
To get things in proper perspective, we have to check what will be the files in /etc/openvpn after we moved or copied the server and client security certificate files. We should have the following the server configuration file (i.e. server.conf, should always have filename extension .conf), the certificates for the server and client (we have just moved them from where we generated them, besides, to save time we configure the server before the client), and the common certificate files for both the server and the client: ca.crt (this is very important as we'll discuss later).

We will now create an OpenVPN server configuration file (in this example, filename is server.conf), with content below (server parameter IP and netmask are arbitrary and can be configured to your liking):

port 1194
proto udp
dev tun
ca ca.crt
dh dh1024.pem
server 10.9.0.0 255.255.255.0
persist-key
persist-tun

To start the server using the venerable command line, we type (if we read the message, as in the start of this article saying "Initialization Sequence Completed" server is up and ready):

sudo openvpn server.conf

The OpenVPN Client Climax
Now we focus on setting up the OpenVPN client. Since the security certificates are from the server, we have to get the client's certificate. All files can be easily copied, except for the client certificate key (the filename could be client.key) which is by default owned by root, so copying it will be denied if the user is not root.

Another catch in our situation is that this client has an existing VPN connection to another server, so it has an existing file named ca.crt, and you either can't or shouldn't overwrite this file, or it can wreak havok on your client's existing or new VPN connection, or worse both. We can rename the newly copied ca.crt from the server to <server>-ca.crt (for example, vpnserver2-ca.crt).

The hopefully last catch is that since there's an existing OpenVPN connection, the port 1194 may already be in use, that turns out to be the case for my situation, so what do we do? The answer is that we use another port number (i.e. 1195 or higher, make sure you don't use a port number that's usually for standard use by another protocol).

Like the case of the OpenVPN server, the client's filename can be anything, but the file extension has to be .conf, so we'll name our client in this example client_<server IP or domain maybe>.conf that contains the following (in this example, let's make the remote point to vpn.edgekit.com):

client
port 1195
proto udp
dev tun
remote vpn.edgekit.com 1195
ca vpnserver2-ca.crt
key client.key
persist-key
persist tun
verb 3


VPN Connect and Conclude
For the refinement on the server side and assurance that server and client will see each other, we have to update the port from 1194 to 1195, so the content of the server.conf will be:

port 1195
proto udp
dev tun
ca ca.crt
dh dh1024.pem
server 10.9.0.0 255.255.255.0
persist-key
persist-tun

We can verify that VPN connection is established by starting the server and client as follows:

(for the server)
sudo openvpn server.conf


(for the client, say the client configuration filename is client-edgekit.com.conf)
sudo openvpn client-edgekit.com.conf

Both should return the message "Initialization Sequence Completed" and we'll be riding towards the sunset, safe in the knowledge that we have successfully configured and connected securely. If all else fails, are you sure your firewall has allowed this VPN session to go through?

3 comments:

  1. Followed your guide and it worked out great. Thank you very much for sharing this.
    US VPN

    ReplyDelete
  2. Do you really need to use Linux to run OpenVPN? Does the performance differ when your running it on Windows environment?

    chicago colocation

    ReplyDelete
  3. Hi Marshal, I hope it suffices to say that provided OpenVPN is part of your infrastructure, when it manifest some problem(s), in the case of Windows, there are many factors to watch out for (and blame?) rather than to ensure that the hardware and base OS is still sanely working :)
    Thanks for reading my blog.

    ReplyDelete