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.

Prerequisites

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:

28cadcb46a256a1547fc23c59b4c1992_c4d572f403947f94578278ceccb5d68e6e2f7dd6.png

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_COUNTRY="US"
export KEY_PROVINCE="CA"
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:

./clean-all

Generate certificate authority data:

./build-ca

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:

./build-dh

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.

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.

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 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"
Uncomment the last two lines:

push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
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 10.8.0.0/24 -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 10.8.0.0/24 -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 203.0.113.2 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 you can use a SFTP client such as WinSCP to copy the file client1.ovpn to your local computer.

To login with an SSH user and password: https://winscp.net/eng/docs/guide_connect. You will enter the IP address of your server under "Host name".

To login with SSH keys: https://winscp.net/eng/docs/guide_public_key.

Then download an OpenVPN client for your platform and import the ".ovpn" configuration file to the application. You will find instructions in the following section.

Useful Links and Recommendations

OpenVPN client for the Windows platform: https://openvpn.net/index.php/open-source/downloads.html

Instructions for using the OpenVPN client on Windows: https://openvpn.net/index.php/access-server/docs/admin-guides-sp-859543150/howto-connect-client-configuration/395-how-to-install-the-openvpn-client-on-windows.html

How to import the .ovpn file on Windows: https://buffered.com/tutorials/setup-openvpn-client-windows-7/. There is another method of loading a profile but you should avoid it. Right-clicking on the .ovpn profile gives you the option to run it in the client, but on some versions of Windows that will fail silently because network routes can't be added, since the application is run without administrator privileges.

OpenVPN for Android: https://play.google.com/store/apps/details?id=net.openvpn.openvpn

OpenVPN for MacOS: https://openvpn.net/index.php/access-server/docs/admin-guides/183-how-to-connect-to-access-server-from-a-mac.html

OpenVPN for iOS: https://itunes.apple.com/app/openvpn-connect/id590379981?mt=8

Linux users can just use their package manager to install the openvpn package. 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/index.php/open-source/documentation.html

Check for possible privacy leaks: https://ipleak.net/. You should consult this page before connecting to your VPN server and 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). You can right-click on the OpenVPN icon in the system tray and then click on "Edit Config" if you have already imported the .ovpn file.

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.