How to setup OpenVPN on CentOS6

Introduction

This article will guide you through the installation and configuration of OpenVPN on a CentOS 6 server. The preferred OpenVPN version is 2.3.3 as that is the most recent one and, more importantly, the only version which has a fix for the Heartbleed bug.

Step 1 – install OpenVPN

Currently the OpenVPN RPM in EPEL has not yet been updated to version 2.3.3. You can either wait for it to be updated (together with pkcs11-helper version 1.11) or create your own RPMs.

Step 2 – get the EasyRSA scripts

Since the key generation scripts in eay-rsa/ were removed from OpenVPN you have to get them separately:

If you create your own OpenVPN RPM it makes sense to include EasyRSA in it.

Step 3 – edit vars in easy-rsa/

Open /etc/openvpn/easy-rsa/vars in your favorite editor and change

to

Next edit the following fields to your liking. Just don’t leave any blank.

Step 4 – create the CA certificate

Press enter at each question if the default is acceptable or change it to your liking. Don’t leave any field empty.

Step 5 – create the server certificate

Press enter at each question if the default is acceptable or change it to your liking. Don’t leave any default empty.

Answer these questions with yes:

Step 6 – create the client certificate

Answer these questions with yes:

If you need a PKCS12 file (a .p12), follow these steps:

Answer these questions with yes:

Next you are asked for a password to secure the .p12 file. Make sure you provide a secure password and store it in a safe place like in Pass, KeePassX or LastPass.

Once the client key is generated, copy it to the host that needs access to the OpenVPN server.

Step 7 – create the DH key

Step 8 – create the tls-auth key (ta.key)

Step 9 – create /etc/openvpn/server.conf

Open your favourite editor and save the config below to /etc/openvpn/server.conf

/etc/openvpn/server.conf:

Do not forget to change ‘SERVER_VPN_NET, ‘SERVER_VPN_NET_NETMASK’, ‘SERVER_NET’, ‘SERVER_NET_NETMASK’, ‘YOUR_DNS_SERVER’ and ‘YOUR_DOMAIN’. Examples below each line/section.

Step 10 – start OpenVPN and check log

In one terminal open the openvpn.log:

And in another terminal start the openvpn service:

Step 11 – enable IP forwarding

Enable IP forwarding so packets from your VPN subnet can be forwarded to the network behind the OpenVPN server.

Open /etc/sysctl.conf in your favourite editor and change:

to

Activate IP forwarding:

Step 12 – setup Masquerading

Make sure that the VPN subnet and interfaces used below are correct for your server.

Restart the iptables service:

Done.

How to fix Fail2ban returned 200

Fail2ban is a wonderful solution to ban IPs that show malicious signs. Unfortunately it’s not always easy to understand why something does not work or what’s causing an error, especially the dreaded “fail2ban returned 200” error:

Here are a few tips to prevent errors like that.

Maximum length of a jail name is 30 chars

The maximum length of a jail name in jail.local (the file where you make your customizations) is 30 characters.

The definition below will not work because there are more than 30 characters in the jail name between the brackets [….].

And the definition below will work because there are 30 or less characters in the jail name between the brackets [….].

Proper use of protocol

The use of protocol should be in sync with the protocols (tcp or udp or all) actually used by the service. So if you want to enable a jail for openvpn and your openvpn setup uses udp, then you need to use protocol=udp in your openvpn jail definition. Likewise if your openvpn setup uses tcp then you need to use protocol=tcp in your openvpn jail definition. Finally if your service uses both tcp and udp then you need to use protocol=all in your jail definition.

If you get this wrong then fail2ban will throw the “fail2ban returned 200” error.

Proper use of port numbers

If your jail needs to use a single port, you put port=xxxx in your jail definition. For example:

If your jail needs to use multiple ports, you use port=”xxx,yyy,zzz” in your jail definition. Notice the double quotes surrounding the port numbers and usage of a comma to separate the port numbers. For example:

Notice the difference between the two definitions? A definition with a single port uses iptables[…] and a definition with multiple ports uses iptables-multiport[…].

Finally, only add the port numbers in your jail definition which the service is actually using. Failure to do that may result in an error and/or unexpected results.

Fixes to prevent a race

When Fail2ban does certain actions (starting up for example) a race can occur and this can result in the “fail2ban returned 200” error. There are two minor changes for Fail2ban which should fix this problem:

1) Fix for action.py

1a) patching the fail2ban source

If you want to patch the fail2ban source, the file action.py is located in your-fail2ban-unpacked-source/server/ and the changes to make are:

1b) patching the installed fail2ban package

If you want to patch an installed fail2ban package on CentOS6 or RHEL6, the file action.py is located in /usr/share/fail2ban/server/ and the changes to make are the same as above:

Please note that the fixes are lost when a fail2ban package update is installed unless the new package has these fixes.

2) Fix for fail2ban-client.py

2a) patching the fail2ban source

If you want to patch the source, the file fail2ban-client.py is located in your-fail2ban-unpacked-source/ and the change to make is:

2b) patching an installed fail2ban package

If you want to patch an installed fail2ban package on CentOS6 or RHEL6, the file fail2ban-client is located in /usr/bin/ and the change to make is the same as above:

Again, this fix is lost when a fail2ban package update is installed unless the new package has this fix.