
How To Set Up an OpenVPN Server on Ubuntu 16.04
Introduction
How to set up your free VPN on ubuntu 16.04? Want to access the Internet safely and securely from your smartphone or laptop when connected to an untrusted network such as the WiFi of a hotel or coffee shop? A Virtual Private Network (VPN) allows you to traverse untrusted networks privately and securely as if you were on a private network. The traffic emerges from the VPN server and continues its journey to the destination.
When combined with HTTPS connections, this setup allows you to secure your wireless logins and transactions. You can circumvent geographical restrictions and censorship, and shield your location and any unencrypted HTTP traffic from the untrusted network.
OpenVPN is a full-featured open source (free vpn) Secure Socket Layer (SSL) VPN solution that accommodates a wide range of configurations. In this tutorial, we’ll set up an OpenVPN server on a Droplet and then configure access to it from Windows, OS X, iOS and Android. This tutorial will keep the installation and configuration steps as simple as possible for these setups.
Note: If you plan to set up an free vpn (OpenVPN) server on a DigitalOcean Droplet, be aware that we, like many hosting providers, charge for bandwidth overages. For this reason, please be mindful of how much traffic your server is handling.
See this page for more info.
Prerequisites
To complete this tutorial, you will need access to an Ubuntu 16.04 server.
You will need to configure a non-root user with sudo
privileges before you start this guide. You can follow our Ubuntu 16.04 initial server setup guide to set up a user with appropriate permissions. The linked tutorial will also set up a firewall, which we will assume is in place during this guide.
When you are ready to begin, log into your Ubuntu server as your sudo
user and continue below.
Step 1: Install OpenVPN
To start off, we will install OpenVPN (free vpn) services onto our server. OpenVPN is available in Ubuntu’s default repositories, so we can use apt
for the installation. We will also be installing the easy-rsa
package, which will help us set up an internal CA (certificate authority) for use with our VPN.
To update your server’s package index and install the necessary packages type:
sudo apt-get update
sudo apt-get install openvpn easy-rsa
The needed software is now on the server, ready to be configured.
Step 2: Set Up the CA Directory
OpenVPN is an TLS/SSL VPN and is also free vpn to use. This means that it utilizes certificates in order to encrypt traffic between the server and clients. In order to issue trusted certificates, we will need to set up our own simple certificate authority (CA).
To begin, we can copy the easy-rsa
template directory into our home directory with the make-cadir
command:
make-cadir ~/openvpn-ca
Move into the newly created directory to begin configuring the CA:
cd ~/openvpn-ca
Step 3: Configure the CA Variables
To configure the values our CA will use, we need to edit the vars
file within the directory. Open that file now in your text editor:
nano vars
Inside, you will find some variables that can be adjusted to determine how your certificates will be created. We only need to worry about a few of these.
Towards the bottom of the file, find the settings that set field defaults for new certificates. It should look something like this:
. . .
export KEY_COUNTRY="US" export KEY_PROVINCE="CA" export KEY_CITY="SanFrancisco" export KEY_ORG="Fort-Funston" export KEY_EMAIL="[email protected]" export KEY_OU="MyOrganizationalUnit"
. . .
Edit the values in red to whatever you’d prefer, but do not leave them blank:
. . .
export KEY_COUNTRY="US" export KEY_PROVINCE="NY" export KEY_CITY="New York City" export KEY_ORG="DigitalOcean" export KEY_EMAIL="[email protected]" export KEY_OU="Community"
. . .
While we are here, we will also edit the KEY_NAME
value just below this section, which populates the subject field. To keep this simple, we’ll call it server
in this guide:
export KEY_NAME="
server"
When you are finished, save and close the file.
Step 4: Build the Certificate Authority
Now, we can use the variables we set and the easy-rsa
utilities to build our certificate authority.
Ensure you are in your CA directory, and then source thevars
file you just edited:cd ~/openvpn-ca
source vars
You should see the following if it was sourced correctly:
Output
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/sammy/openvpn-ca/keys
Make sure we’re operating in a clean environment by typing:
./clean-all
Now, we can build our root CA by typing:
./build-ca
This will initiate the process of creating the root certificate authority key and certificate. Since we filled out the vars
file, all of the values should be populated automatically. Just press ENTER through the prompts to confirm the selections
Output Generating a 2048 bit RSA private key ........................................................... ...............................+++ ...............................+++ writing new private key to ' ca.key' -----
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank.
Country Name (2 letter code) [US]: State or Province Name (full name) [NY]: Locality Name (eg, city) [New York City]: Organization Name (eg, company) [DigitalOcean]: Organizational Unit Name (eg, section) [Community]: Common Name (eg, your name or your server's hostname) [DigitalOcean CA]: Name [server]: Email Address [[email protected]]:
We now have a CA that can be used to create the rest of the files we need.

Step 5: Create the Server Certificate, Key, and Encryption Files
Next, we will generate our server certificate and key pair, as well as some additional files used during the encryption process.
Start by generating the OpenVPN server certificate and key pair. We can do this by typing:
Note: If you choose a name other than server
here, you will have to adjust some of the instructions below. For instance, when copying the generated files to the /etc/openvpn
directroy, you will have to substitute the correct names. You will also have to modify the /etc/openvpn/server.conf
file later to point to the correct .crt
and .key
files.
./build-key-server server
Once again, the prompts will have default values based on the argument we just passed in (server
) and the contents of our vars
file we sourced.
Feel free to accept the default values by pressing ENTER. Do not enter a challenge password for this setup. Towards the end, you will have to enter y to two questions to sign and commit the certificate:
Output
. . .
Certificate is to be certified until May 1 17:51:16 2026 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Next, we’ll generate a few other items. We can generate a strong Diffie-Hellman keys to use during key exchange by typing:
./build-dh
This might take a few minutes to complete.
Afterwards, we can generate an HMAC signature to strengthen the server’s TLS integrity verification capabilities:
openvpn --genkey --secret keys/ta.key
Step 6: Generate a Client Certificate and Key Pair
Next, we can generate a client certificate and key pair. Although this can be done on the client machine and then signed by the server/CA for security purposes, for this guide we will generate the signed key on the server for the sake of simplicity.
We will generate a single client key/certificate for this guide, but if you have more than one client, you can repeat this process as many times as you’d like. Pass in a unique value to the script for each client.
Because you may come back to this step at a later time, we’ll re-source the vars
file. We will use client1
as the value for our first certificate/key pair for this guide.
To produce credentials without a password, to aid in automated connections, use the build-key
command like this:
cd ~/openvpn-ca
source vars
./build-key client1
Again, the defaults should be populated, so you can just hit ENTER to continue. Leave the challenge password blank and make sure to enter y for the prompts that ask whether to sign and commit the certificate.
Step 7: Configure the OpenVPN Service
Next, we can begin configuring the OpenVPN service using the credentials and files we’ve generated.
Copy the Files to the OpenVPN Directory
To begin, we need to copy the files we need to the /etc/openvpn
configuration directory.
We can start with all of the files that we just generated. These were placed within the ~/openvpn-ca/keys
directory as they were created. We need to move our CA cert, our server cert and key, the HMAC signature, and the Diffie-Hellman file:
cd ~/openvpn-ca/keys sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
Next, we need to copy and unzip a sample OpenVPN configuration file into configuration directory so that we can use it as a basis for our setup:
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
Adjust the OpenVPN Configuration
Now that our files are in place, we can modify the server configuration file:
sudo nano /etc/openvpn/server.conf
Basic Configuration
First, find the HMAC section by looking for the tls-auth
directive. Remove the “;” to uncomment the tls-auth
line. Below this, add the key-direction
parameter set to “0”:
tls-auth ta.key 0 # This file is secret
key-direction 0
Next, find the section on cryptographic ciphers by looking for the commented out cipher
lines. The AES-128-CBC
cipher offers a good level of encryption and is well supported. Remove the “;” to uncomment the cipher AES-128-CBC
line:
cipher AES-128-CBC
Below this, add an auth
line to select the HMAC message digest algorithm. For this, SHA256
is a good choice:
auth SHA256
Finally, find theuser
andgroup
settings and remove the ";" at the beginning of to uncomment those lines:
user nobody
group nogroup
The settings above will create the VPN connection between the two machines, but will not force any connections to use the tunnel. If you wish to use the VPN to route all of your traffic, you will likely want to push the DNS settings to the client computers.
You can do this, uncomment a few directives that will configure client machines to redirect all web traffic through the VPN. Find the redirect-gateway
section and remove the semicolon “;” from the beginning of the redirect-gateway
line to uncomment it:
push "redirect-gateway def1 bypass-dhcp"
Just below this, find the dhcp-option
section. Again, remove the “;” from in front of both of the lines to uncomment them:
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
This should assist clients in reconfiguring their DNS settings to use the free VPN tunnel for as the default gateway.
Step 8: Adjust the Server Networking Configuration
Next, we need to adjust some aspects of the server’s networking so that OpenVPN can correctly route traffic.
Allow IP Forwarding
First, we need to allow the server to forward traffic. This is fairly essential to the functionality we want our VPN server to provide.
We can adjust this setting by modifying the /etc/sysctl.conf
file:
sudo nano /etc/sysctl.conf
Inside, look for the line that sets net.ipv4.ip_forward
. Remove the “#” character from the beginning of the line to uncomment that setting:
Adjust the UFW Rules to Masquerade Client Connections
If you followed the Ubuntu 16.04 initial server setup guide in the prerequisites, you should have the UFW firewall in place. Regardless of whether you use the firewall to block unwanted traffic (which you almost always should do), we need the firewall in this guide to manipulate some of the traffic coming into the server. We need to modify the rules file to set up masquerading, an iptables
concept that provides on-the-fly dynamic NAT to correctly route client connections.
Before we open the firewall configuration file to add masquerading, we need to find the public network interface of our machine. To do this, type:
ip route | grep default
Your public interface should follow the word “dev”. For example, this result shows the interface named ens4
, which is highlighted below:
Output :
default via 203.0.113.1 dev wlp11s0 proto static metric 600
When you have the interface associated with your default route, open the /etc/ufw/before.rules
file to add the relevant configuration:
sudo nano /etc/ufw/before.rules
This file handles configuration that should be put into place before the conventional UFW rules are loaded. Towards the top of the file, add the highlighted lines below. This will set the default policy for the POSTROUTING
chain in the nat
table and masquerade any traffic coming from the VPN:
Note: Remember to replace ens4
in the -A POSTROUTING
line below with the interface you found in the above command.
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
# ufw-before-input
# ufw-before-output
# ufw-before-forward
#
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to ens4 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o ens4 -j MASQUERADE
COMMIT
# END OPENVPN RULES
# Don't delete these required lines, otherwise there will be errors
*filter
. . .
we and close the file when you are finished.
We need to tell UFW to allow forwarded packets by default as well. To do this, we will open the /etc/default/ufw
file:
sudo nano /etc/default/ufw
Inside, find the DEFAULT_FORWARD_POLICY
directive. We will change the value from DROP
to ACCEPT
:
DEFAULT_FORWARD_POLICY="ACCEPT"
Save and close the file when you are finished.
Open the OpenVPN Port and Enable the Changes
Next, we’ll adjust the firewall itself to allow traffic to OpenVPN.
If you did not change the port and protocol in the /etc/openvpn/server.conf
file, you will need to open up UDP traffic to port 1194. If you modified the port and/or protocol, substitute the values you selected here.
We’ll also add the SSH port in case you forgot to add it when following the prerequisite tutorial:
sudo ufw allow 1194/udp sudo ufw allow OpenSSH
Now, we can disable and re-enable UFW to load the changes from all of the files we’ve modified:
sudo ufw disable sudo ufw enable
Our server is now configured to correctly handle OpenVPN traffic.
Step 9: Start and Enable the OpenVPN Service
We’re finally ready to start the free vpn service on our server. We can do this using systemd.
We need to start the OpenVPN server by specifying our configuration file name as an instance variable after the systemd unit file name. Our configuration file for our server is called /etc/openvpn/server.conf
, so we will add @server
to end of our unit file when calling it:
sudo systemctl start [email protected]server
Double-check that the service has started successfully by typing:
sudo systemctl status [email protected]
You can also check that the OpenVPN tun0
interface is available by typing:
ip addr show tun0 sudo systemctl enable [email protected]
Step 10: Create Client Configuration Infrastructure
Next, we need to set up a system that will allow us to create client configuration files easily.
Creating the Client Config Directory Structure
Create a directory structure within your home directory to store the files:
mkdir -p ~/client-configs/files
Since our client configuration files will have the client keys embedded, we should lock down permissions on our inner directory:
chmod 700 ~/client-configs/files
Creating a Base Configuration
Next, let’s copy an example client configuration into our directory to use as our base configuration:
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf Open this new file in your text editor: nano ~/client-configs/base.conf Inside, we need to make a few adjustments.
First, locate the remote
directive. This points the client to our free vpn server address. This should be the public IP address of your OpenVPN server. If you changed the port that the OpenVPN server is listening on, change 1194
to the port you selected:
. . .
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote server_IP_address 1194
. . .
Be sure that the protocol matches the value you are using in the server configuration:
proto udp
Next, uncomment the user
and group
directives by removing the “;“:
# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup
Find the directives that set the ca
, cert
, and key
. Comment out these directives since we will be adding the certs and keys within the file itself:
# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
#ca ca.crt
#cert client.crt
#key client.key
Mirror the cipher
and auth
settings that we set in the /etc/openvpn/server.conf
file:
cipher AES-128-CBC
auth SHA256
Next, add the key-direction
directive somewhere in the file. This must be set to “1” to work with the server:
key-direction 1
Finally, add a few commented out lines. We want to include these with every config, but should only enable them for Linux clients that ship with a /etc/openvpn/update-resolv-conf
file. This script uses the resolvconf
utility to update DNS information for Linux clients.
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
If your client is running Linux and has an /etc/openvpn/update-resolv-conf
file, you should uncomment these lines from the generated free vpn OpenVPN client configuration file.
Save the file when you are finished.
Creating a Configuration Generation Script
Next, we will create a simple script to compile our base configuration with the relevant certificate, key, and encryption files. This will place the generated configuration in the ~/client-configs/files
directory.
Create and open a file called make_config.sh
within the ~/client-configs
directory:
nano ~/client-configs/make_config.sh
Inside, paste the following script:
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
Save and close the file when you are finished.
Mark the file as executable by typing:
chmod 700 ~/client-configs/make_config.sh
Step 11: Generate Client Configurations
Now, we can easily generate client configuration files.
If you followed along with the guide, you created a client certificate and key called client1.crt
and client1.key
respectively by running the ./build-key client1
command in step 6. We can generate a config for these credentials by moving into our ~/client-configs
directory and using the script we made:
cd ~/client-configs
./make_config.sh client1
If everything went well, we should have a client1.ovpn
file in our ~/client-configs/files
directory:
ls ~/client-configs/files
Output
client1.ovpn
Your done for installation free vpn in your server. Congratulations!!
Most complete of general code of how to set up is by Digital Ocean.
Thank You Very Much ~
No Comments