Configuring OpenVPN on AWS EC2 (Update: Jun 2019)

Update Jun 2019

The installation procedure listed below works. However, iOS user may encounter issues while surfing the net when VPN is connected.

To resolved this issue, we need to disable compression as it has been decided that compression is unsecure.

Please follow the steps below:

  • Remove any compression settings in the server configuration file by adding ; infront of the settings.

# disable compression as it is unsecure
;compress lz4-v2
;push "compress lz4-v2"
  • At openVPN Connect app in iOS, please ensure that compression is disabled.
We have updated the server configuration file.


Update Aug 2018

When we configure OpenVPN on AWS few months back, OpenVPN is still in the Amazon repo. However, if we start a new instances now, we would not be able to install OpenVPN. Therefore, we need to configure epel as additional repo and install OpenVPN from CentOS. Using epel repo, we managed to installed the latest version of OpenVPN (2.4.6).  Please note that the configuration is quite different. New OpenVPN uses systemd instead of chkconfig. 

If you are still using old AWS image or you are using old version of OpenVPN, this post is not for you. Please check out our older post  Configuring OpenVPN on AWS EC2.

This post is for those who are using the latest AWS AMI image and OpenVPN version 2.4.6.

Security Update Dec 2018

There is a security hack on OpenVPN where attacker can make use of compression option to carry out the attack.

TLDR, for better security, we should disable compression.

For details please refer to the page below:
https://community.openvpn.net/openvpn/wiki/VORACLE


Creating and Starting AWS Instance

We would not be going through the process of starting the instance. Please check out our previous post Configuring OpenVPN on AWS EC2. Alternatively, you can also checkout Amazon AWS tutorial on Launch a Linux Virtual Machine.


Connecting to Instance

In this section, we will be connecting to the server via ssh. First, we move the key file to ssh folder:

mv ~/Downloads/myServerKey.pem ~/.ssh/

If there is no .ssh folder, use the home folder first. 

cp ~/Downloads/myServerKey.pem ~

Next, we need to change the permission:

chmod 400 myServerKey.pem

We connect to ssh with the command:

ssh -i ~/.ssh/myServerKey.pem ec2-user@xxx.xxx.xxx.xxx
# (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, try to install OpenVPN using the command below. 

# Install openvpn try 
sudo yum install openvpn -y
sudo yum install easy-rsa -y --enablerepo=epel

If it works, please skip the next section of configuring epel repo. Otherwise, please continue to configure epel repo.
To configure the latest epel repo using the following command:

# If we cannot install openvpn configure epel for centos 7
# we believe AMI it is base on centos 7
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
Next, we would like to update the system first before installing openvpn and easy-rsa:

# After install epel perform system update and install openvpn
sudo yum update -y
sudo yum install openvpn -y
sudo yum install easy-rsa -y

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

This section of setting up keys remains the same. 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 will generate a Diffie-Hellman key. This is to provide forward secrecy.

sudo ./easyrsa gen-dh

Next we generate the vpn server certificate. Usually, we do not encrypt and lock the server private key. We will not use any password to encrypt the server key. Using no password, the server key does not required unlocking every time the server boots up. 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 no pass version
sudo ./easyrsa gen-req server nopass
# When prompt, use CA password for signing
sudo ./easyrsa sign-req server server

Next, we generate client certificate. 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. The syntax of the command on creating client certificate is as follows:

sudo ./easyrsa gen-req <filename>
sudo ./easyrsa sig-req client <filename>

Note: We need to substitute <filename> with a name of our choice.

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
exit
# ************************************************

Please note that all the keys and certificate are necessary for the client to use except one key. The key that are not required is ca.key. We copy this key for safe keeping 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 ec2-user@xxx.xxx.xxx.xxx:/etc/openvpn/keys/* ~/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 *

In summary, we only provide each client with the follow:
  • ta.key
  • dh.pem
  • ca.crt
  • client.crt - must be the same certificate create for the same user.
  • client.key - must be the same key create for the same user.
On the client side, please also make sure that the key files are secured with permission a 400 or 600. Please also reminded to safe keep ca.key.

Setup OpenVPN Server Configuration

We can get a sample server configuration from the openvpn site. It is easier to copy the config file from the server.

IMPORTAT CHANGED: Please note that we no longer place the config file server.conf on /etc/openvpn. Instead we will be keeping under root folder /etc/openvpn/server. 

Use the following command to copy the sample:

cd /usr/share/doc/openvpn-2.4.7/sample/sample-config-files
sudo cp server.conf /etc/openvpn/server/

To configure the server file using the command

#### Configure server file
sudo nano /etc/openvpn/server/server.conf


Listed below are the configuration we use:

IMPORTANT CHANGED: Please note that for tls-auth no longer work. Please use tls-crypt instead.

IMPORTANT CHANGED: Remove all compression related settings. By default compression is disabled. Please do not enabled them

We add line as shown below

auth-nocache

The following are changes we made or setting we uncomment:

# We set the protocol to TCP as some firewall block UDP.
proto tcp

# 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 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

# tls-auth no longer worked
# Please also provide full path of ta key
tls-crypt /etc/openvpn/ta.key 0 # This file is secret

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

# We need to command out the following
# This is for udp, to use tcp, this must be disabled.
#explicit-exit-notify 1


The follow are the defaults we use:

port 1194
dev tun
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
status openvpn-status.log
verb 3


Start OpenVPN Server

IMPORTANT CHANGE: Please note that OpenVPN server start to use systemd for services.

To start openvpn use the command:

# Use the following command to start server
sudo systemctl start openvpn-server@server.service
# server.service: the name server is the name of .conf file
# If foo.conf is the config file command will be
# sudo systemctl start openvpn-server@foo.service

To check if the server is running use the command:

# Use the following command to check server status
sudo systemctl status -l openvpn-server@server.service
To start server on boot, use the command:

# Use the following command to enable server on boot
sudo systemctl enable openvpn-server@server.service
If error occurs, use the command to check for errors:
# If error occurs use the following command to check for error
journalctl -xe
We can also check for error log at /var/logs/messages


Configure IP Routing 

We also need to configure ip routing. Create a shell script file with the following command:


sudo nano /etc/openvpn/iproute.sh

Please copy the code below to the script file:

###############################################################################
# Copy the section below on the script iproute.sh
###############################################################################
#!/bin/sh
# chkconfig: 345 99 10
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
sudo iptables -t nat -A POSTROUTING -s 10.4.0.1/2 -o eth0 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
###############################################################################


Once the shell script is done, we need to change the permission of the file to executable. Use the command below:
sudo chmod +x iproute.sh


Once the shell script is done, we can test the script using the command below:

sudo ./iproute.sh


To make the script run every reboot, we need to create a service. Use the step as follows:

Step 1: Create a service file using the command:

sudo nano /etc/systemd/system/iproute.service

Step 2: Copy the following section to the service file:

#########################################
# Enter the following section on the file
#########################################
[Unit]
Description=iproute

[Service]
ExecStart=/bin/bash /etc/openvpn/iproute.sh

[Install]
WantedBy=multi-user.target
#########################################

Step 3: Use the following command to start and enable the service:

sudo systemctl start iproute.service
sudo systemctl status -l iproute.service
sudo systemctl enable iproute.service


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:

auth-nocache

We need to made changes to the following:

# The hostname/IP and port of the server.
remote ip-address-my-server-1 1194

# Use tcp for vpn
proto tcp

# tls-auth no longer work
# tls-auth ta.key 1
tls-crypt ta.key 1

#Need to change if keys are in different location
ca ca.crt
cert client.crt
key client.key

The following are default:

client
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
verb 3

For Mac OS X user, we recommend Tunnelblick. We can get their software at https://tunnelblick.net/. 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 10.8.0.1. 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. The most common error is the location of all the keys.

If server is running well with no error, but the client is still not able to connect; then disable tls-auth. Comment them out. Please note that tls-auth is not working for some version of OpenVPN, use tls-crypt instead.

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 and IP routing. Please check port forwarding is correct. Please also check if IP routing command is for the correct interface. Make sure eth0 or wlan0 is the correct interface name. Please remember to check the server configuration file.


***




Comments

Popular posts from this blog

Revive Old Mac Mini (2009) with Linux

Configure Unattended Upgrades on Raspberry Pi

Install and Configure RealVNC in Linux Ubuntu 18.04 LTS