Community Blog How to Create a VPN Server with OpenVPN

How to Create a VPN Server with OpenVPN

In this tutorial, we will show you how to create your own VPN server with OpenVPN.

By Alexandru Andrei, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

In some countries it may be illegal to use a VPN. Please consult the law in your country before proceeding.

Virtual private networks (VPNs) were initially created with the purpose of securely connecting multiple internal networks and/or users over the Internet, constructing a virtual internal network, where authorized entities can access all resources within, as if they were available on-site/locally. By encrypting and authenticating all traffic, unauthorized parties cannot read data packets and cannot join the network. Nothing gets in and nothing gets out, so to speak; everything is contained within a secure bubble. While still being used this way, mostly by companies, nowadays more and more people are using it for another purpose: to encrypt their Internet traffic and hide their location (IP address), mostly for privacy reasons, but also for securing sensitive information when connecting from public places or bypassing firewalls and/or restrictions such as geo-blocking.

Over the Internet, data is passed along from machine to machine, until it reaches its destination. It is a relaying network that routes data packets, in a similar way to how paper mail travels in the real world, passing from post office to post office, until it reaches its destinatary. And just like with real mail, the problem is that anyone can read it along the way, because by default, data packets are unencrypted (the problem has been solved partially in the last years with encryption done at application level, e.g. HTTPS, TLS, etc). For example, if you go to a public place and connect to their Wi-Fi, then visit a site which has an address that starts with http:// and not https://, then your data leaves your device unencrypted. As packets travel across the networks, someone could steal an username and password that you have entered to log in to that site. A common technique that is easy to employ is called packet sniffing. In certain conditions, internal network traffic can be sniffed (captured, read and/or collected) by anyone on that network. This means that one customer in a hotel may be able to see every data packet that comes and goes to and from everyone else staying at that hotel, and using the same network. By using a VPN, you can block these attacks, since packets are encrypted before leaving your device.

There are a lot of businesses on the Internet that offer VPN services but creating your own server has several advantages. A public VPN provider usually squeezes tens (or even hundreds) of users on the same computing instance. This (over)sharing of resources can lead to inconsistent performance, limited bandwidth and sometimes even downtime. Besides improving the quality of service (and possibly even security), creating your own OpenVPN server also gives you total control over every setting and certainty that your browsing history isn't being logged and sold to advertising companies. In some cases it may even help avoid being blocked by some sites or game servers, which automatically block any incoming traffic from publicly known commercial VPN IP addresses.


Log in to the ECS Cloud Console, create a new instance and choose Debian 9 as your Linux distribution. If you can't find Debian 9 in the drop-down list, you have to change the instance type. For example, at the time of writing, on an "ecs.t5-lc2m1.nano" only Debian 8.9 is available, which is too old. 1GB of RAM will suffice.

"Subscription" as a billing method instead of "Pay-As-You-Go", allows setting higher network bandwidth limits (200 Megabits/second instead of 100Mb). Don't forget to adjust the slider according to your needs. A higher packet forwarding rate will give you higher network transfer rates. If you notice that connecting through the VPN server slows down your connection too much, you can upgrade your instance type later on.

As you create your instance, in the step where you setup networking parameters, you will come across this section:


Create a security group and add a rule to allow ingress connections on port 1194 UDP and on TCP, port 22 (SSH). Adding a "Quick Rule" is the easiest way to do this. Picture is attached below with the data you need to fill out.


You can also add a rule to allow "All ICMP" if you want to be able to ping your server.

After you finish adding rules, go back to the instance configuration page and click on "Reselect Security Group" to attach and apply the settings to the instance.

Launch your instance, connect to it with an SSH client and log in as root.

Install OpenVPN

Update package manager information and apply all available upgrades:

    apt update && apt upgrade

If you encounter the following text user interface dialog box:


Press ENTER to select the default answer, "keep the local version currently installed".

Reboot the instance:

    systemctl reboot

Wait 15-30 seconds and then log back in as root.

Install OpenVPN and easy-rsa:

    apt install openvpn easy-rsa

Public Key Infrastructure and Certificate Authorities

The public key infrastructure is too complex to describe in a short tutorial section. But it's important to understand how it's useful for OpenVPN. easy-rsa is a package that allows us to create our own certificate authority. Through clever cryptographic algorithms this facilitates the generation of unique certificates and signatures that cannot be forged by those without access to a set of secrets (usually in the form of private keys). With the help of these certificates we can encrypt, decrypt, authenticate, sign, verify signatures, actions meant to ensure secure communication and trust between parties (in our case, between client and server). The OpenVPN server will only allow clients with valid certificates to connect to it. Furthermore, it will encrypt data in such a way, that only the client that owns that certificate can decrypt it. By checking signatures and fingerprints, clients can also validate the authenticity of the server they are connecting to. This helps avoid attacks such as "man in the middle", where the connection gets hijacked and re-routed through an intermediary, which could then intercept and manipulate network traffic.

Users that only need to encrypt their Internet traffic when they connect from public places, and protect themselves from casual amateur attackers, don't need to employ advanced means of securing their certificate authority data. But those facing powerful adversaries that might be more motivated and advanced in the ability to compromise a server, steal cryptographic secrets and possibly then use the data to impersonate the OpenVPN instance, should take careful measures to protect their certificate authority data.

For the sake of simplicity, we will configure the certificate authority on the same server, but if you find yourself in the above mentioned situation, then you should learn more about the secrets that need to be protected in a public key infrastructure and keep them on a separate, reasonably secure computer, preferably password encrypted and isolated from the Internet. You should generate your certificate authority on such an isolated environment, create and sign certificates as needed and export the public components only when you have to distribute them (for example client certificates that you can import on your laptop or phone, to be able to connect to the VPN server).

Create a Certificate Authority

Create the "ca" directory and copy the easy-rsa tools there:

    make-cadir ca

Step into that directory:

    cd ca

Edit the vars file:

    nano vars

Scroll down until you reach these lines:

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

Edit them as you see fit. The values can be fictional if you desire.

Press CTRL+X to exit nano, Y to save the file, followed by ENTER.

Link the config file to an alternate file name (some scripts will complain if they cannot find this file):

    ln -s openssl-1.0.0.cnf openssl.cnf

Source the var file to set the appropriate environment variables:

    source vars

Generate a clean environment:


Generate certificate authority data:


You can press ENTER at the prompts to select the pre-filled values.

Generate Server and Client Certificates and Keys

Build a certificate for the VPN server:

    ./build-key-server server

Press ENTER to select default answers but pay attention to the last two questions "Sign the certificate? [y/n]:" and "1 out of 1 certificate requests certified, commit? [y/n]" and answer with "y" otherwise the certificate won't be signed and validated.

Generate Diffie-Hellman parameters:


Warning: Two methods of generating a key will be explained below. Pick just one out of these two. Running both commands (with the same key name, "client1") would invalidate the certificate.

  1. Generate client key (we'll name it client1 here) and just like above, be careful to answer with "y" to the last two questions to sign the certificate:
        ./build-key client1

    This key will be imported to the phones/computers that we want to authorize to connect to the OpenVPN server. If you'll be generating multiple keys for multiple devices, you can choose descriptive names such as "iphone", "homepc", "worklaptop" for easier administration later on.

  2. If you want to password protect the key, you can generate it with an alternate command:
        ./build-key-pass client1

Copy required certificates and keys to OpenVPN's configuration directory:
cp keys/server.crt /etc/openvpn/
cp keys/server.key /etc/openvpn/
cp keys/ca.crt /etc/openvpn/
cp keys/dh2048.pem /etc/openvpn/

Configure the OpenVPN Server

Extract the template configuration file:

    zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Start editing the file:

    nano /etc/openvpn/server.conf

Scroll down until you find:

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
;push "redirect-gateway def1 bypass-dhcp"

Uncomment the last line by deleting the leading ";". The final result should look like this:

push "redirect-gateway def1 bypass-dhcp"

Then in the next block:

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses.  CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
# The addresses below refer to the public
# DNS servers provided by opendns.com.
;push "dhcp-option DNS"
;push "dhcp-option DNS"

Uncomment the last two lines:

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

Scroll further down to:

# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
# You can uncomment this out on
# non-Windows systems.
;user nobody
;group nogroup

We're on Linux so we can uncomment the last two lines:

user nobody
group nogroup

Exit nano and save the changes.

Enable HMAC to ensure data integrity (make sure data hasn't been modified in transit by man in the middle type of attack):

    echo -e '\n#Enable HMAC\nauth SHA256' >> /etc/openvpn/server.conf

Generate a key that will be used by HMAC:

    openvpn --genkey --secret /etc/openvpn/ta.key

Start the OpenVPN server process:

    systemctl start openvpn@server

Configure the Server to Route Our Internet Packets

The OpenVPN server will act as an intermediary between our client devices and the rest of the Internet. For it to be able to do this, we need to enable a few things such as IP forwarding:

    echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/local.conf

Now apply the new setting:

    sysctl --system

A technique known as "masquerading" also has to be configured for network address translation to work. For this, we first have to find out what is the name of the device that currently routes packets:

    ip route

This will show that the default route goes through "dev eth0". Let's configure network address translation through eth0:

    iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE

Forwarding traffic for anyone on the network opens the door for possible abuses. Let's limit forwarding only to packets that come through the VPN tunnel (presumably whoever/whatever goes through the tunnel is authorized and authenticated).

iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -s -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -j REJECT

But these settings would be lost after a reboot. Let's make them persistent:

    apt install iptables-persistent

When prompted to "Save current IPv4 rules?", select the default answer "Yes". IPv6 rules are irrelevant since we are not using it so you should answer "No".

Generate Client Profiles (.ovpn Files)

".ovpn" files will contain all the required information (settings, keys and certificates) to connect to the OpenVPN server. Create the directory where these files will be stored:

    mkdir clientprofiles

Copy a template config file:

    cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf clientprofiles/client1.ovpn

Start editing the file:

    nano clientprofiles/client1.ovpn

Scroll down and find the following text:

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote my-server-1 1194
;remote my-server-2 1194

Replace the first occurence of "my-server" with the external (Internet) IP address of your server. You will find it in your Alibaba ECS console by going to the "Instances" view from the left side menu.

The final result could look like this (this is just an example, DO NOT USE THIS IP IN YOUR CONFIG FILE):

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote 1194
;remote my-server-2 1194

Scroll down until you find:

# 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

Comment the last three lines by adding a preceding ";". This would be the end result:

# 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

Those lines indicate the path to the certificate and key files. We will be adding these inside our .ovpn file. This makes transferring .ovpn profiles much easier since we'll have to deal with just one file instead of a profile file and three additional files for each client.

Save the file and exit.

Enable HMAC in the client configuration:

    echo -e '\n#Enable HMAC\nauth SHA256' >> clientprofiles/client1.ovpn

Add the key to the OpenVPN client profile. Copy and paste all three lines at once to avoid accidentally introducing spacing/formatting mistakes.

echo "<key>
`cat keys/client1.key`
</key>" >> clientprofiles/client1.ovpn

Add the client certificate:

echo "<cert>
`cat keys/client1.crt`
</cert>"  >> clientprofiles/client1.ovpn

Add the CA certificate:

echo "<ca>
`cat keys/ca.crt`
</ca>" >> clientprofiles/client1.ovpn

And finally, add the TLS key:

echo "<tls-auth>
`cat /etc/openvpn/ta.key`
</tls-auth>" >> clientprofiles/client1.ovpn

Now, use an SFTP client such as WinSCP to copy the file client1.ovpn to your local computer. You can find instructions on how to use WinSCP on Windows, here.

Finally, download an OpenVPN client for your platform and import the ".ovpn" configuration file to the application. In the following link, you can read a tutorial about how to use the OpenVPN GUI Client on Windows. If you use a different platform, such as macOS, or a mobile operating system, such as Android or iOS, read through the next section.

Useful Links and Recommendations

On an Android device, you can use an app called "OpenVPN Connect" which you can search for in your Play Store. The webpage for the application can be found here: https://play.google.com/store/apps/details?id=net.openvpn.openvpn

The OpenVPN client for macOS can be found here: https://openvpn.net/vpn-server-resources/connecting-to-access-server-with-macos/

For iOS devices, look for "OpenVPN Connect" on your Apple App Store. You can find the webpage for this app, here: https://apps.apple.com/app/openvpn-connect/id590379981

Linux users should install the openvpn package through their package manager. Make sure to also install the resolvconf package, otherwise your DNS servers won't change in your network settings when you connect to your OpenVPN server.

OpenVPN documentation: https://openvpn.net/community-resources/

Check for possible privacy leaks: https://ipleak.net/. You should consult this page before connecting to your VPN server and also after. DNS servers should be different. Also pay attention to the WebRTC section which shouldn't reflect your internal IP address. If you have WebRTC leaks, you have to read the documentation of your browser on how to disable that.

Important: On Windows you should add "block-outside-dns" to the .ovpn config file to stop some possible DNS leaks. Windows 10 has been known to cause some problems (search Google for "windows 10 dns resolver leak" to learn more). Instructions on how to do this have been included in the tutorial titled "How to Use the OpenVPN GUI Client on Windows" which has been included in the last link from the previous section.

It's recommended you setup unattended-upgrades on your Debian server so that the operating system automatically fetches and applies security patches. Also, occasionally reboot your server to apply any possible kernel bug/security fixes. You can find a tutorial on how to setup unattended-upgrades, here. Keep in mind, however, that the ssmtp client has been removed, starting with Debian 10. Setting up unattended-upgrades to send emails after each upgrade is optional. The service is very reliable and usually doesn't require user intervention and/or monitoring. If you do want the emails though, you should look for an alternate simple SMTP client that can forward emails through your favorite email provider.

If you want to install an OpenVPN server on CentOS you can consult the following link: https://www.alibabacloud.com/help/faq-detail/42521.html

0 0 0
Share on

Alibaba Clouder

2,628 posts | 706 followers

You may also like