General security
OpenVPN
February 26, 2014 by
Dejan Lukan
Introduction
In this tutorial we'll talk about OpenVPN client connection settings, which come in handy when the connection to the OpenVPN server does not work. We'll be using GopenVPN GUI client program that can be very useful to connect/disconnect to certain OpenVPN network right from the desktop without entering command line mode. The GopenVPN is also useful, because it presents us with the status of the openvpn connection, which is red if not connected, yellow if connection is being established and green when we're successfully connected to the OpenVPN server.
The basic OpenVPN command when connecting to the OpenVPN server look like the following:
[plain]
# /usr/sbin/openvpn --config /etc/openvpn/client.ovpn --verb 4
[/plain]
We basically need just the config directive that specifies the configuration options for the OpenVPN connection. The verb is used to instruct the openvpn process to be more verbose; the verbosity level can be from 0 (no output), 1 (default) to 11.
The configuration file
The configuration file often specifies a lot of options that we should understand when connecting to the OpenVPN server. In this section we'll present the most often used configuration options by their intention, which are presented in a table below. The configuration options and their explanation was summarized after official OpenVPN manual residing at [1].
Options used for authentication to the OpenVPN server are the following:
Option |
Description |
ca |
CA root certificate that was signed the public/private key pair and is used to check the authenticity of the client as well as of the server. |
key |
The private key of the certificate key pair. |
cert |
The public key of the certificate key pair used when establishing a connection. |
pkcs12 |
The .p12 file, which contains the private key, the public key as well as the CA certificate. If we use this option, then we don't need the ca, key and cert options at all. |
tls-auth |
Provides an additional layer of protection to protect against DoS attacks, where the packets with invalid HMAC signature are dropped without response. This option is needed when we're running a VPN server that's accepting connections from anybody, not just the predefined trustworthy IP addresses. |
askpass <file> |
Asks the user for password of the private key on stdin or reads it from a file if we're using password protected certificate. |
auth-user-pass <file> |
Specifies a file that contains the username and password, where the username is written on the first line and password is written on the second line. Openvpn will only read password from a file if it was compiled with ENABLE_PASSWORD_SAVE option or passwordsave USE flag in Gentoo. If we don't specify the file, the openvpn process will prompt us to enter it in stdin. |
auth-nocache |
Causes the openvpn to not cache the passwords of askpass or auth-user-pass directives in memory. As soon as we enter the password, the openvpn program will delete it from memory and when the password is needed again, we will have to type it again manually. |
auth-retry-type |
Is used to control the actions taken when the username and password have been rejected by the server, because they were invalid, which can happen if we made a mistake in typing in the password. We can use the following options:
|
- none: fatal error occurs and client exits (default)
- nointeract: client will retry the current username and password again
- interact: client will ask the user for username and password again before reconnecting, so the user can correct the possible mistake he made previously.
script-security <level> |
Defines the policy used when calling external programs. The level can be one of the following:
|
- 0: openvpn isn't allowed to call any external programs.
- 1: openvpn can only call the built-in executables like ifconfig, ip, route or netsh.
- 2: openvpn can call executables and scripts.
- 3: openvpn can pass passwords to other programs in environmental variables.
up <cmd> |
After successful TUN/TAP device has been opened, the cmd command is executed. |
down <cmd> |
After TUN/TAP device has been closed, the cmd command is executed. |
cd <dir> |
Changes directory to dir before reading any files like configuration files, key files, scripts, etc. |
chroot <dir> |
Redefines the root directory to be the dir directory, so openvpn won't be able to access files outside this chroot directory. |
daemon |
Will start openvpn in daemon mode, where all the logs will be sent to /var/log/messages, except for the output of the scripts specified with up/down directives, which will go to /dev/null. |
log <file> |
All output from stdout as well as stderr is redirected to the file, including the output of the scripts specified with the up/down directives. |
comp-lzo mode |
Used to compress the data with LZO algorithm, where the mode can be one of the following:
|
- yes: turn LZO on by default.
- no: turn LZO off by default, but allow push overrides from the server, which can dynamically change this option.
- adaptive (default): selectively turn on or off the LZO compression.
We should also take a look at the management interface provided by the OpenVPN. The table below presents all the configuration options that we can use regarding management interface.
Option |
Description |
management <ip> <port> <file> |
Enables the management server, which will listen on ip:port. If file is used, when connecting, we need to specify the same password as written in this file to be able to execute commands. The management interface enables other programs to connect to it and administer the openvpn. We can also connect to it with the telnet program, where we can type help to print a list of support commands. For security reasons, the ip must be set to 127.0.0.1 to prevent unauthorized access from other clients on the network. |
management-query-passwords |
The management interface is used to prompt the user to enter the username and password for the private key, which is more intuitive than having to telnet to the management interface and inputting the desired command. |
management-forget-disconnect |
Makes the openvpn forget the password, when we disconnect from the management interface,. |
management-hold |
Starts the openvpn in hibernating state until we connect to the management interface and manually start it with "hold release" command. |
management-signal |
Sends the SIGUSR1 signal to openvpn when we disconnect from the management interface. This is useful when we close the connection in gopenvpn that disconnects from the openvpn management interface, which in turn sends the signal to openvpn, thus terminating the openvpn connection. |
Keep in mind that if we don't want to reenter the password every now and then, we mustn't use the auth-nocache option, which causes OpenVPN to delete the username and password from the memory. So, when the OpenVPN needs to reestablish the connection a pop-up dialog will be presented to us and we'll have to reenter the username and password. Doing this every hour quickly becomes very tedious, so we're better off by not using this option at all. Nevertheless it's more secure to use public/private keys, which are password protected and then cache the password of the private key rather than the actual password in memory.
Authenticaton Mechanisms
Usually, the OpenVPN can be used in the two modes presented below:
- Peer to Peer: is used to connect together two sites where one site is used as a server and the other site as a client. This is usually done when we have a central location and would like to connect a remote location together with central location by using VPN.
- Remote Access: is used by desktop clients to connect to VPN.
No matter which server mode type we choose there are different authentication modes that we can use and are presented below.
- User Auth: when we want to connect to the OpenVPN server with username and password directly, we have to specify the auth-user-pass directive, which will instruct the OpenVPN to ask us for username/password when connecting to the VPN server and then sending those over the secure TLS channel.
- Shared Key: instead of using username/password pairs, we're rather using a shared key, which is used to establish a connection with the VPN server.
- SSL/TLS: only public/private key pairs can be used to connect to the VPN server. This option is the most secure among the presented options.
Prevent MITM Attacks
We should pay special attention to MITM attacks when connecting to VPN server. Usually we can connect to OpenVPN server without verifying whether the server's certificate was signed by CA certificate, but that would allow an attacker to perform MITM (Man-In-The-Middle) attack. This would consequently allow him to sniff all traffic between the OpenVPN client and server, which should be secure. This is possible, because we're not verifying the identity of the VPN server and thus anyone can pretend to be our VPN server.
In order to prevent MITM attack to be possible, we need to tell the client to check whether it's connecting to the right VPN server. We can do that by one of the following options:
Option |
Description |
ns-cert-type server |
Checks if the server certificate's nsCertType field is set to 'server', which ensures that the client is actually connecting to the right VPN server. |
tls-remote name |
Accepts connections only from a host with x509 name name. |
tls-verify cmd |
Executes the cmd command to verify the authenticity of the server. |
Using Certificate Revocation List
The CRL is useful when we have a CA certificate, the server certificate and a bunch of trusted client certificates. If one of the client certificates is no longer trusted, because the laptop containing that certificate was stolen, we need to revoke access to that certificate. Remember that we don't want to disable the whole PKI infrastructure, but rather disable just that certificate. To do that, we need to add the compromised certificate to the certificate revocation list (CRL). When that happens the certificate is no longer able to connect to the VPN server, because it's not trusted anymore.
To use that open with OpenVPN we have to specify the crl-verify option and pass the file in PEM format to it. That file contains all revoked certificates that are no longer valid.
References:
FREE role-guided training plans
Get 12 cybersecurity training plans — one for each of the most common roles requested by employers.
[1] OpenVPN, Section: Maintenance Commands (8)
https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage.
Dejan Lukan is a security researcher for InfoSec Institute and penetration tester from Slovenia. He is very interested in finding new bugs in real world software products with source code analysis, fuzzing and reverse engineering. He also has a great passion for developing his own simple scripts for security related problems and learning about new hacking techniques. He knows a great deal about programming languages, as he can write in couple of dozen of them. His passion is also Antivirus bypassing techniques, malware research and operating systems, mainly Linux, Windows and BSD. He also has his own blog available here: http://www.proteansec.com/.