Hardening OpenVPN on ubuntu / Mac os x
One of the often-repeated maxims of network security is that one
should never place so much trust in a single security component that its
failure causes a catastrophic security breach. OpenVPN provides several
mechanisms to add additional security layers to hedge against such an
outcome.
tls-auth
The
tls-auth directive adds an additional HMAC
signature to all SSL/TLS handshake packets for integrity verification.
Any UDP packet not bearing the correct HMAC signature can be dropped
without further processing. The
tls-auth HMAC signature provides an additional level of security above and beyond that provided by SSL/TLS. It can protect against:
- DoS attacks or port flooding on the OpenVPN UDP port.
- Port scanning to determine which server UDP ports are in a listening state.
- Buffer overflow vulnerabilities in the SSL/TLS implementation.
- SSL/TLS handshake initiations from unauthorized machines (while such handshakes would ultimately fail to authenticate, tls-auth can cut them off at a much earlier point).
Using
tls-auth requires that you generate a shared-secret key that is used in addition to the standard RSA certificate/key:
openvpn --genkey --secret ta.key
This command will generate an OpenVPN static key and write it to the file
ta.key.
This key should be copied over a pre-existing secure channel to the
server and all client machines. It can be placed in the same directory
as the RSA
.key and
.crt files.
In the server configuration, add:
tls-auth ta.key 0
In the client configuration, add:
tls-auth ta.key 1
proto udp
While OpenVPN allows either the TCP or UDP protocol to be used as the
VPN carrier connection, the UDP protocol will provide better protection
against DoS attacks and port scanning than TCP:
proto udp
user/group (non-Windows only)
OpenVPN has been very carefully designed to allow root privileges to
be dropped after initialization, and this feature should always be used
on Linux/BSD/Solaris. Without root privileges, a running OpenVPN server
daemon provides a far less enticing target to an attacker.
user nobody
group nobody
Unprivileged mode (Linux only)
On Linux OpenVPN can be run completely unprivileged. This configuration is a little more complex, but provides best security.
In order to work with this configuration, OpenVPN must be configured
to use iproute interface, this is done by specifying --enable-iproute2
to configure script. sudo package should also be available on your
system.
This configuration uses the Linux ability to change the permission of
a tun device, so that unprivileged user may access it. It also uses
sudo in order to execute iproute so that interface properties and
routing table may be modified.
OpenVPN configuration:
- Write the following script and place it at: /usr/local/sbin/unpriv-ip:
#!/bin/sh
sudo /sbin/ip $*
- Execute visudo, and add the followings to allow user 'user1' to execute /sbin/ip:
user1 ALL=(ALL) NOPASSWD: /sbin/ip
You can also enable a group of users with the following command:
%users ALL=(ALL) NOPASSWD: /sbin/ip
- Add the following to your OpenVPN configuration:
dev tunX/tapX
iproute /usr/local/sbin/unpriv-ip
Please note that you must select constant X and specify tun or tap not both.
- As root add persistant interface, and permit user and/or group to
manage it, the following create tunX (replace with your own) and allow
user1 and group users to access it.
openvpn --mktun --dev tunX --type tun --user user1 --group users
- Run OpenVPN in the context of the unprivileged user.
Further security constraints may be added by examining the parameters at the /usr/local/sbin/unpriv-ip script.
chroot (non-Windows only)
The
chroot directive allows you to lock the OpenVPN daemon into a so-called
chroot jail,
where the daemon would not be able to access any part of the host
system's filesystem except for the specific directory given as a
parameter to the directive. For example,
chroot jail
would cause the OpenVPN daemon to cd into the
jail
subdirectory on initialization, and would then reorient its root
filesystem to this directory so that it would be impossible thereafter
for the daemon to access any files outside of
jail and
its subdirectory tree. This is important from a security perspective,
because even if an attacker were able to compromise the server with a
code insertion exploit, the exploit would be locked out of most of the
server's filesystem.
Caveats: because
chroot reorients the filesystem
(from the perspective of the daemon only), it is necessary to place any
files which OpenVPN might need after initialization in the
jail directory, such as:
- the crl-verify file, or
- the client-config-dir directory.
More info here:
http://openvpn.net/index.php/open-source/documentation/howto.html#security