Running an OpenVPN Server on Cloud-A

The cloud is great for hosting internet-facing applications, but what if you require something that can only be accessed by a set list of users? Sure, you can maintain security groups with those users’ IP addresses, or use login pages to block access to unauthorized users. An alternative and more secure solution is the use of a Virtual Private Network (VPN) between a user’s local network and your Cloud-A private network. There are several VPN solutions available, both free and commercial. We’re going to show you how to use one of the most popular free VPNs available, OpenVPN.

Instance Creation and Prep

In this tutorial, we are going to be using an Ubuntu 16.04 instance as our VPN server. Feel free to use any distribution that you prefer, however keep in mind that these instructions may vary. To create your instance, follow the steps in the animation below.

Next, associate a public IP address to your instance.

screenshot-1483466386 screenshot-1483466421

Once that’s complete, you should be able to SSH into your new instance as the ubuntu user. For more information on managing SSH, check out the documentation. In order for OpenVPN to work, we’ll need to open UDP port 1194 by creating a security group and assigning it to our new instance.

Let’s create our security group and add a rule for the port that OpenVPN uses:


Finally, we need to apply the security group to our instance. Go back to the instance list and do the following:

screenshot-1483466718 screenshot-1483466745

OpenVPN Setup

Now that we have our instance ready with the proper port open, we’re ready to install and setup OpenVPN. The first step is to SSH into our instance as the ubuntu user. If you’re using Windows, you’ll have to use a separate program like PuTTY, while Mac OSX and most Linux distributions have an SSH client pre-installed. If you have questions about accessing your instance, please don’t hesitate to reach out to our support team.

Once logged in, we always recommend installing the latest updates for your OS to ensure that any known security vulnerabilities are patched.

sudo apt-get update && sudo apt-get dist-upgrade -y

This may take some time to complete. Once it has, it’s a good idea to reboot your instance to load the updated kernel if one has been installed. Simply issue the sudo reboot command and wait a moment for your instance to come back online.

Next, we’ll install OpenVPN. It’s available in the official Ubuntu repositories, so installation is simple:

sudo apt-get install -y openvpn easy-rsa zip

OpenVPN is a certificate-based VPN, so we’ll need to create a Certificate Authority (CA) on our VPN server. To start, we’ll want to copy the easyrsa tools to our OpenVPN configuration directory and create a directory to store our private keys:

sudo cp -r /usr/share/easy-rsa /etc/openvpn/
sudo mkdir /etc/openvpn/easy-rsa/keys

Edit the following variables in the /etc/openvpn/easy-rsa/vars file to match your company’s information.

export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

Next, we need to create Diffie-Hellman (DH) Parameters. These are used to provide PKI encryption for our VPN connection.

sudo openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Once complete, we’re going to enter our PKI environment to generate all of the keys that we’ll need for authentication and encryption.

sudo -i
cd /etc/openvpn/easy-rsa/
source vars

When generating future keys, you won’t want to run ./clean-all. Doing so will remove all previously generated keys! To begin generating client keys and certificates, we will first need to create a Certificate Authority (CA) and create keys for our server. Easy RSA has a simple script to make this process easier.


You should be able to simply press enter at all of the prompts as it will pull the values from the vars file that we edited earlier. At the end of the second command, you will have to enter y for the following questions:

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

Next, we’ll need to copy our CA certificate and our VPN server certificate and key to the main OpenVPN directory. We’ll also want to copy the example configuration file from the OpenVPN package. All of the default settings will work just fine, we’ll just want to add one line to the end of the file to enable routing between our Cloud-A network and our client.

cp /etc/openvpn/easy-rsa/keys/{server.*,ca.crt} /etc/openvpn/
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

We’re assuming that you’re using the default private subnet. If not, you will have to replace “” with the subnet that you have configured on Cloud-A.

echo 'push "route"' >> /etc/openvpn/server.conf

Now we can start our VPN service:

systemctl start openvpn@server

NAT Configuration

In order for our VPN server to route traffic to and from our Cloud-A private network to and from our remote clients, we’ll need to setup a simple NAT rule. This will translate traffic between the two networks so that they can communicate. First, we’ll need to make sure that we have the iptables-persistent package so that our firewall rules will persist on boot.

apt-get update && apt-get install -y iptables-persistent

In order to create our NAT rule, we first need to get the name of our network interface. Run ‘ip link’ to view interfaces attached to the instance:

root@openvpn:~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:bb:33:de brd ff:ff:ff:ff:ff:ff

There should only be two interfaces listed, with lo being the loopback interface. In this case, our interface is called ens3. If yours is different, change “ens3” in the next step to match it.

Next, we’ll create our rule and save it:

iptables -t nat -A POSTROUTING -s -o ens3 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4

We’ll also need to enable IP forwarding in the Linux kernel so that our machine will accept packets for destination IP addresses that aren’t assigned to it. To do so, uncomment the following line in /etc/sysctl.conf by removing the leading ‘#’:




And apply the changes:

sysctl -p

Now we’re ready to setup our client configuration.

Client Setup

Now that our server is configured and running, we need to create certificates for our clients to use to connect to the OpenVPN server. By default, OpenVPN only allows one simultaneous connection per certificate, so you’ll want to repeat this process for every device that will be connecting to your VPN. In this example, we’re going to create a certificate for Bob’s laptop.

./build-key bob-laptop

Again, you should be able to accept the default options and enter ‘y’ for the last two prompts. Once the certificate and key have been created, we’ll need to download them as well as the CA certificate to our device. The method used to do this will depend on your operating system, for our purposes we’re going to use the SCP client. If you’re using Windows, you can use Filezilla or WinSCP. SCP transfers files over SSH, meaning that we won’t have to do any additional configuration on our instance.

First, we’re going to zip our key files to make downloading them easier. Then we’ll use SCP to download the zip file to our local Downloads folder. Feel free to change ~/Downloads to something more appropriate on your system.

On your Cloud-A instance:

cd keys
zip ~ubuntu/ bob-laptop.crt bob-laptop.key ca.crt

On the client machine (OS X /  Linux):

scp ubuntu@<PUBLIC_IP>:/home/ubuntu/ ~/Downloads

Now that we have our certificate and key, we’ll need to download OpenVPN on our client device.

Windows download:
Redhat / CentOS: sudo yum install openvpn
Debian / Ubuntu: sudo apt-get install openvpn
Mac OS X: We recommend using Tunnelblick ( You can also download and compile the native client from OpenVPN’s website.

All of these applications will have slightly different configuration directories, however all of them will require the same files: the device’s unique certificate, the device’s unique key file, the VPN server’s CA certificate, and an OpenVPN configuration file. We have already created and downloaded all but the last item.

Let’s unzip our certificates and private key into a folder our home directory. Windows users will want to extract them into C:/Program Files/OpenVPN/config instead. In OS X and Linux, you can do the following:

mkdir ~/clouda_vpn
cd ~/clouda_vpn
unzip ~/Downloads/ 

Next, we’ll want to create an OpenVPN configuration file in the same directory. You can name the file whatever you would like, as long as it ends with the .ovpn file extension. Here are some sample configuration files. Ensure to replace anything encased in “<..>” with the proper values for your setup.

Linux Users:

remote <PUBLIC_IP>
ca /home/<USER>/clouda_vpn/ca.crt
cert /home/<USER>/clouda_vpn/bob-laptop.crt
key /home/<USER>/clouda_vpn/bob-laptop.key
comp-lzo yes
dev tun
proto udp
script-security 2

Mac OS X Users:

remote <PUBLIC_IP>
ca /Users/<USER>/clouda_vpn/ca.crt
cert /Users/<USER>/clouda_vpn/bob-laptop.crt
key /Users/<USER>/clouda_vpn/bob-laptop.key
comp-lzo yes
dev tun
proto udp
script-security 2

Windows users:

remote <PUBLIC_IP>
ca ca.crt
cert bob-laptop.crt
key bob-laptop.key
comp-lzo yes
dev tun
proto udp
script-security 2

Linux users can then connect to their VPN by running the following:

sudo openvpn /home/<USER>/clouda_vpn/<FILENAME>.ovpn

Mac users will want to check the Tunnelblick documentation to complete configuration of their VPN:

The Windows OpenVPN client will automatically pick up the new configuration on (re)start of the application. Connection is as simple as right clicking on the OpenVPN icon in your taskbar, hovering over the name that you gave your .ovpn file and clicking connect.

After connecting, you should now be able to access your Cloud-A network!