A VPN (Virtual Private Network) enables connections between clients and servers from multiple different internal networks across a public network (like the Internet) as if the nodes were located in the same private network. Since the communication is transferred across the public network, it must be properly encrypted to prevent eavesdropping. When a user is connected to the VPN connection, he/she can access the extended network services the same way as if they were located with its private network.
There are two types of VPNs: the remote-access VPN used to connect a device to a network and site-to-site VPN used when connecting two networks together. A VPN can be used for multiple different scenarios, like allowing employees to securely access the company’s internal network even when outside the office (remote-access VPN), connecting two remote offices together into one internal private network (site-to-site VPN), etc.
There are different implementations of the VPN protocols, including the ones listed below (summarized after ):
- Internet Protocol Security (IPsec): a widely used VPN implementation that uses IPv4 and operates on layer 2, where the packet is encapsulated into an IPsec header and sent to its endpoint.
- Transport Layer Security (SSL/TLS): another widely used VPN implementation that’s most often incorporated with OpenVPN, which we’ll take a look in this article. OpenVPN is an SSL-based VPN that uses SSL certificates to encrypt the data in transit.
- Datagram Transport Layer Security (DTLS)
- Microsoft Point-to-Point Encryption (MPPE)
- Microsoft Secure Socket Tunneling Protocol (SSTP)
- Secure Shell (SSH) VPN
Depending on the type of VPN we’re checking during our penetration test, there are different procedures that will drive our testing. Despite the type of VPN being used, the basic steps to pentest the VPN are the following:
Reconnaissance: the first step is determining which type of VPN we’re dealing with in order to plan how to proceed with the attack. We can do that with a simple port scan by using an open-source tool like Nmap or any other tool with port scanning capabilities. The purpose is determining the type of VPN implementation we’re dealing with, which is often bound to a default port. Usually the following ports are involved with VPN services: UDP 500 (IPSec), TCP 1723, TCP 443 (SSL VPN) and UDP 1194 (OpenVPN).
- Exploitation: the phase is under direct influence of the type of the VPN we’re dealing with. When testing network-based IPSec VPN, we can rely on the Ike-scan program to perform the testing. First, we can identify the VPN product and its version and search for related vulnerabilities online; there are vulnerabilities for different vendors like Cisco or CheckPoint regarding the VPN services that we can use to our advantage. When dealing with SSL VPN, we could theoretically use the tools used for SSL pentesting, and in some cases we can do that, but most tools out there support TCP protocol only, where UDP isn’t supported. One of the most critical vulnerabilities this year has been the HeartBleed vulnerability, which affects the OpenSSL library that OpenVPN is also using. Therefore, if OpenVPN is using a vulnerable version of the OpenSSL library, the service can be exploited by malicious attackers and the whole server can be compromised. This is why we have to take every security precaution in order to protect our network.
- Credentials: when the connection with a VPN server is initiated, a client must present a valid passphrase or a certificate to prove that it’s authorized to use the server. If the VPN server is only using passphrases, we should instead configure to use certificates with each of the passphrases to improve security. I’ve often seen a VPN server using only user credentials to authenticate to the VPN server; not to mention some of the user passwords were quite simple and easy to guess within a few bruteforcing attempts. That is certainly something we have to keep in mind when conducting a penetration test of the VPN server or when setting up such a server for our own network.
Recommendations for Hardening OpenVPN
To harden the OpenVPN security, we have to edit its configuration file, usually passed to the OpenVPN daemon by the –config command-line option. If we use the “ps -ef” command and grep the OpenVPN processes, we can see where the configuration file is located and view it accordingly.
Table 1: Security configuration options in openvpn.conf
|tls-auth||Provides an additional layer of security by checking whether each SSL/TLS handshake packet contains the correct HMAC signature; if that is not the case, the packet is discarded immediately. This option protects against DoS attacks, port flooding attacks on UDP port, fingerprinting to determine if UDP port is open, SSL/TLS handshakes from unauthorized clients, etc. We can generate the 2048-bit static key for authentication of TLS packets with the following command:
# openvpn –genkey –secret server.tls-authThe key needs to be available on the server as well as all the clients that wish to connect to the VPN server. In the server configuration, we have to add the following:
> tls-auth server.tls-auth 0
|proto <udp|tcp>||Defines whether the TCP or UDP protocol is used for the OpenVPN server. Usually, the hackers will only port scan the TCP ports, leaving UDP ports unscanned, since scanning UDP ports takes a long time. To use the UDP protocol, we can set the following option in configuration file:
> proto udp
|port <port>||Defines the port the OpenVPN server will listen to for incoming connections. By changing the default port of the OpenVPN server, the attacker might not find the open port or move to the next interesting port. By changing the port to some other number, we’re essentially using security through obscurity technique, which by some is not considered a security feature.
> port 1234
|The user/group configuration options allow the OpenVPN daemon to drop the root privileges after the initialization phase. This provides an additional layer of security, since the daemon will be running under nobody and not under root user. This provides enhanced security, since an attacker successfully exploiting a vulnerability in the OpenVPN daemon would instantly gain root privileges on the server. When proper user/group directives are used, the OpenVPN daemon can be run under a different unprivileged user account.
> user nobody
> group nobody
|chroot <dir>||Allows the OpenVPN daemon to be locked inside the chroot jail, which is a separate directory on the host filesystem to which the daemon has access to. Since the daemon doesn’t have access to the rest of the filesystem, we must properly copy all needed files to the chrooted jail, so the OpenVPN can function properly. The specified jail directory will be the daemon’s root directory, so even if an attacker is able to exploit the OpenVPN daemon, he will be restricted to that directory and won’t be able to access the rest of the filesystem. When creating the chroot directory for OpenVPN daemon, we must copy all needed files, binaries and libraries to the chroot jail for the daemon to be able to access them. All the needed libraries of the OpenVPN daemon can be displayed by using the ldd command as presented below, which will report a bunch of .so libraries we need to copy to the jail directory.
# ldd /usr/local/sbin/openvpn
|cipher <cipher>||The cipher directive controls which cipher is going to be used for encryption. Obviously, the strong the cipher, the harder it is to bruteforce it and obtain clear text from cipher text. We can use the command presented on the picture below to list all supported ciphers.
It’s advisable that a 256-bit cipher is used to increase security. Note that a strong cipher will have slight impact on the performance of OpenVPN server, especially on the SSL/TLS handshake, but the slowdown is negligible and gain is tremendous. We can use the following configuration line to switch to a strong symmetric cipher:
> cipher AES-256-CBC
|auth-user-pass <file>||Usually the client certificates are used to connect to the OpenVPN server, but by using this configuration directive, an additional username and password needs to be used with each certificate.|
|auth-nocache||Instructs OpenVPN to not cache the passwords of auth-user-pass directives in memory. As soon as we enter the password, it is removed from memory, and when needed again upon renegotiation, we have to enter it again.|
|crl-verify||This server configuration directive is used to instruct OpenVPN to verify whether the certificates have been revoked against a specified file. If the certificate has been revoked, the client will be denied access to the OpenVPN, which is specifically useful for people leaving an organization, where an administrator can easily revoke their certificate to make it invalid. The option is also used to revoke the certificates that have been stolen or lost.|
|management||A server configuration directive used to restrict the management interface that allows administration of the OpenVPN daemon. Since the protocol communication is not encrypted, we have to ensure access is allowed to local users only and therefore the communication must be allowed only from localhost.
> management 127.0.0.1 port
|duplicate-cn||Disables certificate reuse, where one certificate can only spawn one communication channel with the OpenVPN server. Otherwise one certificate would be able to open an arbitrary number of connections.|
|remote-cert-tls||A client-side directive instructing the OpenVPN client to check the server certificate, which greatly improves security, since MITM attacks are no longer possible. Basically, the OpenVPN client expects to see certain certificate information when connecting to the OpenVPN server, and if such information is not provided by the endpoint, a connection will not be established. An attacker performing a MITM attack on the client will be able to inspect all network traffic going to and coming from the client. But the attacker can’t see all the traffic in cleartext, since the traffic is often encrypted, which is also the case with OpenVPN connections. Thus, during the VPN session initialization, an attacker must present his own certificate to the client, which connects to the attack that in turn connects to the original OpenVPN server. Therefore, the client is actually connecting to the attacker’s machine thinking it’s the OpenVPN server. If the client is not properly secured, the attacker performing a MITM attack can also intercept, view and modify OpenVPN connections in cleartext.|
|ns-cert-type server||This defines the certificate type, which indicates the purpose of the certificate and for which it can be used. Acceptable values are the following: client, server, email, objsign, reserved, sslCA, emailCA, objCA. To properly protect the OpenVPN server, we have to set the ns-cert-type to ‘server’ to ensure the client is actually connecting to the right VPN server. The picture below presents some common usage values for the certificate.
|A client directive specifying the common name of the server certificate which will be accepted. If the common-name does not match, the connection will be rejected. Note that the tls-remote option is deprecated and will be removed in the future versions of OpenVPN, which is why we should update our configuration to the new option verify-x509-name that can be used for the same purpose.|
|tls-verify cmd||A client directive specifying a test, which verifies custom information in the server’s certificate that must match in order for the certificate to be accepted and connection established.|
It goes without saying that when a hacker stumbles upon an open VPN port, he will most likely check it for different security holes. Therefore, we have to properly protect our VPN server in order to secure our users and our whole internal network. If an attacker is able to compromise the VPN service, he can get access to our whole network.
Some of the administrators might argue that the VPN service is very secure by itself and needs no additional protection, but such predictions have been proved incorrect in the past. One such vulnerability was found in April 2014, named the HeartBleed vulnerability, which can be used to dump memory from the OpenVPN daemon process. Therefore, if an attacker is able to determine that VPN service is running on some port, he might be able to dump arbitrary memory from the server or possibly even take control of the server. Once such a vulnerability is discovered, we must patch it as soon as possible, but properly a hardened service should give an attacker as little access to the server as possible. Imagine a new devastating vulnerability being found in OpenVPN/OpenSSL in the future; a secure service running under an unprivileged account might be just what you need to protect yourself from being a victim of cyber attack.
 Virtual private network,
 Hardening OpenVPN Security,