We’re all lazy, aren’t we? If you think about it for a second, everything you do is more or less aimed at making your life easier, simpler and less-time consuming. Think about your last project. What were you more concerned about: polishing every little detail or maybe getting some stuff done as soon as possible due to an incoming deadline?

We’ve all been there and we all know that feeling. Even if you try to be perceived as your colleagues and clients as the most hardworking admin around, at the end of the day you, after setting up 20 virtually identical VMs, you’re probably thinking “How could I get this done faster next time?”, less likely “Have I checked everything on #13 before pushing it into production?”.

Well, we all do. We all look how to get even a smallest bit of work off our back.

Do you remember your last trip to commsroom? Don’t you think it would be so much easier to connect to some kind of relay that would transfer the commands you’re typing in on your home laptop to the corporate network back at work? If only such a relay would be possible…

Wait a second – it is possible. It’s a VPN server we need.

Before continuing, I highly recommend reading my previous post about setting up a vRouter on a Linux VM. The tutorial part of this article is going to be based around similar system.

I. Virtual Private Network - Intro

Our story begins in 1996, when a Microsoft employee developed PPTP (peer-to-peer tunnelling protocol). PPTP alone wasn’t what we would consider a VPN-ish solution by today’s standard – it did not provide any sort of encryption or user authentication whatsoever. Creating a secure network link with PPTP required setting up additional security checks based on either PAP or CHAP protocols.

However, if we look past PPTP flaws, it was indeed one of the first network protocols capable of transferring data between two or more remote private networks (inter-connected via the internet) as if they were all a part of single LAN. At the time this protocol was revolutionary, letting companies connect all of their internal networks into a single, centralized intranet without investing in extremely expensive dedicated link provided by an ISP.

As the years went by, PPTP users started to look for more secure alternatives. While end-client security wasn’t a big concern back then (people had waaaay more trust in their AV software at the time), network admins were trying to find a way to secure traffic during the transfer itself (sniffing, man-in-a-middle attacks etc.). Two technologies originating from that period and still being used today are SSL and IPsec

The VPN flavour we are going to look into in this post is OpenVPN – based mostly on SSL/TLS. Because of its custom security protocol born from a mix both of these encryption standards, OpenVPN is considered one of the most secure, if not the most secure VPN software on the market.

II. Virtual Private Network - The Basics

OpenVPN is an open source VPN implementation used mostly for creating secure point-to-point or site-to-site connections. You can see the difference between the two on the diagram below. To simplify the setup, we are going to assume the routers in both network have a VPN server functionality.

As you can see, in a point-to-point (P2P) VPN setup, users connect to the main office – mostly using dedicated clients – through a VPN gateway (office router), while the remote site sends the return data as if it was regular traffic within LAN. The VPN gateway (router) has been configured to “distinguish” traffic sent to the hosts connected directly to LAN and traffic sent to hosts connected to VPN – the latter receive appropriate packet tags before being put through to the Internet. This setup ensures only the selected users can connect to the site from the Internet – a double edged sword to be honest. Network admin doesn’t have to worry about unauthorized users getting access to remote site resources from outside the network, while on the other hand, users who are authorized to do so, need to be trained in VPN client usage (at minimum).

Site-to-Site (S2S) setup is a little bit more complicated – in this setup, we are connecting two (or more) sites with each other, creating single virtual LAN (not to be confused with vLANs/vNetworks VMware terms). The traffic is getting routed between the gateways directly, meaning the end-users don’t even have to know they are being a part of a VPN. That’s obviously, a huge advantage, but at the same time this requires the network admin to secure restricted resources on a system level.

In this post we are going to have an in-depth look on both of these situations (and deploy an OpenVPN VM for each), but for the time being the summary above should suffice.

III. Virtual Private Network – Technical Overview

In a nutshell, VPN connection is established between two or more parties – both connected to the Internet. On top of user authentication, modern VPN setup usually includes a strong end-to-end encryption to avoid data leaks “between” users.

As mentioned above, OpenVPN is considered the best (or one of the best, depending on who you ask) VPN software available. It’s main advantage over IPsec-based solutions is its security (SSL/TLS mix) and flexibility – while IPsec uses specialized ports & network protocols, OpenVPN relies only on common UDP/TCP ports. This is highly desirable with restrictive ISPs or countries disallowing the use VPNs, as while IPsec can be easily disabled without disturbing regular online activity, doing same with OpenVPN would be highly difficult if not impossible.

The most basic OpenVPN setup between a client (remote) and a server (local) requires the following:

  • First and foremost, Internet access on both sides of the VPN link
  • Individual (not shared between multiple sites, i.e. NATed) public IP or DDNS address on WAN-facing router interface in the local network
  • Router with OpenVPN support or dedicated machine for VPN (VPN server) in the local network
  • S2S only: Public IP (again, not NATed) or DDNS address on WAN-facing router interface in the remote network
  • S2S only: OpenVPN-enabled router in the remote network or a dedicated machine for VPN (server)

Some advanced features we could implement are:

  • Certificate/secret key authentication for P2P remote users
  • SSL authentication between the sites in S2S setup based on CA-level certificate (“HTTPS” certificate bought from ISP or provider such as GoDaddy, Let’s Encrypt etc.)
  • Secure VPN portal for easier rollout for new P2P remote users
  • Service over VPN (DNS, Active Directory, SMB)

In the following tutorial we are going to look into the “basic” P2P OpenVPN setup. Advanced features and S2S are going to be described in another post (coming soon).

IV. Setting up OpenVPN server on Linux vRouter

1. Preparation

Before starting the actual setup of an OpenVPN server in our network, we need to plan things out a little bit. First major thing to consider is networking. Frankly speaking, VPN is just another network which your users are going to access. This means we need to plan how big we need it to be as well as where to “include” it in the subnet environment.

Let’s say your local network in the office is operating on the most common B-level private subnet 172.18.x.0/24. In this case, it is recommended to setup the VPN on A-level 10.x.x.0 subnet or different 172.18.x.0 network. What you need to avoid is having your clients connect to the VPN from the same subnet as the one used in either your local network or VPN. Keep in mind you can safely assume most of the users are going to use their VPN clients from either home LAN or services such as open WiFi hotspots, which are probably based on 192.168.x.0/24.

2. Installation

Firstly, let’s update our system:

sudo apt-get update
sudo apt-get upgrade

Next, we’ll need to download the OpenVPN & Easy-RSA (encryption):

sudo apt-get install openvpn easy-rsa

And that’s it – we have our base services installed. Now it’s time to configure them.

3. Configuration

3.1. Server.conf

We are going to use the sample OpenVPN configuration file as template. We can get it extracted to /etc/openvpn/server.conf by running the following:

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

Open it up with nano or other text editor of your choice:

nano /etc/openvpn/server.conf

For a basic OpenVPN setup, we need to do the following changes:

a) double RSA key length for stronger encryption – replace dh dh1024.pem with dh dh2048.pem

# Substitute 2048 for 1024 if you are using
# 2048 bit keys.
dh dh2048.pem

b) enable traffic redirection so the server passes clients web traffic to correct destination by uncommenting ;push “redirect-gateway def1 bypass-dhcp” (remove ; character)

# (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”

c) push OpenDNS servers’ IP addresses as DNS settings for clients (to prevent leaks outside DNS connection) by uncommenting ;push “dhcp-option DNS 208.67.222.222” and ;push “dhcp-option DNS 208.67.222.220” (again, remove the ; character)

# 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”

d) set OpenVPN to run as unprivileged user by uncommenting user nobody and group nogroup (OpenVPN server runs by default as root – we don’t need that)

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

e) enable TLS authentication by uncommenting ;tls-auth and ;key-direction 0

tls-auth ta.key 0
key-direction 0

f) select AES128 CBC cipher by uncommenting ;cipher AES-128-CBS and adding auth SHA256

cipher AES-128-CBC
auth SHA256

Save your changes and exit the editor (if using nano – CTRL+X and double y)

The next step is not needed if you’re using the vRouter VM from my previous post (skip to 3.3).

3.2. Port Forwarding

As VPN is based on forwarding packets from clients to the server (and vice-versa), we need to make sure our OpenVPN VM has that option enabled in the system. You can check that by running:

cat /proc/sys/net/ipv4/ip_forward

Getting 1 as a result means the IP forwarding is enabled, while 0 indicates it’s disabled. In case the later is true, run the following:

echo 1 > /proc/sys/net/ipv4/ip_forward

Alternatively, edit /etc/sysctl.conf and and uncomment the line #net.ipv4.ip_forward=1 (remove #) to make the change permanent.

3.3. Firewall – opening ports required by OpenVPN

a) Advanced setup – applicable if your VM have IPtables configured with /etc/iptables.rules backup file (just like the one in this post)

Open up IPtables backup file:

sudo nano /etc/iptables.rules

Add the following line to the filter (replace eth0 with your LAN-facing interface name):

*filter
()
-A INPUT -i eth0 -p udp -m udp –dport 1194 -j ACCEPT
-A INPUT -i eth0 -j DROP
()

Save and close the file (CTRL+X) and refresh the rules in the system:

sudo iptables-restore < /etc/iptables.rules

b) Simple setup – UFW; applicable if you’re setting up OpenVPN server on a new system

Install ufw package (simple firewall manager):

sudo apt-get install ufw

Open the required ports by running:

sudo ufw allow 1194/udp

Finally, apply the changes to the firewall by running:

sudo ufw disable
sudo ufw enable

3.4. Server & client RSA certificates

3.4.1 Setting up CA directory & basic variables

As OpenVPN is an TLS/SSL VPN, we need to setup an encryption for our traffic.

To begin, we can copy the easy-rsa template directory into our /home and move into it:

sudo make-cadir ~/openvpn-ca
cd ~/openvpn-ca

Now it’s time to configure the CA (Certificate Authority) variables. Easy-RSA will use those values for identifying our server. We can set them in ~/openvpn-ca/vars

sudo nano vars

We need to edit only the most basic variables for our OpenVPN server to work:
export KEY_COUNTRY=”US” Change US to your country ID (i.e. PL, IE, DE)

export KEY_PROVINCE=”CA”
Change CA to your province (ND, SD, NY, WLKP etc.)

export KEY_CITY=”SanFrancisco”
Change SanFrancisco to your city

export KEY_ORG=”Fort-Funston”
Change Fort-Funston to your company/organization

export KEY_EMAIL=”me@host.mydomain”
Change me@host.mydomain to your email address (optional; mostly needed while getting a Global SSL certificate from CA authorities such as LetsEncrypt, GoDaddy etc.)

export KEY_OU=”MyOrganizationUnit” Change MyOrganizationUnit to your department (i.e. IT, Accounts)

Remember you need to fill every single one of the values above. Do not leave them blank under any circumstances. Once finished, press CTRL+X to save changes and close the editor.

3.4.2 Building the CA

Run the following command to source the vars file you just edited:

sudo 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/()/openvpn-ca/keys

At this point we want to make sure we’re operating in a clean system, so let’s run:

sudo ./clean-all

Now, we can build our root CA by typing:

sudo ./build-ca</span>

Since we already filled in all required info in the vars file, you can safely press ENTER through the prompts to confirm default selections.

3.4.3 Creating Server certificate & encryption files

Now we are going to generate all the certificates and encryption files needed for securing OpenVPN connections between our server & the client machines.

Start by generating the OpenVPN server certificate and key pair by running:

sudo ./build-key-server server

You can safely press ENTER on all prompts as we filled the vars file before.

There are going to be two additional questions (regarding challenge passwords) at the end of this process. We are not going to go through them in this guide, so leave them blank for now by pressing ENTER twice.

Next, we are going to generate Diffie-Hellman keys (used during key exchange), by typing:

sudo ./build-dh

Afterwards, we are going to generate an HMAC signature to strengthen the server’s TLS integrity verification capabilities:

openvpn –genkey –secret keys/ta.key

3.4.4 Client Certificate & key pair

For the sake of simplicity, we are going to generate the client certificate on the server side, however it is possible to the same on client’s machine and then sign it. We are going to generate a single certificate/key pair, but if your setup includes more than one client, feel free to repeat the steps below as many times as needed (remember to replace client1 with a different name for each cert).

If you don’t want the client to use additional password, use the build-key command in the next step. Otherwise, replace it with build-key-pass.

cd ~/openvpn-ca
source vars
sudo ./build-key client1

Press ENTER for every question. Remember to leave challenge passwords blank.

3.5 Finishing up the configuration

To finish up the setup, copy all the files we created in the previous step to /etc/openvpn

cd ~/openvpn-ca/keys
sudo cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn

Now we can start the OpenVPN service by running:

sudo systemctl start openvpn@server

Finally, make sure the OpenVPN service starts at boot:

sudo systemctl enable openvpn@server

V. End Notes

End notes have been moved to Part 2