Getting OpenVPN to work on an OpenVZ VPS


Note: This is a personal VPN, so I just used static keys. A general guide to getting OpenVPN set up is available on the OpenVPN website, but this guide is targeted at CentOS 5 on an OpenVZ VPS.

This guide should be usable in other RH derivatives without much (any?) modification; and with slight modifications for debian-style distros, especially in installing packages and folder paths.

If you’re not running OpenVZ, I’d recommend following the site where the vast majority of this guide comes from, but I had problems with it – I had to mess around with the config files, and the iptables commands *will* kill your SSH session if you run it.

Setting up the server

Step 0:

Grab the RepoForge RPM from repoforge.org/use/ and install it. It has the alternative packages for CentOS/RHEL.  (On Fedora, this is unneeded.)

Step 1:

Switch to root (If you don’t know how, stop now. I’m serious.)

Step 2:

Install OpenVPN – yum -y install openvpn

Step 3: Configure networking

Part 0: Check that the TUN adaptor is working

Run cat /dev/net/tun. It should return cat: /dev/net/tun: File descriptor in bad state. If it doesn’t poke around in the VPS control panel looking for something that mentions TUN/TAP. (If you’re using SolusVM, there’s a button under settings for this.)

Part 1: Enable packet forwarding

First off, tell the kernel to enable packet forwarding:
Edit /etc/sysctl.conf and make sure the line net.ipv4.ip_forward = 1 exists. If it doesn’t, add it. This will ensure that it works after every reboot. To get it working now, run sysctl -p to make it re-read the file.

(Just for interest, CentOS 5.8 apparently had this enabled by default, but Fedora 15 & 17 didn’t.)

Part 2: Actually forward the ports

Next is editing iptables. This is one place where the original guide tripped up. OpenVZ by default DOESN’T support MASQUERADE (which is provided by a kernel module, and on OpenVZ, you don’t have privilieges to add kernel modules).

However, it’s Server Fault to the rescue: Use SNAT rather than MASQUERADE.

So the bunch of commands you’re going to run looks something like this:

# Flush existing rules from iptables.
# IF YOU HAVE PREEXISTING RULES, DON'T DO THIS
# I MEAN IT
/sbin/iptables -F
# Allow all outgoing packets
/sbin/iptables -P OUTPUT ACCEPT
# Allow packets that are from an established connection
/sbin/iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow packets coming from the VPN IP address range
/sbin/iptables -A FORWARD -s 10.9.0.0/24 -j ACCEPT
# Reject all other packets from other sources - in theory unnecessary, but good for security
/sbin/iptables -A FORWARD -j REJECT
# Perform NATing on outgoing packets to change the IP address the packets come from
/sbin/iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -j SNAT --to-source <VPS IP Address>
# Accept the OpenVPN connection (UDP on port 1194)
/sbin/iptables -A INPUT -p udp --dport 1194 -j ACCEPT
# Accept ICMP packets
/sbin/iptables -A INPUT -p icmp -j ACCEPT
# Accept everything on the loopback interface
/sbin/iptables -A INPUT -i lo -j ACCEPT
# Accept everything coming from the OpenVPN adaptor
/sbin/iptables -A INPUT -i tun0 -j ACCEPT
# Accept packets from an established connection
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Save the firewall rules so they persist beyond a reboot
/sbin/service iptables save

Step 4: Build the certificates for OpenVPN

(aka GENERATE ALL THE KEYS!)

We’re going to copy the key generator into the OpenVPN folder. The latest version as of this writing is 2.2.2, but if there’s an updated version, you’ll need to change the version number in “openvpn-2.2.2”:

cp -r /usr/share/doc/openvpn-2.2.2/easy-rsa/2.0/ /etc/openvpn/ && mv /etc/openvpn/2.0 /etc/openvpn/easy-rsa

It’s not necessary to do rename the folder (the second part of the command), but it’ll make things a bit simpler.

Open the file vars in your favourite text editor, and go to the bottom of the file. Change the last few lines as appropriate, this’ll allow us to use defaults when it comes to generating all the keys later.

Make the files all executable if they aren’t already: chmod +x ./*

Export everything to environment variables (This also means that you HAVE TO DO EVERYTHING IN THE SAME TERMINAL from now on, or you’ll need to run this in every terminal you use): source ./vars

Clean everything (In theory, also not necessary, but it refused to run until I did this): ./clean-all

Build the certificate authority key (Accept the defaults or type in new ones.): ./build-ca

Generate the server key (Don’t just blindly hit enter, you need to answer yes to make it sign the cert and import the cert into the database): ./build-key-server server

Generate the Diffie/Hallman key: ./build-dh

Generate the server TLS key (Optional, but recommended to prevent MitM attacks): openvpn --genkey --secret keys/ta.key

Copy all the keys into the OpenVPN directory: cp keys/ca.crt keys/ca.key keys/dh1024.pem keys/server.crt keys/server.csr keys/server.key keys/ta.key /etc/openvpn/

Step 5: Configure OpenVPN

Either copy the sample conf from the included docs (cp /usr/share/doc/openvpn-2.2.2/sample-config-files/server.conf /etc/openvpn/), or copy and paste the following into /etc/openvpn/server.conf:

 port 1194
 proto udp
 dev tun
 ca ca.crt
 cert server.crt
 key server.key
 dh dh1024.pem
 server 10.9.0.0 255.255.255.0
 ifconfig-pool-persist ipp.txt
 push "redirect-gateway def1 bypass-dhcp"
 push "dhcp-option DNS 208.67.222.222"
 push "dhcp-option DNS 208.67.220.220"
 keepalive 10 120
 comp-lzo
 user nobody
 group nobody
 persist-key
 persist-tun
 status openvpn-status.log
 tls-auth keys/ta.key 0
 verb 3

Actually start OpenVPN: service openvpn start

Configure OpenVPN to start automatically at boot: chkconfig --levels=345 openvpn on

Step 6:

There is no step 6.

The server should now be up, and it’s time to get a client connected.

Getting a client connected

Step 0:

Get the OpenVPN client software. For Windows, download the client software from openvpn.net/index.php/download.html

Step 1:

Build keys for the OpenVPN client – this is done on the server, so use the same terminal window from when you generated the bunch of keys for the OpenVPN server.

Note: Keys MUST be unique to clients – if two clients connect with the same key, the later one will win, and the earlier one will be booted out.

Build a key for a client, substituting a name for client1 if you want:
./build-key client1

Step 1.5:

Get the generated files (ca.crt, client1.crt, client1.key and ta.key) onto your client system using whatever method you want. (SFTP is pretty good at that.)

Step 2: Configure the OpenVPN client

Again, either copy the default config file from C:\Program Files\OpenVPN\sample-config\client.ovpn to C:\Program Files\OpenVPN\config\client1.ovpn, or copy & paste this into C:\Program Files\OpenVPN\config\client1.ovpn:

client
dev tun
proto udp
remote SERVER_DNS_OR_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client1.crt
key client1.key
tls-auth ta.key 1
ns-cert-type server
comp-lzo
verb 3
keepalive 10 120
route-method exe
route-delay 2

Windows tip: If Notepad refuses to save with an Access Denied error message, run Notepad as an Administrator (from the Start Menu) and open the file from within Notepad.

Step 3: Run OpenVPN as an Administrator

You’re messing around with Network Settings and Devices. Of course Win 7 won’t let OpenVPN work unless it’s run as Administrator.

Step 4: Connect to the server

This should be as simple as double clicking on the OpenVPN icon in your taskbar. If nothing appears, or the OpenVPN icon is red instead of yellow/green, check that your config file is named client1.ovpn. If it has a different extension, OpenVPN WON’T recognize & run it.

Step 5:

Verify that the VPN works by going to icanhazip.com. The IP address displayed there should be the IP address of the VPN server, not your IP address.

And just like that, you should have a VPN connection up and running.

Now, chances are you got here by wanting to configure an existing OpenVZ instance to run OpenVPN. But if you haven’t already got a OpenVZ VPS, check out LowEndBox – they’ve got frequent offers on cheap OpenVZ instances. (For example, this guide came about because I picked up a VPS at $10 for a year.)

, ,

  1. #1 by the_martines on May 29, 2013 - 3:58 pm

    Thank you soo much! Helped me A LOT!

  2. #2 by James on May 31, 2016 - 7:08 pm

    Thank you very much! you are the only one who actually explains what each line does in the IPTABLES….i was going crazy trying to figure out how to install OpenVPN server with CSF/LFD firewall.

    Just take your commands and put them in nano /etc/csf/csfpre.sh
    iptables -P OUTPUT ACCEPT
    iptables -A FORWARD -m state –state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
    iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT –to-source public_ip
    iptables -A INPUT -p udp –dport 1194 -j ACCEPT
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A INPUT -i tun0 -j ACCEPT;
    iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
    service iptables save

  3. #3 by Moe on July 2, 2016 - 1:13 pm

    Nice! Helped me a lot!

(will not be published)