EDIT (Jaunary 2011): Since I originally wrote this article in 2009, a new project has appeared called Easy OpenVPN, which is described as “a collection of bash scripts which will install and configure the Open VPN software on your PBXIAF server. Also includes scripts for creating client certificate files.” The project’s page further notes that these scripts are compatible with the security models used in, and have been tested with PBX In A Flash and Elastix, and that they may be compatible with other PBX distributions, but have not been formally tested. It also notes that the scripts do not interact directly with Asterisk or FreePBX. I have NOT tested these scripts, but it sounds as if it they might work on just about any CentOS-based OS. Certainly, if you are using one of those distributions, it’s worth looking into — it might be a faster and easier way to set up OpenVPN on your server than the procedure I outline here. Some instructions can be found in this thread. Even if you go that route, you might still want to read the rest of this series, since it gives some explanations and usage tips that may come in handy if the scripts don’t configure OpenVPN the way you’d like. FURTHER EDIT: If you want a dedicated OpenVPN server, check this out: Create a VPN with the Raspberry Pi (from Linux User & Developer).
Before you can begin to set up the OpenVPN server, there is some preparation work that needs to be done. But first, let’s talk about the prerequisites and assumptions we are making here. In the case of the tunnel I was helping to set up, the OpenVPN server was located on a box that runs the Elastix PBX distribution, which includes the CentOS operating system, plus FreePBX and Asterisk and a few other things. It doesn’t really matter whether the box has other servers on it (of course, if it’s a really old/slow box there may be performance issues), but for the purposes of our instructions here, the most important thing is that you have Webmin installed. Let me repeat that loud and clear:
You MUST have Webmin installed to use these instructions!
You don’t have Webmin installed and you don’t want to install it? Fine, shoo, away with you then. There are hundreds of other installation guides on the Internet, go find one you like. You have to keep in mind that with me, whenever there’s a choice between using the Linux command line or manually editing a configuration file, and using a nice GUI, I’ll pick the GUI every time. Some people (usually long time Linux users) seem to have some philosophical objection to using Webmin – if that’s you then you’re obviously much too smart to need these instructions, so what are you doing here?
I’m going to assume you already have Webmin installed, but if you don’t, try doing yum install webmin — it might already be in a CentOS repository. If that doesn’t work, you should be able to do this:
rpm -ivh webmin-current.rpm
Once you get Webmin installed (or if you are using a Debian-based distribution such as Ubuntu) go to The ‘Point and Click’ Home VPN HowTo Guide — we’re going to refer to that document several times, so you may want to keep it open in another browser tab. But for now, just follow the instructions related to installing Webmin, starting (for CentOS users) with the subheading “Access Webmin”. For now, just follow the instructions in the two paragraphs in that section. On a Debian-based system, I’d try following the entire document, but I can tell you there are parts missing for a CentOS-based system, so stick with us for a bit.
Another assumption we are making is that your primary network (the one the server in on) has addresses in the 192.168.0.1 through 192.168.0.255 range. It’s okay if the “0” in the third octet is some other number (hopefully it’s not 5, because that what we used at the client end) but the main point is that we’re assuming it’s a small network. If you’re using more than 255 addresses on the primary network it’s not an insurmountable problem, as long as the client end has its own unique address space.
Open the file /etc/hosts.allow at the server – you should see something like this:
ALL : 192.168.0.0/255.255.255.0
If you do, you could change it to the following two lines (note the change in the netmask in the first line):
ALL : 192.168.0.0/255.255.0.0
ALL : 10.8.0.0/255.255.255.0
However, if there are any addresses in the range 192.168.0.0 through 192.168.255.255 that are normally reachable but not in your LAN — a primary example is a cable modem status page on 192.168.100.1 — you may not want to extend the scope of your local network quite that much. You could use a more restrictive netmask — for example, you could use these two lines, which is what I’d recommend for this project:
ALL : 192.168.0.0/255.255.240.0
ALL : 10.8.0.0/255.255.255.0
That would specify that anything in the range 192.168.0.0 through 192.168.15.255 is on your local network (including subnets on the other side of your tunnel). Alternately, if you wish to be a bit more precise and/or secure, you could specify the network(s) at the distant ends of the tunnel individually (using a more restrictive netmask), e.g.:
ALL : 192.168.0.0/255.255.255.0
ALL : 192.168.5.0/255.255.255.0
ALL : 10.8.0.0/255.255.255.0
(If you do the latter, you may also want to add a line for the network on the WAN side of the client router, e.g. ALL : 192.168.1.0/255.255.255.0 to be able to reach devices in that subnet from the server side of the tunnel — assuming that won’t conflict with any addresses on your own local network).
You also need to go into your router (the one between the OpenVPN server and the Internet, that controls the LAN at the server end – not the client router running the Tomato firmware) and expand the scope of your local network. I can’t give you specific instructions for your router, but generally the principle is the same as in the hosts.allow file – in most cases you need to expand the scope of the local netmask to 255.255.something.0, where something is less restrictive than 255 and includes all local nets on both sides of the tunnel, but not your cable or DSL modem’s status page (don’t worry about the 10.8.0.x addresses, your router won’t see those). I suggest using 255.255.240.0 and then making sure that your local networks on both ends of the tunnel fall within the range 192.168.0.x through 192.168.15.x. The reason you need to change the netmask is so that when something on your primary LAN tries to connect to an address in the 192.168.5.x range (on the other side of the tunnel), your router will send out an ARP probe to find out which device on the network has that address (getting the OpenVPN server to respond is another issue that we’ll cover later). But if you are trying to get to something on the backside of your router (the modem status page being the prime example), you don’t want your router thinking it’s on your LAN – hence the need for care when changing the netmask.
If for some reason you can’t follow my suggestions about local network range, you’ll still need to figure out an appropriate netmask, both for the etc/hosts.allow file and your server-side router configuration. Fortunately, there are many pages on the Web that will help you – Google the phrase “netmask calculator” (include the quotes) and you’ll find several sites that will help you calculate an appropriate netmask. Of course, there are limits on this – you’re going to have a much harder time making this all work if all the local networks on both sides of the tunnel aren’t in the 192.168.x.x range (or, more specifically, don’t have at least the first two octets of the LAN IP address in common).
While you are in the router on the server side of your connection, you need to open UDP port 1194 for incoming traffic and point it at your OpenVPN server – otherwise outside connection attempts will never be received by the server. Don’t open the corresponding TCP port – it’s really not a good idea to use TCP for OpenVPN unless you are forced to do so (by an overly restrictive ISP, for example).
You also need to open up the file /etc/sysctl.conf and make sure that the following line is NOT commented out (add it if it doesn’t already exist):
Also, at a terminal prompt, execute the following:
echo 1 > /proc/sys/net/ipv4/ip_forward
While in the terminal, you SHOULD upgrade OpenVPN to the most current version (or install it if it’s not already installed). Older versions of OpenVPN will not work with these instructions. Just type openvpn from a command prompt and at the top of the resulting output it should show you what version you have, if it is installed. It will look something like this:
OpenVPN 2.2.0 i686-redhat-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Jun 6 2011
2.2.0 is the version in this example. But on a recent CentOS install, just doing yum install openvpn only offered to install version 2.0.9, which is too old to work with these instructions! Here is how I installed a newer version (edited July 27, 2011 to reflect a better way):
Add the dag repository if you haven’t done so already. In the /etc/yum.repos.d directory, create a new file called dag.repo:
Edit the file using any text editor (for example, nano /etc/yum.repos.d/dag.repo) and add the following lines exactly as shown:
name=Dag RPM Repository for Red Hat Enterprise Linux
Save the edited file and then from a command prompt import the repository’s key:
rpm –import http://apt.sw.be/RPM-GPG-KEY.dag.txt
Now if you do
yum install openvpn
You should get the latest version plus any dependencies (it should offer to upgrade your current version if it is older). Note that you must use compatible versions of OpenVPN at both the client and server ends, so once you have an OpenVPN tunnel working, it might not be a good idea to just go upgrading the software at one end or the other unless you know the newer version is still compatible with what you’re using on the other end (minor version upgrades are probably okay, but I am not guaranteeing that!).
Now return to The ‘Point and Click’ Home VPN HowTo Guide — you want to find the section headed “Setting Firewall rule(s) to allow VPN web traffic to redirect out eth0” — now I will just say that you need to follow those instructions, but when setting up the actual rules, I found that only two were really important. So if I were rewriting their instructions, here is how I’d say it:
First we’ll assume that the firewall is not set up yet so click Reset Firewall. Now we need to add some rules. From the Showing IPTable: dropdown select Packet filtering (filter) where we’ll create the following rule:
Forwarded Packets (FORWARD)
|Accept If input interface is tun0
Then, from the Showing IPTable: dropdown select Network address translation (nat) where we’ll create the following rule — this is the rule that goes along with the VPN “push redirect-gateway”. This allows the VPN web traffic to be routed out through your connection:
Packets after routing (POSTROUTING)
|Masquerade If source is 10.8.0.0/24 and output interface is eth0
|Source address or network||Equals||10.8.0.0/24|
Why not add the rest of the rules? Well, if you Reset Firewall as instructed, you don’t need them, because they are specifying default conditions. But if you didn’t want to reset the firewall because you already have some preexisting rules, or if you ever actually decide to go in and configure some more restrictive firewall rules, then you may need some of the other rules listed. There’s certainly no harm in adding the other rules, but I’d rather emphasize the two that are absolutely necessary to get this working, assuming you started with a clean slate.
When you are finished, the two rules pages should look like this:
(I know that at this point, some Elastix and FreePBX users may be wondering if the above would interfere with the operation of fail2ban, in the event they have installed it. As far as I can tell, the answer is no… fail2ban communicates with the firewall in a different way, and unless you add rules that explicitly contradict what fail2ban does, I don’t think there will be any issues. However, I do recommend that you temporarily disable fail2ban, possibly from Webmin’s System | Bootup and Shutdown page, prior to connecting a new VoIP adapter or similar device on the client end of a tunnel for the first time. The reason is that if the device fails to register for any reason, such as a mis-typed password, fail2ban might refuse connections even after you fix the issue, and it might even clamp down on other connections from the client end of your tunnel. So get your devices registered and working, then restart fail2ban. Alternately, if turning off fail2ban makes you nervous, you could open /etc/fail2ban/jail.conf in a text editor, then edit the ignoreip option under the [DEFAULT] section to include the IP addresses or network on the client side of your tunnel — for example, you could add 10.8.0.0/24 and 192.168.5.0/24 as address ranges you don’t ever want to ban.)
Once again, return to The ‘Point and Click’ Home VPN HowTo Guide — now you want to start at the section, “Install OpenVPN-admin module” and continue through to the part entitled “Testing the VPN Server using the OpenVPN client GUI from Windows.” If their suggested download method doesn’t work, use the download link on this page to download it to your local machine, then in Webmin install the module “From uploaded file” rather than “From ftp or http URL” as the article suggests. What I suggest you do here is setup TWO clients, one for a soft client you can use for testing purposes, and one that you will use with the OpenVPN client in the Tomato firmware. While you might be able to get a Windows-based client to work using the instructions shown, I can assure you that the Tomato client isn’t going to work until you add a few additional tweaks, which we’ll cover in Part 3. But you can certainly set up and test the Windows-based client if you like, just to assure yourself that the server is actually working.
Just so you don’t spend a couple hours beating yourself up wondering why the server won’t start, I will point out that there’s a glitch in the Webmin OpenVPN module. When you click on the VPN server list and then click on Start to start a server, the server name is supposed to turn from red to black, and the word Start is supposed to turn to Stop. For whatever reason, that doesn’t happen on our server… you can click Start until the cows come home and it still won’t turn black. It probably has something to do with the module configuration itself – for example there’s a setting for PID file path of running OpenVPN processes (*) which by default is set to /var/run, which may not be correct — however, when I changed it to /var/run/openvpn, which does seem to be correct, it made no difference. I just start and stop the server using the buttons at the bottom of the main “OpenVPN Administration” page, which seem to work fine. EDIT: See Leon Baker’s comment in the comments section below for a fix for this problem. Thanks, Leon!
Next up, in Part 3: Configuring the OpenVPN server using Webmin (or more specifically, the changes and additions you need to make to actually get it working as expected). More screenshots!!!