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
Grab the RepoForge RPM from repoforge.org/use/ and install it. It has the alternative packages for CentOS/RHEL. (On Fedora, this is unneeded.)
Switch to root (If you don’t know how, stop now. I’m serious.)
Install OpenVPN –
yum -y install openvpn
Step 3: Configure networking
Part 0: Check that the TUN adaptor is working
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:
/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
# 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):
Clean everything (In theory, also not necessary, but it refused to run until I did this):
Build the certificate authority key (Accept the defaults or type in new ones.):
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):
Generate the Diffie/Hallman key:
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
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 188.8.131.52" push "dhcp-option DNS 184.108.40.206" keepalive 10 120 comp-lzo user nobody group nobody persist-key persist-tun status openvpn-status.log tls-auth keys/ta.key 0verb 3
Actually start OpenVPN:
service openvpn start
Configure OpenVPN to start automatically at boot:
chkconfig --levels=345 openvpn on
There is no step 6.
The server should now be up, and it’s time to get a client connected.
Getting a client connected
Get the OpenVPN client software. For Windows, download the client software from openvpn.net/index.php/download.html
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:
Get the generated files (
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
remote SERVER_DNS_OR_IP 1194
tls-auth ta.key 1
keepalive 10 120
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.
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 by the_martines on May 29, 2013 - 3:58 pm
Thank you soo much! Helped me A LOT!
#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 by Moe on July 2, 2016 - 1:13 pm
Nice! Helped me a lot!