Table of Contents:


Security Protocol Evolution


At first there was IP.

IP stands for Internet Protocol, and it is based on IP address. IP address is a unique string of numbers used to identify each individual computer (host).

IP delivers packets from the source host to the destination host based on the IP addresses it detects inside packet headers.

IP design is not secure since anyone can intercept the packet and read the data from it. This is why IPsec came out.


IPsec stands for Internet Protocol Security. It’s there to provide encrypted communication between two hosts over IP (Internet Protocol) network. Since the connection is encrypted it can be used for VPNs.


Turns out that OpenVPN is currently most popular VPN protocol that is open source. Since open source anyone can improve it.

When comparing with older VPN protocols OpenVPN brings much better security and simplicity. But there are always new protocols catching up such as WireGuard.

Protocols before OpenVPN

Before OpenVPN we had two major tunnelling protocols: PPTP and L2TP.

Both PPTP and L2TP use fixed ports which makes them easier to block by some firewalls using Deep Packet Inspection (DPI) techniques.


PPTP or Point-to-Point Tunneling Protocol is an outdated method for implementing VPNs developed by Microsoft. Usually PPTP VPN encrypts data using 128-bit encryption key.


Layer 2 Tunneling Protocol (L2TP) is the result of a partnership between Cisco and Microsoft. L2TP runs on UDP. It encrypts data using 256-bit encryption key.

Since L2TP doesn’t have any encryption or authentication capabilities it is paired with IPSec and this brings to L2TP/IPsec.


IKEv2 is an extension of the IPsec protocol that supports iOS devices.

OpenVPN features

It can select protocol: UDP or TCP

Once you use OpenVPN you may select either UDP or TCP transport. UDP is the acronym for User Datagram Protocol and does not perform error correction. It is known as Fire and forget protocol. Because of that UDP is faster but less reliable than TCP.

TCP is the acronym for Transmission Control Protocol. It performs error correction but it demands creating connection, handshaking, synchronization etc.

Supports different encryption key size

OpenVPN can use different key size to encrypt data: 160 and 256 byte keys are common.

Recommended OpenVPN encryption protocol nowadays is ‘AES-256-CBC’.

TUN or TAP devices

OpenVPN can create a tunnel (TUN) to connect two computers one in Japan and other in Brasil. You would just specify dev tun to make a tunnel inside a config file.

TAP is used to bridge two network segments together. For instance, segment 192.168.1.x and 192.168.2.x devices without using a router.

With TAP you will get a new segment say 10.10.x.y and all devices will get IP address from the new segment.

Client and Server

OpenVPN is based on client-server paradigm. It connects two parties together where one is a client and other is a server.

So there are: OpenVPN client and OpenVPN server know as peers. OpenVPN peers authenticate each other using:

  • pre-shared secret keys
  • certificates or
  • username/password

Both peers have configuration files. Here are some well commented examples.

Example: OpenVPN Client Configuration File



Typically there are multiple clients and one server. This is called multi-client server.

Each client need to have cert and key files (those with the extension .crt and .key).

Typical extension for the configuration file is .ovpn (what is in the image).

The task of the client is to pull certain config file directives from the server to authenticate.

First line client specify the client configuration file.

This device is tunneling (dev tun). On client side, firewall for tun/tap device need to be disabled.

proto udp means OpenVPN will use UDP protocol. This must be the same in the server config file.

remote is the OpenVPN server name or IP address with teh addition of the port. You may select any port.

There may be multiple remote entries, for load balancing and remote-random would be the instruction to pick random one.

nobind is there to tell for the client not to bind to specific port to IP address, but to allocate a dynamic port for returning packets.

user nobody and same for the group nogroup would downgrade privileges.

persist-key and persist-tun would be to preserve some state across restarts.

Instructions with the proxy are if you connect through HTTP proxy to reach the OpenVPN server (not so common).

Now the bitter sweet part, the certificates. Certificates may be injected inside the .ovpn file have. Or they can point to files.

cert ca.crt 
cert client.crt 
key client.key

client.crt and client.key are separate for each client, and ca.crt is the Certificate Authority (same for all clients).

remote-cert-tls server if one of five ways to protect from the man-in-the-middle attack.

comp-lzo is the compression algorithm that need to be enabled on server as well.

There are other client instructions that may be used, you would typically check them from the OpenVPN web site.

Example: OpenVPN Server Configuration File



local a.b.c.d is where OpenVPN should listen. port 1194 is which TCP/UDP port OpenVPN should listen.

Picking the protocol and device need to be the same as on client: proto udp, dev tun.

Each client and the server must have their own cert and key file. The server and all clients will use the same ca file.

ca ca.crt
cert server.crt
key server.key # keep as secret

dh dh2048.pem are Diffie-hellman parameters generated via:

openssl dhparam -out dh2048.pem 2048

Network topology is by defaults subnet (topology subnet) rather than the older “net30”.

Subnet mode allocates a single IP address per connecting client.

The line server means the server will take the IP address, and the rest /24 space will be available for clients.

server-bridge is only important if you use TAP.

Push routes to the client to allow it to reach other private subnets behind the server using push directive.

It is possible to assign specific IP addresses to specific clients using ccd stands for client-specific configuration files.

If you set client-to-client on server different clients will be able to “see” each other.

keepalive 10 120 directive causes ping-like messages to keep live connection.

Example: Man-in-the-middle attack and ways to prevent it

As described in on community site, you need to be aware of the possible Man-in-the-Middle attack.

If the clients do not verify the certificate of the server, some other client from the same subnet may act as a false server.

To avoid a possible Man-in-the-Middle attack where an authorized client tries to connect to another client by impersonating the server, you need to enforce server certificate verification on clients.

There are currently five different ways of accomplishing this:

  1. Sign server certificates with one CA and client certificates with a different CA. The client configuration ca directive should reference the server-signing CA file, while the server configuration ca directive should reference the client-signing CA file.

  2. Use a tls-verify script or plugin to accept/reject the server connection based on a custom test of the server certificate’s embedded X509 subject details.

  3. Use the tls-remote directive on the client to accept/reject the server connection based on the common name of the server certificate.

  4. Build your server certificates with the build-key-server script (see the easy-rsa documentation for more info). This will designate the certificate as a server-only certificate by setting nsCertType=server. Now add the following line to your client configuration: ns-cert-type server.

  5. Build your server certificates with the build-key-server script (see the easy-rsadocumentation for more info). This will designate the certificate as a server-only certificate by setting the right attributes. Now add the following line to your client configuration: remote-cert-tls server.

Check the version of OpenVPN

openvpn --version


OpenVPN 2.4.0 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Oct 14 2018
library versions: OpenSSL 1.0.2u  20 Dec 2019, LZO 2.08
Originally developed by James Yonan
Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <[email protected]>
Compile time defines: enable_async_push=no enable_comp_stub=no enable_crypto=yes enable_crypto_ofb_cfb=yes enable_debug=yes enable_def_auth=yes enable_dependency_tracking=no enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown enable_fast_install=needless enable_fragment=yes enable_iproute2=yes enable_libtool_lock=yes enable_lz4=yes enable_lzo=yes enable_maintainer_mode=no enable_management=yes enable_multi=yes enable_multihome=yes enable_pam_dlopen=no enable_password_save=yes enable_pedantic=no enable_pf=yes enable_pkcs11=yes enable_plugin_auth_pam=yes enable_plugin_down_root=yes enable_plugins=yes enable_port_share=yes enable_selinux=no enable_server=yes enable_shared=yes enable_shared_with_static_runtimes=no enable_silent_rules=no enable_small=no enable_static=yes enable_strict=no enable_strict_options=no enable_systemd=yes enable_werror=no enable_win32_dll=yes enable_x509_alt_username=yes with_crypto_library=openssl with_gnu_ld=yes with_mem_check=no with_plugindir='${prefix}/lib/openvpn' with_sysroot=no

tags: openvpn - vpn & category: protocols