Sunday, June 3, 2018

Configuring OpenVPN on AWS EC2

This tutorial focus on configuring OpenVPN on Amazon AWS EC2. We will not be going through the process of creating an Amazon account. For details about Amazon AWS please refer to the main site


We would like to shout-out to Paul Bischoff for his post on "How to make your own free VPN with Amazon Web Services" He has recently updated the post for easy-rsa configuration. He made it easy for installing and configuring easy-rsa. However, we did not follow his openvpn configuration. For configuration we refer to openvpn HOWTO articles.

Create an Instance (Create a Linux Server)

First login to Amazon AWS, then navigate to EC2 Dashboard.  Select Services and EC2.

Once we are in the EC2 we should have the screen below

On the left column select EC2 Dashboard.

We should have the screen similar to below.

Please also note that we can create server in any region we choose. To switch region, please look out for the location at the top right corner next to our userid. Click on the location and select the region we want. Similar EC2 Dashboard will appear.

At EC2 Dashboard, scroll down the main page to display the part on "Create Instance"

Click on Launch Instance. The screen will show various server image for us to choose. See screenshot below:

Select the first image by clicking on Select. The screen will show the details of our selected image. Please note that for new user Amazon provide a 12 month free tier if we do not exceed certain usage limit. The first image is eligible for the free tier.

The screen above show us the CPU capacity and RAM allotment for our server. We can select other server and pay for the usage, for a start, we will stick to the free tier. Please scroll down to configure our security group.

Under Security group name. Enter the security group name. We use mySecurity as the group name. Next click Add Rule and configure the rules as follows:

Type:SSH, Protocol:TCP, Port:22, Source:Anywhere
Type:Custom TCP, Protocol:TCP, Port:943, Source:Anywhere
Type:Custom TCP, Protocol:TCP, Port:443, Source:Anywhere
Type:Custom UDP Protocol:UDP, Port:1194, Source:Anywhere

See screenshot below:

Please note that there will be warning since our source is anywhere. If we want to be able to access the server from anywhere, we should leave the source as anywhere. Click Review & Launch. In the next step, we review all the settings such as image and security group.

Once we are satisfy with the settings, scroll to the end and click Launch.

The next step is to create key pair. Please note that for EC2, we do not login to the server with our Amazon account. We will not be using any account to login the server. We connect to the server using key pair.

Select Create a new key pair and enter the key pair name. Once it is done, click to Download Key Pair. Once the key is with us, please safe keep this key file. we would not be able to login to the server with the key file.

Scroll down and click Launch Instances

The system will response with the launch status as shown below:

Managing Instances

This section briefly discuss, the very basic of managing instance. Please note that if we want to remain in the free tier, there are limits on how many instances we can create. 

First, select Services on the top left corner and select EC2 as shown below:

Once we are in the EC2 we should have the screen below

On the left column select EC2 Dashboard.

EC2 Dashboard is similar to the screen below:

Now, Click on Instances. We should have the screen below:

This instances summary tell us what instances we have are running. Next, we would like to pause and explain a bit about EC2 instances. 

Once important information we need is the IP address. Once an instance is launch, it will be assigned with a public address. We need the ip address to connect to the server.

Under normal tier, every instances contributed to the billing meter. We can reboot the instances. Please note that the billing meter will still be counting when you reboot.

If we stop the instances, the data will not be lost provided we use EBS-backed instances. For normal instance without EBS-backed instance, data will be lost. Only the ip address remains.

However, if we terminate the instances, the billing meter stop. Please note this important fact. Once we terminated the instances, the data, configuration and ip address for the server will be lost.

To manage the instance, select the instance we want and click on Actions:

Under Instance State, we can Stop, Reboot or Terminate.

If we select Stop, the system will warn us the all data will be lost.

If we select Terminate, the system will warn us that all will be lost

Let refrain from stopping or terminating the instance. In the next section, we will be connecting to the instance/server.

Connecting to Instance

In this section, we will be showing how to connect to the server via ssh. Please note that this section is for Mac/Linux user. For Windows user, please refer to the article mentioned at the beginning.

First we copy the file myServerKey.pem to ~/.ssh folder. If we do not have we can just copy to the home drive. After we start a SSH session, a hidden folder will be created in the home drive.

First, open a terminal. 

The follwoing command is to copy the session key to the .ssh folder.
cp ~/Downloads/myServerKey.pem ~/.ssh/

If there is no .ssh folder, use the home folder first. Before the next session, we can copy the file to .ssh folder.
cp ~/Downloads/myServerKey.pem ~

Next, we need to change the permission:
chmod 400 myServerKey.pem

We connect to ssh with:
ssh -i ~/.ssh/myServerKey.pem 
(xxx refers to ip address from our instance summary)

Once the connection is successful, we have the following screen

Next, we would like to prepare the server for openvpn.

Installing OpenVPN and Preparation

Before we start installing openvpn, we need to update the system as follows:
# EC2 maintenance
sudo yum update -y

Next, we install openvpn and easy-rsa
# Install openvpn 
sudo yum install openvpn -y
sudo yum install easy-rsa -y --enablerepo=epel

Next, we would like to create a directory for easy-rsa under /etc/openvpn. This way any configuration will not be lost when there is an update. It is not advisable to store the configuration under /usr/share folder.
# make a direcotry for easy-rsa
sudo mkdir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
sudo cp -rv /usr/share/easy-rsa/3.0.3/* ./

Setup OpenVPN and Generate Keys

To setup openvpn, first we initialize PKI and build the certificate authority:
# Build PKI and CA
sudo ./easyrsa init-pki
sudo ./easyrsa build-ca
Please note that we will be asked to create the password for the CA. It is advisable to create a good and long password.

Next we generate generate a Diffie-Hellman key. This is to provide forward secrecy.
sudo ./easyrsa gen-dh

Next we generate the vpn server certificate. Please create a good password for the server certificate. Please note that for the second command, it will prompt a signing password. We need to use CA PASSWORD FOR SIGNING.
# Generate server cert and signed
# Create a good server password
sudo ./easyrsa gen-req server
# When prompt, use CA password for signing
sudo ./easyrsa sign-req server server

Next, we generate client certificate. Similarly, create a good password for the client certificate. If we are generating the client certificate for family or friends; we may need to ask them to enter the passphrase. Similarly, use CA password for signing certificate.
# Generate client
sudo ./easyrsa gen-req client
sudo ./easyrsa sign-req client client

We can create as many client certificate according to our needs.

Finally for added security we add TLS security by generating a ta.key. This feature is to prevent DDOS attack.
# add TLS security
cd /etc/openvpn
sudo openvpn --genkey --secret ta.key

Copy Keys

We need to copy keys generated to client for connection. For that, we prefer to create a separate folder and park the necessary keys to the folder.

Please note that while preparing the key files, it is easier if we use operate as root.

# *********************************************
# Below is the step to copy key files to a folder for scp

sudo su
cd /etc/openvpn
mkdir keys
cp ta.key keys
cp /etc/openvpn/easy-rsa/pki/dh.pem keys
cp /etc/openvpn/easy-rsa/pki/ca.crt keys
cp /etc/openvpn/easy-rsa/pki/private/ca.key keys
cp /etc/openvpn/easy-rsa/pki/private/client.key keys
cp /etc/openvpn/easy-rsa/pki/issued/client.crt keys
cd keys
chmod 777 *

# ls to confirm
# exit from root
# ************************************************

Please note that all the keys and certificate are necessary for the client to use except one. The key that are not required is ca.key. We copy this key for keep offline since it is not necessary for the server to use this key.

Just a reminder .crt files are public key and .key are private key. If we are working with multiple clients, then we can only give them the appropriate client private key. Clients can have all the crt files. ta.key are for extra security, similar to dh.pem.

# Below is instruction for local machine
# Copy from local machine
scp -i ~/.ssh/myServerKey.pem* ~/localpath/

Finally, we clean up the ca.key and change the permission to the more restrictive one.
# Must only do after ca.key is copied to local machine
sudo rm /etc/openvpn/easy-rsa/pki/private/ca.key
sudo rm /etc/openvpn/keys/ca.key
cd /etc/openvpn/keys
sudo chmod 600 *

Summary we only provide client with the follow:
  • ta.key
  • dh.pem
  • ca.crt
  • client.crt - must be the same certificate create for the user.
  • client.key - must be the same key create for the user.
Please also reminded to safe keep the ca.key.

Setup OpenVPN Server Configuration

We can get a sample server configuration from the openvpn site. Please copy the conf file to /etc/openvpn and use any favorite editor to edit the configuration.

Listed below are the configuration we use:

We add 2 lines as shown below

The following are changes we made or setting we uncomment:
# SSL/TLS root certificate (ca), certificate
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key

# Diffie hellman parameters.
dh /etc/openvpn/easy-rsa/pki/dh.pem

push "redirect-gateway def1 bypass-dhcp"

push "dhcp-option DNS"
push "dhcp-option DNS"

# Enable compression on the VPN link and push the
compress lz4-v2
push "compress lz4-v2"

# You can uncomment this out on
# non-Windows systems.
user nobody
group nobody

The follow are the defaults we use:
port 1194
proto udp
dev tun
ifconfig-pool-persist ipp.txt
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-CBC
status openvpn-status.log
verb 3
explicit-exit-notify 1

Start OpenVPN Server

To start openvpn use the command
sudo service openvpn start

To check the log please refer to /var/logs/messages

Configuring Client

Before we start connecting the vpn session, we need to configure the client file. Copy the sample file from openvpn site.

We add the following line:

We only made changes to the server ipaddress:
# The hostname/IP and port of the server.
remote ip-address-my-server-1 1194

The following are default:
dev tun
proto udp
resolv-retry infinite
#Need to change if keys are in different location
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3

For Mac OS X user, we do not recommend the client software provide by openvpn, instead we recommend to use Tunnelblick. We can get their software at Please follow the site tutorial on how to use tunnelblick. But it is quite intuitive.

For Ubuntu (Debian class) or Red Hat class user,  we can install openvpn using yum or apt-get. After that we can launch the session using the command line

# To connect openvpn vis command line
sudo openvpn --config '/pathToClientConfigFile'
enter client password when asked.

Alternatively, we can also use network manager.

Connecting From Client and Troubleshooting

Now, we can start the session. To test connection, please ping If ping test is successful then we are good to go.

If client failed to make connection, first check the server log to see if openvpn is running.

If server is running well with no error and client still failed to make connection, perhaps we should try to make connection in a public wifi. Try to make connection from different location to see if the problem lies with the firewall.

If connection is successful but we cannot use the browser, then we need to check the DNS settings. Please remember to check the server configuration file.

Update 15 Jun 18

Some Open WiFI Network Do Not Support UDP

When you have established vpn connection on a wifi network, but you could not browse the internet. There are some troubleshooting steps involved.

The first issue is name resolution, so you need to ping the DNS server. If DNS server is reachable, we should clear our DNS cache. Please also check wether we could browse using other browser.

If all ease is fine, there is one possibility that some public wifi disable udp port. In this case we need to reconfigure our server to run on TCP port.

Please note that using TCP port for openvpn will slow down the transmission speed.

For server configuration, we just need to change the proto from udp to tcp. Please also make sure to add a custom TCP rule that open port 1194 in the AWS security group. Very IMPORTANT, please comment out explicit-exit-notify as it is not supported in tcp.

Please also remember to change the client from proto udp to proto tcp