Setting up OpenVPN server on your instance
When you need to connect to your internal Bluemix Private Cloud instances, but either you don’t have the available floating IP addresses or you prefer to not put those virtual machines on the internet, one recourse is to establish a bastion host with OpenVPN running on it. That way, you can connect and pass through the host to your internal network. In this article, you’ll learn how to install and set up your OpenVPN server and client for the connection. Assume that you’re already running a virtual machine that has a floating IP allocated to it. We’re not going to discuss setting up ufw or go into any hardened of linux, this how-to is strictly about getting OpenVPN up and running on an instance hosted on OpenStack. For the purpose of this example, we’re using Ubuntu 14.04.
Complete these steps for your server-side setup.
Step 1 - OpenVPN Configuration
Before we install any packages, first we’ll update Ubuntu’s repository lists.
Then we can install OpenVPN and Easy-RSA.
The example VPN server configuration file needs to be extracted to /etc/openvpn
so we can incorporate it into our setup. This extraction can be done with one command:
Once extracted, open server.conf
in a text editor. This tutorial will use Vim but you can use whichever editor you prefer.
There are several changes to make in this file. You will see a section looking like this:
Edit dh1024.pem
to say dh2048.pem
This change will double the RSA key length used when generating server and client keys.
Still in the server.conf
file, now look for this section:
Uncomment push "redirect-gateway def1 bypass-dhcp"
so the VPN server passes on clients’ web traffic to its destination. The line should look like this when done:
The next edit to make is in this area of the file:
Uncomment push "dhcp-option DNS 208.67.222.222"
and push "dhcp-option DNS 208.67.220.220"
. The entries should look like this when done:
This entry tells the server to push OpenDNS to connected clients for DNS resolution where possible. Using push can help prevent DNS requests from leaking outside the VPN connection. However, it’s important to specify desired DNS resolvers in client devices as well. Though OpenDNS is the default used by OpenVPN, you can use whichever DNS services you prefer.
The last area to change in the server.conf
file is here:
Uncomment user nobody
and group nogroup
. The entry should look like this when done:
By default, OpenVPN runs as the root user and thus has full root access to the system. Instead, confine OpenVPN to the user nobody
and group nogroup
, which is an unprivileged user with no default login capabilities, often reserved for running untrusted applications such as web-facing servers.
Now save your changes and exit Vim.
Packet Forwarding
We need a sysctl
setting that tells the server’s kernel to forward traffic from client devices out to the Internet. Otherwise, the traffic will stop at the server. Enable packet forwarding during runtime by entering this command:
We now need to make this forwarding permanent, so the server still forwards traffic after rebooting.
Near the top of the sysctl
file, you will see:
Uncomment net.ipv4.ip_forward. The line should look like this when done:
Save your changes and exit Vim.
Uncomplicated Firewall (ufw)
ufw
is a front-end for iptables. Setting up ufw
is not difficult. It’s included by default in Ubuntu 14.04, so we only need to make a few rules and configuration edits, then switch the firewall on. As a reference for more uses for ufw
, see How To Set up a Firewall with UFW on an Ubuntu and Debian Cloud Server.
First, set ufw
to allow SSH. In the command prompt, enter:
This tutorial will use OpenVPN over UDP, so ufw must also allow UDP traffic over port 1194.
The ufw
forwarding policy needs to be set as well. We’ll do this in ufw’s primary configuration file.
Look for DEFAULT_FORWARD_POLICY="DROP"
. This entry must be changed from DROP
to ACCEPT.
The entry should look like this when done:
Next we will add additional ufw
rules for network address translation and IP masquerading of connected clients.
Make the top of your before.rules
file look like the example that follows. The area in red for OPENVPN RULES
must be added:
With the changes made to ufw
, we can now enable it. Enter into the command prompt:
Enabling ufw
will return the following prompt:
Answer y
. The result will be this output:
To check ufw’s primary firewall rules:
The status command should return these results:
Step 2 - Creating a Certificate Authority and Server-Side Certificate & Key
OpenVPN uses certificates to encrypt traffic.
Configure and Build the Certificate Authority
It is now time to set up our own Certificate Authority (CA) and generate a certificate and key for the OpenVPN server. OpenVPN supports bidirectional authentication based on certificates, meaning that the client must authenticate the server certificate and the server must authenticate the client certificate before mutual trust is established. We will use Easy RSA’s scripts we copied earlier to do this.
First, copy over the Easy-RSA generation scripts.
Then make the key storage directory.
Easy-RSA has a variables file we can edit to create certificates exclusive to our person, business, or whatever entity we choose. This information is copied to the certificates and keys, and it will help identify the keys later.
The variables below should be changed according to your preference.
In the same vars file, also edit this one line shown below. For simplicity, we will use server as the key name. If you want to use a different name, you would also need to update the OpenVPN configuration files that reference server.key
and server.crt
.
We need to generate the Diffie-Hellman parameters; this can take several minutes.
Now let’s change directories so that we’re working directly out of where we moved Easy-RSA’s scripts to earlier in Step 2.
Initialize the PKI (Public Key Infrastructure). Pay attention to the dot (.) and space in front of ./varscommand
. That signifies the current working directory (source).
The output from the above command is shown below. Since we haven’t generated anything in the keysdirectory yet, the warning is nothing to be concerned about.
NOTE: If you run ./clean-all
, I will be doing a rm -rf
on /etc/openvpn/easy-rsa/keys
Now we’ll clear the working directory of any possible old or example keys to make way for our new ones.
This final command builds the certificate authority (CA) by invoking an interactive OpenSSL command. The output will prompt you to confirm the Distinguished Name variables that were entered earlier into the Easy-RSA’s variable file (country name, organization, etc.).
Simply press ENTER to pass through each prompt. If something must be changed, you can do that from within the prompt.
Generate a Certificate and Key for the Server
Still working from /etc/openvpn/easy-rsa
, now enter the command to build the server’s key. Where you see server marked in red is the export KEY_NAME
variable we set in Easy-RSA’s vars file earlier in Step 2.
Similar output is generated as when we ran ./build-ca
, and you can again press ENTER to confirm each line of the Distinguished Name. However, this time there are two additional prompts:
Both should be left blank, so just press ENTER to pass through each one.
Two additional queries at the end require a positive (y
) response:
The last prompt above should complete with:
Move the Server Certificates and Keys
OpenVPN expects to see the server’s CA, certificate and key in /etc/openvpn
. Let’s copy them into the proper location.
You can verify the copy operation was successful with this command:
You should see the certificate and key files for the server.
At this point, the OpenVPN server is ready to go. Start it and check the status.
The status command should return this result:
Congratulations! Your OpenVPN server is operational.
If the status message says the VPN is not running, take a look at the /var/log/syslog file
for errors such as:
That error indicates that server.key
was not copied to /etc/openvpn
correctly. Re-copy the file and try again.
Step 3 - Generate Certificates and Keys for Clients
So far we’ve installed and configured the OpenVPN server, created a Certificate Authority, and created the server’s own certificate and key. In this step, we use the server’s CA to generate certificates and keys for each client device that will be connecting to the VPN. These files later will be installed onto the client devices, such as a laptop or smartphone.
Key and Certificate Building
It’s ideal for each client connecting to the VPN to have its own unique certificate and key. This setup is preferable to generating one general certificate and key to use among all client devices.
Note: By default, OpenVPN does not allow simultaneous connections to the server from clients using the same certificate and key. (See duplicate-cn
in /etc/openvpn/server.conf
.)
To create separate authentication credentials for each device you intend to connect to the VPN, you should complete this step for each device, but change the name client1
below to something different such as client2
or iphone2
. With separate credentials per device, they can later be deactivated at the server individually, if need be. The remaining examples in this tutorial will use client1
as our example client device’s name.
As we did with the server’s key, now we build one for our client1
example. You should still be working out of /etc/openvpn/easy-rsa
.
Once again, you’ll be asked to change or confirm the Distinguished Name variables and these two prompts which should be left blank. Press ENTER to accept the defaults.
As before, these two confirmations at the end of the build process require a (y
) response:
If the key build was successful, the output will again be:
The example client configuration file should be copied to the Easy-RSA key directory too. We’ll use it as a template which will be downloaded to client devices for editing. In the copy process, we are changing the name of the example file from client.conf
to client.ovpn
because the .ovpn
file extension is what the clients will expect to use.
You can repeat this section again for each client, replacing client1
with the appropriate client name throughout.
Transferring Certificates and Keys to Client Devices
Recall from the steps above that we created the client certificates and keys, and that they are stored on the OpenVPN server in the /etc/openvpn/easy-rsa/keys
directory.
For each client we need to transfer the client certificate, key, and profile template files to a folder on our local computer or another client device.
In this example, our client1
device requires its certificate and key, located on the server in:
The ca.crt
and client.ovpn
files are the same for all clients. Download these two files as well; notice that the ca.crt
file is in a different directory than the others.
While the exact applications used to accomplish this transfer will depend on your choice and device’s operating system, you want the application to use SFTP (SSH file transfer protocol) or SCP (Secure Copy) on the backend. This will transport your client’s VPN authentication files over an encrypted connection.
Here is an example SCP command using our client1
example. It places the file client1.key
into the Downloads directory on the local computer.
Here are several tools and tutorials for securely transfering files from the server to a local computer:
WinSCP How To Use SFTP to Securely Transfer Files with a Remote Server How To Use Filezilla to Transfer and Manage Files Securely on your VPS
At the end of this section, make sure you have these four files on your client device:
Step 4 - Creating a Unified OpenVPN Profile for Client Devices
There are several methods for managing the client files but the easiest uses a unified profile. This is created by modifying the client.ovpn template file to include the server’s Certificate Authority, and the client’s certificate and its key. Once merged, only the single client.ovpn profile needs to be imported into the client’s OpenVPN application.
We will create a single profile for our client1 device on the local computer we downloaded all the client files to. This local computer could itself be an intended client or just a temporary work area to merge the authentication files. The original client.ovpn template file should be duplicated and renamed. How you do this will depend on the operating system of your local computer.
Note: The name of your duplicated client.ovpn doesn’t need to be related to the client device. The client-side OpenVPN application will use the file name as an identifier for the VPN connection itself. Instead, you should duplicate client.ovpn to whatever you want the VPN’s nametag to be in your operating system. For example: work.ovpn will be identified as work, school.ovpn as school, etc.
In this tutorial, we’ll name the VPN connection Test1 so Test1.ovpn will be the file name referenced from this point on. Once named, we then must open Test1.ovpn in a text editor; you can use whichever editor you prefer.
The first area of attention will be for the IP address of your Droplet. Near the top of the file, change my-server-1 to reflect your VPN’s IP.
Next, find the area shown below and uncomment user nobody
and group nogroup
, just like we did in server.conf
in Step 1. Note: This step doesn’t apply to Windows so you can skip it. The entry should look like this when done:
The area given below needs the three lines shown to be commented out so we can instead include the certificate and key directly in the Test1.ovpn
file. It should look like this when done:
To merge the individual files into the one unified profile, the contents of the ca.crt
, client1.crt
, and client1.key
files are pasted directly into the .ovpn
profile using a basic XML-like syntax. The XML at the end of the file should take this form:
When finished, the end of the file should be similar to this abbreviated example:
The client1.crt
file has some extra information in it; it’s fine to just include the whole file.
Save the changes and exit. We now have a unified OpenVPN client profile to configure our client1
.
From here, we just need to feed the .ovpn
file into the VPN client of our choice, whether that be Tunnelblick, Viscosity (both for OSX) or of your choice.
Before we test this, though, we need to make sure that OpenStack is prepared to allow this traffic to go through. Let’s take a look at our instances:
Formatting aside due to constrained space, what we have here are 3 instances; jkbastion, which has a floating IP, and also jkinternal-ssh and jkinternal-web, which obviously correlate to web and ssh (the web VM is running nginx).
Also, let’s peek at our security groups, to make sure we’re allowing UDP 1194 to our bastion host:
Details of jkbastion:
That should do it! With the VPN connected, you should be able to hit internal virtual machines with the services you need.