How to forward a call if a remote extension is unreachable in FreePBX 2.x

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

DISCLAIMER AND WARNING: This article contains EXPERIMENTAL code. DO NOT USE IT IN A PRODUCTION ENVIRONMENT until you have thoroughly tested it AND MODIFIED IT to meet your needs. It is guaranteed to NOT work (at least not in a way that will be useful to you) if you simply copy and paste it, and even if you read and follow the instructions below I don’t guarantee a thing (Asterisk can be funny, sometimes code that runs fine on one system will not on another). Anyway, you are NOT allowed to use this code unless you are willing to take ALL responsibility for modifying and testing it to make sure it will work in your situation. If you use this code and in some way it winds up not working and costing you money, don’t come after me because I’m warning you now that might happen, and it’s the risk you alone assume if you attempt to use this code!

FreePBX and Asterisk allow you to call forward a call on a busy or no-answer condition (as well as unconditionally), but there is no provision for specific forwarding if an extension (presumably an offsite one) is unreachable over the Internet. It is possible to do this, although in Asterisk 1.4 it’s not at all elegant. Some commercial VoIP providers offer a feature similar to this, calling it “Failover”, “Network Unavailable Forward” or just “Unavailable Forward”, “Network Availability Number ®” (Vonage trademarked that one!), or some similar name, but FreePBX and Asterisk do not offer similar functionality — there is no “Call Forwarding Unreachable” setting.  However, with a bit of work and a minimal amount of dialplan creation, you can emulate this feature.

Here’s an example that may work in many situations (as written it works with SIP extensions only, but maybe you can modify it slightly if you need to use it with IAX2 extensions or some other type):

First, if you are still using Asterisk 1.4 or earlier, add the following code to etc/asterisk/extensions_custom.conf:

[custom-unreachable-test] exten => _X!,1,Noop(Testing for unreachable extension ${EXTEN})
exten => _X!,n,TrySystem(asterisk -rx "sip show peers" | grep ^${EXTEN}/${EXTEN}[[:space:]] > /tmp/${EXTEN}.flag)
exten => _X!,n,ReadFile(reachable=/tmp/${EXTEN}.flag,1)
exten => _X!,n,GotoIf($["${LEN(${reachable})}" = "0"]?extoffline)
exten => _X!,n,Noop(Extension ${EXTEN} is reachable - sending to *${EXTEN} voice mailbox)
exten => _X!,n,Goto(from-internal,*${EXTEN},1)
exten => _X!,n(extoffline),Noop(Extension ${EXTEN} is NOT reachable)
;This is where you enter special forwarding conditionals for each unreachable extension
exten => _X!,n,GotoIf($["${EXTEN}" = "1101"]?from-internal,18005558355,1)
;This is the fallover (voicemail) destination in case no special destination is specified
exten => _X!,n,Noop(WARNING - no unreachable destination specified for extension ${EXTEN} - trying to send to voicemail)
exten => _X!,n,Goto(from-internal,*${EXTEN},1)

If you are using Asterisk 1.6 or later then use this instead:

[custom-unreachable-test] exten => _X!,1,Noop(Testing for unreachable extension ${EXTEN})
exten => _X!,n,Set(reachable=${SHELL(asterisk -rx "sip show peers" | grep ^${EXTEN}/${EXTEN}[[:space:]])})
exten => _X!,n,GotoIf($["${LEN(${reachable})}" = "0"]?extoffline)
exten => _X!,n,Noop(Extension ${EXTEN} is reachable - sending to *${EXTEN} voice mailbox)
;This is where you enter special forwarding conditionals for each unreachable extension
exten => _X!,n,GotoIf($["${EXTEN}" = "1101"]?from-internal,18005558355,1)
;This is the fallover (voicemail) destination in case no special destination is specified
exten => _X!,n,Noop(WARNING - no unreachable destination specified for extension ${EXTEN} - trying to send to voicemail)
exten => _X!,n,Goto(from-internal,*${EXTEN},1)

In both of the above examples, change the number 1101 to match an actual extension number on your system and change the 18005558355 to the actual number you want to send calls to (note this could be another extension on your system, including a custom extension or a ring group). Duplicate the line containing those values for each extension you may want to forward, changing those two vales in each line appropriately (also see the comment section for another possible approach).

The above code assumes that if an extension is reachable, but is busy or does not answer, you want the call to go to voicemail (* + the original extension number — obviously, this would be easy to change if that’s an incorrect assumption). However, if the extension is unreachable, you want to reroute it to the user’s cell phone or some other number. In the above example, if extension 1101 receives a call and is unreachable, it would be forwarded to TellMe at 1-800-555-TELL (18005558355) – obviously not practical in a real-world situation, but it’s just an example. Again, note you have to duplicate that line in the code for each extension that might be forwarded in this way.

In order to make this work, you need to go into the FreePBX Tools menu and select “Custom Destinations”, then add a new custom destination. The destination must be custom-unreachable-test,${EXTEN},1 and the description can be anything you want (I suggest “Unreachable Extension Test” or something similar).

For each extension you wish to use this with, you must have qualify=yes (or set qualify to a valid numeric value) in the extension settings.

Finally, for each extension you want to use this with, create a Follow-Me (or edit any existing one) for that extension. You can leave the defaults as they are (or change them if you want – maybe you want to change the Ring Time, for example) but the one thing you must change is the Destination if no answer. Change that to the Custom Destination that you just created. Also, don’t forget to add the line in extensions_custom.conf to actually do something with calls to that extension when the extension is unreachable.

The reason I say this code is not elegant is because it relies on a kludge. It does a “sip show peers”, then looks for the pattern ${EXTEN}/${EXTEN} (e.g. 1101/1101) at the start of a line, which on most systems indicates the extension is connected. This may not be the case if you are using what is known as “deviceanduser” mode (which you probably aren’t unless you’re running a call center) so in that case you may need to use a different pattern match, for example:

exten => _X!,n,TrySystem(asterisk -rx "sip show peers" | grep ^${EXTEN}[[:space:]] | grep OK > /tmp/${EXTEN}.flag)

The result of the system call will be written to the file /tmp/1101.flag (or a similar file with a different extension number) and will either contain the full line from “sip show peers” (if the device or phone is reachable) or nothing (it will be an empty file). So in the next line we read the file in (actually just one character) and test the length – if it’s zero, then that’s when we do the unreachable processing. If it’s non-zero, we send the call to voicemail. EDIT: In Asterisk 1.6 and later there’s no need to create a temporary file.

I’m not saying this is the best way to do this, or the only way to do it, but it is a way that seems to work in VERY limited testing (at least on a system running Asterisk 1.4.35 and FreePBX 2.5).

This was inspired by a thread I saw on the PBX in a Flash forum, which also notes that there may be an even better way to do this in Asterisk 1.8, but since I don’t have it and VERY few FreePBX users are running 1.8 at this time, I’m not even going to touch that one.

EDIT: I did a VERY limited test of this (and made one change in the above code as a result) on an Asterisk 1.8 system running F—PBX 2.8. There are now two code sections above, one for those running Asterisk 1.4 or earlier, and one for those running Asterisk 1.6 or later (only tested with Asterisk 1.8). And before you try that “even better way” mentioned in the last paragraph, note that “Having chan_sip set HASH(SIP_CAUSE,) on the channel carries a significant performance penalty because of the usage of the MASTER_CHANNEL() dialplan function” and that Digium has “decided to disable this feature by default in future 1.8 versions” (see this page for more information). So, probably best to stick with the method shown here, if you can get it to work for you.

Review of FreeSWITCH 1.0.6 by Anthony Minessale, Darren Schreiber, Michael S. Collins (Packt Publishing)

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog. In order to comply with Federal Trade Commission regulations, I am disclosing that he received a free product sample of the item under review prior to writing the review, and that any links to Amazon.com in this article are affiliate links, and if you make a purchase through one of those links I will receive a small commission on the sale.
Cover of FreeSWITCH 1.0.6

In case you’ve never heard of FreeSWITCH, it is a “telephony software engine”, which means it’s in the same category as Asterisk. Over the years I’ve noticed that some Asterisk users have become frustrated with Asterisk due to unfixed bugs and design flaws that mean that the software doesn’t always work as it should. So, for quite some time, I’d hoped that a viable alternative to Asterisk might emerge, if only to keep the Asterisk developers on their toes. Competition between software projects tends to be a healthy thing, and from what I’ve read in this book, it appears that FreeSWITCH just may be the software product that eventually replaces Asterisk as the open source telephony software engine.

Before I begin, as is my custom with such reviews, let’s start with a quick overview of what’s in each chapter (for the complete Table of Contents, see the Packt Publishing web site):

  • Preface
  • Chapter 1: Architecture of FreeSWITCH – includes notes on the FreeSWITCH design and important modules
  • Chapter 2: Building and Installation – how to build and run FreeSWITCH under Linux/Unix, Mac OS X, or Windows
  • Chapter 3: Test Driving the Default Configuration – here you learn how to control FreeSWITCH with the CLI and to make your first call
  • Chapter 4: SIP and the User Directory – includes adding users, setting up voicemail, and setting up a gateway to connect to the world (link is to sample chapter in PDF format at the Packt Publishing site)
  • Chapter 5: Understanding the XML Dialplan – this gets into the “meat” of FreeSWITCH dialplan creation
  • Chapter 6: Using the Built-in XML IVR Engine – here’s where you learn one way to build an IVR (auto-attendant)
  • Chapter 7: Building IVR Applications with Lua – really an example of using a scripting language with FreeSWITCH. A few other languages are supported
  • Chapter 8: Advanced Dialplan Concepts – if Chapter 5 was the hamburger, this is the sirloin
  • Chapter 9: Controlling FreeSWITCH Externally – explains the event system architecture, and how to read and send events
  • Chapter 10: Advanced Features and Further Reading – includes multi-user conferencing, billing, XML/Curl, alternative endpoints, and configuration tools and related projects

There are also two appendices:

  • Appendix A: The FreeSWITCH Online Community
  • Appendix B: The History of FreeSWITCH

The  Packt Publishing web site also has this to say about the book:

What you will learn from this book :

  • Set up a basic system to make and receive phone calls, make calls between extensions, and utilize basic PBX functionality
  • Avoid common implementation mistakes and deploy various features of this telephony system with best practices and expert tips
  • Perform routine maintenance for smooth running and troubleshoot the system when things are not going right
  • Apply regular expressions to unlock unique and powerful call routing scenarios
  • Call your own application(s) when particular events occur and control FreeSWITCH using the powerful Event Socket
  • Set up multi-party conferencing facilities for your system
  • Interact with callers, gather information, and route calls to the appropriate recipient using the automated, built-in XML IVR (Interactive Voice Response) engine
  • Create a flexible dialplan, and allow third-party tools to be quickly and easily created using dialplan parsers other than the default XML Dialplan
  • Park multiple calls in a FIFO queue and unpark them in the order in which they were received, using the mod_fifo module
  • Record an entire phone call or session using the call recording feature
  • Create advanced call control applications with the Lua scripting language
  • Take a peek into the vibrant online community and history of FreeSWITCH

Approach

This book is a step-by-step tutorial with clear instructions and screenshots to guide you through the creation of a complete, cost-effective telephony system. You will start with installation, walk through the different features, and see how to manage and maintain the system.

Who this book is written for

If you are an IT professional or enthusiast who is interested in quickly getting a powerful telephony system up and running using the free and open source application FreeSWITCH, this book is for you. Telephony experience will be helpful, but is not required.

Now, here are my impressions. Please bear in mind that I did not actually attempt to build a working FreeSWITCH installation (I would need yet another spare computer to do that), but I certainly feel as though I could after reading this book. One thing that is somewhat uncommon about this book is that the author of the software is also one of the authors of the book. Too often, when you see a book written about a piece of software, the writer doesn’t fully understand the software and therefore makes guesses and assumptions about how it works, that may lead to problems down the road if you follow their advice. When the software author collaborates on the book, that’s far less likely to happen, and indeed, at no point in this book did I get the feeling that the author was struggling to understand the subject. I will even go so far as to say that this is one of the best written technical books I have read in a long time.

The biggest complaint I had about this book — and it is a very minor one — is that it could have benefited from another proofreader. Occasionally I’d see an obvious error that the proofreader should have caught — nothing major, and nothing I couldn’t figure out with about two seconds of thought, with one exception.  On page 91 of the book, it appears to me as though there is some missing text at the bottom of the page.  It’s discussing making a test call to Music on Hold and then, suddenly and jarringly, it jumps into a time of day example.  I think the disconnect occurs in middle of a sentence: “In our example, call the debug output is as follows:”  The sentence as written does not make sense to me, and it appears a block of text (perhaps a large one) may have been omitted at this point. But that is the only place in the book where I encountered an error of that magnitude. I have submitted the error to Packt Publishing and I’m hoping they will figure out what was supposed to go there and place it in the errata section of their web site.

One other point I will make about a software author writing a book on his own creation is that I think sometimes, it’s difficult for the author to correctly envision how end users will want to use the software.  As an example, virtually all the dialplan examples in this book are in XML.  There may be advantages to using XML, but it’s not going to be very familiar to someone coming from an Asterisk background, and I might have wished for a few non-XML examples.  On pages 158-159, the author notes that,

There is a common misconception that the FreeSWITCH Dialplan is based on, and requires, XML. That is simply not true. If you prefer flat files, you could use them to store your Dialplan configuration. If you prefer YAML, you could use that, too. You just need to load the correct C-based Dialplan module to interpret your stored logic for the particular type of configuration file you want FreeSWITCH to utilize.

This aside, the most common (and currently, the most robust) Dialplan processing mechanism in FreeSWITCH is still the XML-based Dialplan module. Most Dialplan examples that are shipped with FreeSWITCH, or those scattered on the Web are in XML, therefore, they will remain the focus of this chapter. …..

Indeed, there is even an Asterisk dialplan module, albeit with limited capabilities.  From page 199:

If you are used to the Asterisk Dialplan, some basic functionality is provided by the Asterisk Dialplan module, although it is not nearly as feature-rich as the XML engine. You can process contexts and route calls to phones using the Asterisk Dialplan. This module, again, is more of a sample on how to build an alternate Dialplan processing module and should not be utilized as a full, feature-rich Dialplan system.

Yet you won’t find examples using flat files, YAML, or Asterisk Dialplan in the book.  However, the XML examples were clearly written and easy to understand, so I don’t think that there would be a steep learning curve to start writing dialplans in XML, assuming you are a proficient enough coder to write dialplans in the first place.  And, I suspect that XML would be easier for a new user to pick up than any of the other options.

I mention the above to emphasize two points:  FreeSWITCH is different from Asterisk. If you are thinking about moving from Asterisk to FreeSWITCH, you need this book to get you up to speed on the differences.  And second, FreeSWITCH is both more capable than Asterisk, and arguably easier to use, once you get used to the differences (or if you have no prior experience with similar software). FreeSWITCH appears to have been designed from the ground up to avoid the issues that have plagued Asterisk, particularly those that cause Asterisk to fall to its knees under heavy load or heavy call volumes. Even if you’re a long-time Asterisk user, you may want to get this book just to see what you’re missing.  You might decide that it’s worth your effort to set up a test system using FreeSWITCH, to help you understand how much better the next generation of telephony software engines can be.

One other point, in case you are reading this review several months after I wrote it — the author notes this in the preface:

At the time of this writing this book, the FreeSWITCH developers were putting the finishing touches on FreeSWITCH version 1.2. While the examples presented in this book were specifically tested with version 1.0.6, they have also been confirmed to work with the latest FreeSWITCH development versions that form the basis of version 1.2. Do not be concerned about the fact that this material does not cover version 1.2—it certainly does. The FreeSWITCH user interface is very stable between versions; therefore, this text will be applicable for years to come.

There will no doubt be some of you who are reading this that wonder if there are any Web GUI “front ends” (dialplan and configuration file generators) for FreeSWITCH.  Indeed there are, and they are covered in Chapter 10, which briefly explains the differences between WikiPBX, FreePBX v3, FusionPBX, and 2600hz.  Even if you plan on using a Web GUI, there may be times when you find the need to write a bit of custom code, and in that case having this book available would definitely be helpful to you.

One other thing I personally found interesting in this book was Appendix B, “The History Of FreeSWITCH.”  This explains how FreeSWITCH came to be, and along the way offers further explanation on how it is different from Asterisk and why the developers felt the need to start a new project.  What I think I found most interesting (and perhaps unfortunate, depending on your point of view) is that FreeSWITCH could have been the basis for Asterisk version 2, had only the Asterisk developers reacted positively to the idea. I see this sort of thing happen occasionally in the open source community, where the lead developers of a project start to develop an attitude that does not encourage outside contributions (or, they treat contributions or suggestions for improvement as if they were piles of steaming dog poo on their doorstep). Perhaps this should serve as a cautionary tale to such developers that your project can always be replaced by something better, if you do not encourage contributions to your own project from those not currently in your “inner circle” of developers.

As you may know if you have read my previous reviews, it’s rare that I get wildly enthusiastic about a book.  In this case I’ll make an exception, because overall the book is that well-written (my comments above notwithstanding). If you have any interest at all in using FreeSWITCH, or are even just curious about it, you really should buy this book.  It’s available in both traditional softcover dead-tree format, and as a DRM free Adobe PDF eBook, and there’s even a package deal if you want both formats. Don’t forget that you can view a sample chapter (PDF format) prior to purchase. EDIT: Also, there is an online article by the book’s authors entitled FreeSWITCH: Utilizing the Built-in IVR Engine.

FreeSWITCH 1.0.6 by Anthony Minessale, Darren Schreiber, Michael S. Collins (Amazon affiliate link)

Related: Review of FreeSWITCH Cookbook by Anthony Minessale, Michael S Collins, Darren Schreiber, Raymond Chandler (Packt Publishing)

A Perl script to send Caller ID popups from Asterisk to computers running Growl under OS X on a Mac or Growl for Windows

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.
Notice
EDIT March, 2014 and August 2020: If you are running OS X Mavericks or later, or any version of MacOS we recommend that you do NOT use the script shown here, but instead send notifications to a XMPP/Jabber account and use either Apple’s Messages app (formerly iChat) or a third party messaging program such as Adium to receive them, since the message will then display in the Notifications Center and you do not need Growl. See How to send various types of notifications on an incoming call in FreePBX for more information. You may also find this thread on the RasPBX forum useful.

What follows will probably not work on ANY currently supported version of MacOS and is left here as a historical reference only.

Quite some time ago, I wrote a post explaining how you could poll a Linksys or Sipura VoIP adapter or phone once per second, and whenever there was an incoming call, generate a notification popup on your computer, if you have the Growl notification service installed.  However, that method doesn’t work if you’re not using a Linksys or Sipura phone or device.

If you are running Asterisk, there’s another way to do it, and that’s to get Asterisk to send the notifications directly. In order for this to work, the computer on which you want to receive the notifications has to be running Growl (under Mac OS X) or Growl for Windows. You must also configure Growl to receive network notifications. I will note here that if you are using a Mac and have never done that before, you may want to make sure that Growl network notifications work before proceeding, because it appears that under OS X, it’s pretty much a crap shoot whether Growl network notifications will work at all, and when they don’t the Growl folks apparently have no clue as to why they don’t. It seems to be a machine-specific thing – on some Macs they work fine, while on others they don’t work at all.

You must have the Perl language installed on your Asterisk server, and you must have the Net::Growl and Asterisk::AGI modules installed (I’m going to assume you know how to install a Perl module from the CPAN repository – if you have Webmin installed, it can be done from within Webmin). Chances are you already have Asterisk::AGI installed, unless you built your Asterisk server “from scratch” and never installed it, but if you’ve never installed Net::Growl you’ll need to do that first.

Next you want to copy and paste the following Perl script to the filename /var/lib/asterisk/agi-bin/growlsend.agi on your Asterisk server (to create a non-existent file, you can use the touch command, and after that you can edit it in Midnight Commander or by using the text editor of your choice). If this code looks somewhat familiar, it’s because it’s adapted from some code that originally appeared in a FreePBX How-To, which I modified.

#!/usr/bin/perl
use strict;
use warnings;
use Net::Growl;
use Asterisk::AGI;
my $agi = new Asterisk::AGI;
my %input = $agi->ReadParse();
my $num = $input{'callerid'};
my $name = $input{'calleridname'};
my $ext = $input{'extension'};
my $ip = $ARGV[0];

if ( $ip =~ /^([0-9a-f]{2}(:|$)){6}$/i ) {
    $ip = $agi->database_get('growlsend',uc($ip));
}

unless ( $ip =~ /^(d+).(d+).(d+).(d+)$/ ) {
    exit;
}

open STDOUT, '>/dev/null';
fork and exit;

if ( $ARGV[2] ne "" ) {
    $ext = $ARGV[2];
}

# Define months and weekdays in English

my @months = (
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
);
my @weekdays = (
    "Sunday", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday"
);

# Construct date/time string

my (
    $sec, $min, $hour, $mday, $mon,
    $year, $wday, $yday, $isdst
) = localtime(time);
my $ampm = "AM";
if ( $hour > 12 ) {
    $ampm = "PM";
    $hour = ( $hour - 12 );
}
elsif ( $hour eq 12 ) { $ampm = "PM"; }
elsif ( $hour eq 0 ) { $hour = "12"; }
if ( $min < 10 ) { $min = "0" . $min; }
$year += 1900;

my $fulldate =
"$hour:$min $ampm on $weekdays[$wday], $months[$mon] $mday, $year";

# Next two lines normalize NANP numbers, probably not wanted outside of U.S.A./Canada/other NANP places
$num =~ s/^([2-9])(d{2})([2-9])(d{2})(d{4})$/$1$2-$3$4-$5/;
$num =~ s/^(1)([2-9])(d{2})([2-9])(d{2})(d{4})$/$1-$2$3-$4$5-$6/;

register(host => "$ip",
    application=>"Incoming Call",
    password=>"$ARGV[1]", );
notify(host => "$ip",
    application=>"Incoming Call",
    title=>"$name",
    description=>"$numnfor $extn$fulldate",
    priority=>1,
    sticky=>'True',
    password=>"$ARGV[1]",
    );

Also, if you want to be able to specify computers that you wish to send notifications to using MAC addresses rather than IP addresses (in case computers on your network get their addresses via DHCP, and therefore the IP address of the target computer can change from time to time), then you must in addition install the following Perl script. It requires a command-line utility caller arp-scan so install that if you need to – I used to use nmap for this but they changed the output format, making it harder to parse, and arp-scan is much faster anyway. Call it /var/lib/asterisk/agi-bin/gshelper.agi and note that there are two references to 192.168.0… within it that you may need to change to reflect the scope of your local network, if your network’s IP addresses don’t start with 192.168.0.:

#!/usr/bin/perl
use strict;
use warnings;
my @mac;
# Change the following lines to reflect the scope of your local network, if necessary
my @arp = `arp-scan --quiet --interface=eth0 192.168.0.0/24`;
foreach (@arp) {
        if (index($_, "192.168.0.") == 0) {
                @mac = split(" ");
                `/usr/sbin/asterisk -rx "database put growlsend \U$mac[1] $mac[0]"`;
        }
}

Make sure to modify the permissions on both scripts to make them the same as other scripts in that directory (owner and group should be asterisk, and the file should be executable), and also, if you use the gshelper script, make sure to set up a cron job to run it every so often (I would suggest once per hour, but it’s up to you).

Now go to this page and search for the paragraph starting with, “After you have created that file, check the ownership and permissions” (it’s right under a code block, just a bit more than halfway down the page) and if you are using FreePBX follow the instructions from there on out (if you are not using FreePBX then just read that section of the page so you understand how this works, and in any case ignore the top half of the page, it’s talking about a different notification system entirely).  But note that if you use the above code and have the gshelper.agi program running as a cron job, then after the first time it has run while the computer to receive the notifications is online you should be able to use a computer’s MAC address instead of the IP address.  This only works if you’ve used the modified script on this page, not the one shown in the FreePBX How-To.  As an example, instead of

exten => ****525,1,AGI(growlsend.agi,192.168.0.123,GrowlPassWord,525)

as shown in the example there, you could use

exten => ****525,1,AGI(growlsend.agi,01:23:45:AB:CD:EF,GrowlPassWord,525)

(the above is all one line) where 01:23:45:AB:CD:EF is the MAC address of the computer you want to send the notification to.  Once again, just in case you missed it the first time I said it, this won’t work until the gshelper.agi script has been run at least once while the computer to receive the notifications was online.  If for some reason it still doesn’t appear to work, run the nmap command including everything between the two backticks (`) directly from a Linux command prompt and see if it’s finding the computer (depending on the size of your network, it might be several seconds before you see any output, which is why I don’t try to run this in real time while a call is coming in).

If you are NOT running FreePBX, but instead writing your Asterisk dial plans by hand, then you will have to insert a line similar to one of the above examples into your dial plan, except that you don’t need the four asterisks (****) in front of the extension number, and if it’s not the first line in the context, you’ll probably want to use n rather than 1 for the line designator (and, you won’t be putting the line into extensions_custom.conf because you probably don’t have such a file; instead you’ll just put it right in the appropriate section of your dial plan).  In other words, something like this (using extension 525 as an example):

exten => 525,n,AGI(growlsend.agi,192.168.0.123,GrowlPassWord,525)

This line should go before the line that actually connects the call through to extension 525.  I do not write Asterisk dial plans by hand, so that’s about all the help I can give you. And if you don’t write your dial plans by hand, but you aren’t using FreePBX, then I’m afraid you’ll have to ask for help in whatever forum you use for advice on the particular software that you do use to generate dial plans, because I can’t tell you how to insert the above line (or something like it) into your dial plan.

Virtually everything in this article has already been published in one place or another, but I wanted to get it into an article with a relevant title and cut out some of the extraneous explanations and such.  There are links to all the original sources throughout the article, so feel free to follow those if you want more in-depth commentary.

Geolock — a Perl script for Asterisk or FreePBX users to enhance security

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

I created the following Perl script and have been running it for a week or so, and it seems to be working well.  The idea is that this script runs once per minute, and whenever a SIP or IAX extension is registered with your Asterisk system the script looks at the IP address that the extension is registering from, and if that address is outside your home country (the United States by default), the IP address is immediately banned using IPtables.  So, your remote extensions could be anywhere in your home country and connect to your system, but if a hacker from some other nation penetrates your system and somehow guesses one of your passwords, they will (in theory) have less than a minute to do any damage before they are banned. And once they are banned, the rightful user of that extension should still have no difficulty connecting, as long as they are not coming in from outside your home country.

For those of you that don’t have any extensions connecting from outside your home country, consider this another tool in your arsenal of defenses against intrusions.  Combine it with strong passwords, and Fail2Ban with IPtables for additional security.

NOTE THAT THIS SCRIPT IS NOT GUARANTEED TO DO ANYTHING AT ALL, other than take up space on your computer.  IT SHOULD STILL BE CONSIDERED EXPERIMENTAL until there has been more testing on it.  I believe it works properly, but have no way to do extreme testing on it to see if or how it might break. THERE IS NO WARRANTY OF ANY KIND!!!

Prerequisite: Obviously, you must have IPtables installed and functioning properly, and you must install either the Geo::IP or Geo::IP::PurePerl Perl module (do NOT install both!). You can install one of these using Webmin (using Webmin’s Others | Perl modules page), or in any other way you usually install Perl modules (e.g. CPAN). The difference between the two was explained in my original article, as follows:

… there is a Perl module called Geo::IP, which calls the GeoIP C API. If you install that API (when downloading, I’d go into the test/ directory and get the latest beta) using the directions on the linked page, and then install the Perl module (you must do it in that order, or installation of the Perl module will fail), you could run a Perl script that shows the location that your off-site extensions are coming in from. If you don’t want to install the API, or can’t figure out how (not difficult if you follow the directions), you can use the Geo::IP::PurePerl Module which is slower, but does not require the additional C library. Just so you know, GeoIP puts its data file at /usr/local/share/GeoIP/GeoIPCity.dat and they suggest that you go to http://www.maxmind.com/download/geoip/database/ every month or so to grab the latest database (the full link for the country database is currently http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz or you can get a much larger city-level database at http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz — just make sure you don’t grab a CSV version by mistake!). If you need them, there are installation instructions for the database, although they are primarily for the city-level database. If you buy an account, they’ll give you automatic updates, though I can’t imagine it would be that hard to write a script to do that (or maybe Google could help you find one, or see this message thread).

If the above is confusing to you, I’d stick with the Geo::IP::PurePerl Module. That should at least get you going. You also need the Perl Sys::Syslog module (unless you want to omit all the syslog-related instructions), though chances are you may already have that one.

Now, here is the Perl script. I called it geolock.pl (although you are free to name it whatever you want), and I put it in the /var/lib/asterisk/agi-bin/ directory and made it executable. Note this is in a code block so the long lines will overflow the column width, so you need to copy and paste this into a text editor. Also there are certain lines you will need to change, as explained below:

#!/usr/bin/perl
use strict;
use warnings;
use Geo::IP;
use Sys::Syslog;
my $gi = Geo::IP->new(GEOIP_STANDARD);
my ($ext, @peerline, @extension, $ipaddress, $country, $shellcmd);
my $flag = 0;

my @sippeers = `asterisk -rx "sip show peers" | grep -v 192.168.0. | grep ^[1-9] | grep -v "(Unspecified)" | grep / | sort -n`;
# change grep statements in above line to match your local IP range (1st grep) and first digits of extensions (2nd grep)
foreach (@sippeers) {
@peerline = split(" ");
$ipaddress = $peerline[1];
$country = $gi->country_code_by_name($ipaddress);
@extension = split("/",$peerline[0]);
$ext = $extension[0];
#    print "Extension $ext has IP address $ipaddress which is in country $countryn";
if ($country && $country ne 'US') {
$shellcmd = `iptables -D INPUT -p ALL -s $ipaddress -j DROP 2>&1`;
system("iptables -A INPUT -p ALL -s $ipaddress -j DROP");
openlog($0,'pid','user');
syslog('notice', "Banning IP address $ipaddress in $country because Asterisk SIP Extension $ext is connecting from there");
closelog;
if (index($shellcmd, "Bad rule") >= 0) {
$shellcmd = 'echo "This is an automated message - please do not reply. IP address ' . $ipaddress . ' in country ' . $country . ' was banned in iptables because Asterisk SIP extension ' . $ext . ' was connecting from there." | mail -s "IP address banned on Asterisk box" root@localhost';
system($shellcmd);
$flag = 1;
}
}
}

### INCLUDE THIS NEXT SECTION ONLY IF YOU HAVE IAX2 EXTENSIONS ###
my @iaxpeers = `asterisk -rx "iax2 show peers" | grep -v 192.168.0. | grep ^[1-9] | grep -v "(Unspecified)" | grep -v "iax2 peers" | sort -n`;
# change grep statements in above line to match your local IP range (1st grep) and first digits of extensions (2nd grep)
foreach (@iaxpeers) {
@peerline = split(" ");
$ipaddress = $peerline[1];
$country = $gi->country_code_by_name($ipaddress);
$ext = $peerline[0];
#    print "Extension $ext has IP address $ipaddress which is in country $countryn";
if ($country && $country ne 'US') {
$shellcmd = `iptables -D INPUT -p ALL -s $ipaddress -j DROP 2>&1`;
system("iptables -A INPUT -p ALL -s $ipaddress -j DROP");
openlog($0,'pid','user');
syslog('notice', "Banning IP address $ipaddress in $country because Asterisk IAX2 Extension $ext is connecting from there");
closelog;
if (index($shellcmd, "Bad rule") >= 0) {
$shellcmd = 'echo "This is an automated message - please do not reply. IP address ' . $ipaddress . ' in country ' . $country . ' was banned in iptables because Asterisk IAX2 extension ' . $ext . ' was connecting from there." | mail -s "IP address banned on Asterisk box"
root@localhost';
system($shellcmd);
$flag = 1;
}
}
}
### END OF SECTION ONLY NEEDED IF YOU HAVE IAX2 EXTENSIONS ###

if ($flag == 1) {
`asterisk -rx "restart now"`;
}
else {
openlog($0,'pid','user');
syslog('info', "Completed normally");
closelog;
}

These are the things you need to change for your local installation:

  • If you used the Geo::IP::PurePerl module then be sure to change the two references to Geo::IP to Geo::IP::PurePerl.
  • Remove the optional section for IAX2 extensions if you don’t have any of those (but keep it if you have any IAX2 extensions, even if they are only internal ones).
  • In the line(s) “if ($country && $country ne ‘US’) {” change US to the code for your home country if you are somewhere else in the world. You could also create a more expansive conditional statement here to allow multiple countries, or a more restrictive ones if you want to block an IP that doesn’t resolve to any country (I consider that a database error, but maybe you don’t). If you have installed the city-level database, you could even (in theory) test for something other than country, such as a state or province, city, time zone, ISP, etc. This line appears in the SIP section and also the optional IAX2 section, so make sure you change both lines if necessary.
  • There are two instances of root@localhost in the above script (in the SIP section and also the optional IAX2 section), which you should change to a valid e-mail address if you want to receive e-mail notifications when an IP address is banned. If you don’t want to receive such e-mail notifications, then comment out or remove those two lines in their entirety (they start with: $shellcmd = ‘echo “This is an automated message …) and also remove the following system($shellcmd); line(s).

The following apply to the two lines that begin with "my @sippeers” and, in the optional IAX2 section, “my @iaxpeers”:

  • Change “grep -v 192.168.0.” to a regular expression or pattern that will match it IP address of all extensions on your local network.  The pattern as shown works if all your local extensions will be in the range 192.168.0.x. Since you can use a regular expression, you could do something like “grep -v 192.168.[1-5].” which would match any local address from 192.168.1.0 through 192.168.5.255.
  • Change grep ^[1-9] to match the first digit of your extensions – as shown, anything starting with a digit 1 through 9 would be considered an extension.  The idea here is that we only want to look at extensions, not trunks (which you can restrict using permit and deny statements, if necessary). Most trunks don’t begin with a number (when you do a “sip show peers” or “iax2 show peers” listing from the CLI), so this is what separates extensions from trunks.  You may have to get a bit more creative if you have a trunk that starts with a number that overlaps your extensions. If you run the entire section between the backticks (the ` characters) from a Linux command prompt,  it should show you all of your connected non-local (that is, not on your internal network) SIP or IAX extensions (depending on which line you run), but no trunks, local extensions, offline extensions, or header information.

Sharp-eyed readers may observe that I first try to delete an iptables rule before creating it.  That’s because I don’t want to create the same rule multiple times (iptables happily accepts duplicates, unfortunately).  If I get an error when trying to delete the rule, then I know that what follows will be the first attempt to create it, and I should send an e-mail and restart Asterisk when we’re all finished.  Basically, it’s supposed to be a safety mechanism to keep from repeatedly sending the same e-mail, or restarting Asterisk once a minute if for some reason the iptables rule doesn’t “take” at first.

Again, don’t forget to make the Perl script executable, and run it manually a few times to watch the output (uncomment the commented-out “print” lines during initial testing – you can remove them once you are satisfied it’s working as it should be).  After you have run it a few times, from the Linux command prompt do iptables –list and make sure everything looks okay there.

One thing you should be aware of is that when this script detects an intrusion attempt (a connection from outside the United States), after it bans the IP address it restarts Asterisk, which will interrupt any calls in progress.  That’s deliberate; I assume you want to throw the hackers off your system right now, even if it means your users may have to re-dial their calls. Howerver, if for some reason you don’t want to do that, then you can change the line `asterisk -rx “restart now”`; to `asterisk -rx “restart when convenient”`;, which will wait until there is no usage on your system to restart Asterisk.  In that case, good luck to you if the hacker just placed a call to some $100-a-minute destination! In theory IPtables will interrupt the conversation (no audio will pass) BUT that does not mean Asterisk will tear the call down right away – when an extension “just disappears”, Asterisk tends to wait a LONG time to see if it will come back, and if it never does, well that’s what we call a “zombie” call — it just won’t die (at least not until the other end disconnects)! EDIT: If you don’t want to restart the whole system but do want to throw the hacker off NOW, see the modification by “Florent” in the comments below — I have NOT tested his changes personally, but they may do what you want.

The final step is to make this execute once a minute.  I used Webmin’s “System | Scheduled Cron Jobs” to set this up:

cron job setup using WebminBut if you are more comfortable creating a cron job from the command line, by all means, feel free to do so.

Finally, I always say that suggestions for improvement are welcome, and also, if you want to translate this into some other programming language, you have my blessing. Please be sure to test it thoroughly before relying on it, because if someone manages to hack through anyway, I’m not going to pay your phone bill! Once again, the above should be considered experimental code and is not guaranteed to do anything at all.

Mini-review of Sangoma U100 USBfxo device

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.

This article was originally posted in June, 2010.

I recently had the experience of trying to help someone make a Sangoma USBfxo device (model U100) work on a server that runs FreePBX and Asterisk. The advertised features of this device are as follows:

  • Dual FXO ports
  • Easy installation, no need to open up computer to install PCI/PCIe card
  • Supports up to 2 simultaneous calls
  • Compact plastic enclosure
  • Low power consumption, takes power from USB bus
  • USB 2.0 compliant (compatible with USB 1.1)

The first thing I would note is that although you don’t have to open up the computer, it’s definitely not “plug and play.” At the very least you have to install driver software, and on an Asterisk server you will also need to install and configure DADHI or ZAPTEL (unless this has already been done). Depending on your level of expertise, this might be easy, or quite daunting. I would certainly take issue with the claim of “easy installation” although I can understand how a true Linux geek might consider it a walk in the park. It wasn’t so much that there were any major hitches in the installation as that it was time consuming and required quite a bit of mental effort to figure out what needed to be done — someone who has just set up a PBX using a “load and go” distribution like Elastix, PBX in a Flash, AsteriskNOW, Trixbox, etc. might not find it all that easy to get this thing working.

The major issue we had was with the performance. We initially discovered that it was “clipping” speech severely, causing audio artifacts that are difficult to describe in print, but unpleasant to hear. We got in touch with Sangoma customer support and finally traced the problem to the built in hardware echo cancellation. By disabling the hardware echo cancellation, the speech was clear, but of course we then had mild echo. Enabling echo cancellation in Zaptel fixed that on a temporary basis, but about a week later Sangoma customer support e-mailed us and suggested that we try OSLEC, the open source echo canceler. We might have actually done that had we not discovered another issue in the meantime, that made us decide we didn’t want to mess with this unit anymore.

This new issue was that initially, it did not pick up incoming caller ID on incoming calls. We discovered that this could be fixed by changing the gain settings in Zaptel, but even when we did that it still wasn’t 100% reliable (I’d say it worked about 90% of the time). And, the downside of that was that we had to reduce the incoming gain, so that it was harder to hear callers.

We’ve used Sipura SPA-3000’s before for this same function, although they are only single line units (they have one FXS port and one FXO port) and have never had any of these issues. The main reason we tried the USBfxo was because we wanted two FXO ports, and also liked the idea that it was powered off the USB cable, and didn’t require us to have yet another device with a “wall wart” to plug in. But the difficulties with Caller ID, volume levels, and the fact that Sangoma had apparently given up on getting the hardware echo cancellation to work without distorting the audio led us to get frustrated with this device fairly quickly. The non-techies that had to make and receive calls that went through this device were not very understanding of the issues, especially since the SPA-3000’s (now superseded by the Linksys SPA-3102, which is essentially an updated version of the Sipura SPA-3000) had always worked much more reliably. We finally gave in and found another Sipura SPA-3000 on eBay and put it into service, and within a relatively short time (part of which was spent locating and installing updated firmware) it was working like a champ. Unlike the Sangoma, it detects the Caller ID 100% of the time, and we can tweak the transmit and receive gain to comfortable levels.

My personal opinion is that Sangoma should be ashamed to put their name on the USBfxo.  The hardware echo cancellation, in a word, sucks.  And one of the big reasons you’d buy a brand like Sangoma in the first place is because of the supposedly superior echo cancellation.  Echo cancellation is supposed to cancel echo, not make it sound like your words are clipped.  My guess is that the hardware echo cancellation is far too aggressive and they don’t give you any way to “tune” it — you can either enable or disable it, but that’s all.  The USBfxo is a great idea, but it needs to go back to the drawing board. Sangoma’s motto (shown on their Wiki pages, etc.) is “Because it must work!”, but apparently that motto does not imply that it must work well!

Also, a note to Sangoma customer service — next time a customer is dropping hints that they’d like you to take your defective unit back and send a replacement, you might want to be a bit more responsive to that request. We were willing to work with you up to a point but the message came through loud and clear that you really didn’t want to replace this dog of a device unless you absolutely had to.  We didn’t sign up to be beta testers, we just wanted the damn thing to work. Given Sangoma’s (perhaps undeserved) reputation we really thought you’d be more agreeable to making sure that we got a unit that worked, not making us try a bunch of different things and then ultimately told to try OSLEC, effectively giving up hope that the hardware echo cancellation would ever work properly.

Another suggestion to Sangoma (or any other manufacturer that may be listening) — most of us who did not cut our teeth on Linux would probably prefer not to have to mess with ZAPTEL or DADHI.  The nice thing about the Linksys/Sipura devices is that they sit out on the network and appear as just another SIP-based device, and in FreePBX you configure them pretty much as you would any other SIP trunk.  I’m not saying that installing any of these devices is the proverbial “piece of cake”, especially if you have never done it before, but when you have to start installing and configuring drivers, that goes outside of the realm of what I would consider easy to install. What someone really needs to come out with is an inexpensive four to six-port SIP based FXO device that sits out on your local network, like the SPA-3000/3102.

If you are in need of one or two FXO ports for your Asterisk server, my advice would be to first try one or two Sipura SPA-3000 or Linksys SPA-3102 devices (following these instructions if you are a FreePBX user) — if those do not work the way you’d like, you can always resell them on eBay and then try a more expensive solution.  If your server doesn’t have card slots (as is increasingly the case, as users turn to small computers like the Acer Aspire Revo to use as small, power-efficient PBX’s) then your choices are limited to external devices such as the aformentioned units. However, if your system can accept internal cards, then you can buy cards that provide FXO ports from several manufacturers, including Digium and Sangoma (if you need eight or more FXO ports than I believe there are other external options, but they are quite a bit more pricey and I have not really investigated them, so I won’t comment on them at this point.  However, if any manufacturer would care to send a review sample, I’d be more than happy to give it a try!). 😉

The one caveat I will add is that not every device will work on every line.  If you have a very long line from a traditional telephone company, your requirements (and experience with a particular device) may be quite different from someone who is sitting 500 feet from the central office, or someone who’s trying to take the output of a cable company’s VoIP adapter and pipe it over to the FXO card or device using twenty feet of copper wire. Just because the Sipura devices have worked better for us does not mean they will for you. I’m guessing that some people have purchased the exact same Sangoma device that we tried and were able to get it working well enough for their needs, but I just cannot recommend this device — at least not until Sangoma fixes the echo cancellation, and makes it read the incoming Caller ID reliably 100% of the time, preferably without having to change the incoming gain in DADHI or ZAPTEL.

EDIT: For more comments/opinions on this device (and on this review), see this thread on the PBX in a Flash forum.

Mini-review of Beginning OpenVPN 2.0.9 by Markus Feilner and Norbert Graf (Packt Publishing)

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog. In order to comply with Federal Trade Commission regulations, I am disclosing that he received a free product sample of the item under review prior to writing the review, and that any links to Amazon.com in this article are affiliate links, and if you make a purchase through one of those links I will receive a small commission on the sale.
Cover of Beginning OpenVPN 2.0.9

I have previously reviewed the title, “Review of OpenVPN: Building and Integrating Virtual Private Networks by Markus Feilner“, and this is the updated and expanded version of that book. The publisher says that all examples in the book work with version 2.0.9 and 2.1 of OpenVPN. Since the original book was released in 2006, it was definitely due for an update!

Here’s what the publisher wants you to know about the book (my comments will follow):

In Detail

OpenVPN is a powerful, open source SSL VPN application. It can secure site-to-site connections, WiFi, and enterprise-scale remote connections. While being a full-featured VPN solution, OpenVPN is easy to use and does not suffer from the complexity that characterizes other IPsec VPN implementations. It uses the secure and stable TLS/SSL mechanisms for authentication and encryption. This book is an easy introduction to this popular VPN application. After introducing the basics of security and VPN, it moves on to cover using OpenVPN, from installing it on various platforms, through configuring basic tunnels, to more advanced features, such as using the application with firewalls, routers, proxy servers, and OpenVPN scripting.

This is a practical guide to using OpenVPN for building both basic and complex Virtual Private Networks. It will save you a lot of time and help you build better VPNs that suit your requirements. While providing only necessary theoretical background, the book takes a practical approach, presenting plenty of examples. It starts with an introduction into the theory of VPNs and OpenVPN, followed by a simple installation example on almost every available platform. After a concise and ordered list of OpenVPN’s parameters, we dive into connecting several machines in a safe way. The last third of the book deals with professional and high-end scenarios, and also mobile integration. After having read the whole book and followed and understood all the examples, you will be an expert in VPN, Security, and especially in OpenVPN Technology. This book was written for version 2.0.9 of OpenVPN, but all examples have been tested and run smoothly on version 2.1 too.
Read the full Table of Contents for Beginning OpenVPN 2.0.9

What you will learn from this book

  • Install OpenVPN on Windows Server, Vista, and Mac OS X and also on different Linux versions and FreeBSD
  • Learn basic security concepts necessary to understand VPNs and OpenVPN in particular
  • Take a look at encryption matters, symmetric and asymmetric keying, and certificates
  • Connect Windows and Linux systems and safely transfer the necessary encryption keys using WinSCP
  • Learn about OpenVPN, its development, features, resources, advantages, and disadvantages compared to other VPN solutions, especially IPsec
  • Discuss non-standard and advanced methods of installing OpenVPN by compiling the source code provided by the OpenVPN project
  • Create an encryption key for OpenVPN and use it to set up an OpenVPN tunnel between two Windows systems in the same network
  • Create X.509 server and client certificates for use with OpenVPN and learn how to use tools to debug and monitor VPN tunnels
  • Create and administer certificates that have to be transferred to the machines that are supposed to take part in the VPN
  • Configure two different firewall networks that connect to each other through the secure OpenVPN tunnel
  • Install and use XCA and TinyCA2 to generate certificate revocation lists that are used to block unwanted connections by formerly authorized clients
  • Install OpenVPN on Windows Mobile and Smartphones running embedded Linux, like Nokia’s Maemo platform
  • Analyze the flow of datagrams between the VPN servers and the connected networks with tools like ifconfig, ping, traceroute, and mtr

Approach

This book is an easy introduction to OpenVPN. While providing only necessary theoretical background, it takes a practical approach, presenting plenty of examples. It is written in a friendly style making this complex topic easy and a joy to read. It first covers basic VPN concepts, then moves to introduce basic OpenVPN configurations, before covering advanced uses of OpenVPN.

Who this book is written for

This book is for both experienced and new OpenVPN users. If you are interested in security and privacy in the internet, or want to have your notebook or mobile phone connected safely to the internet, the server in your company, or at home, you will find this book useful. It presumes basic knowledge of Linux, but no knowledge of VPNs is required.

Now back to my mini-review. If you read my original review (which explains why I think a VPN can be an important part of securing private VoIP networks, among other uses), you know that I found Mr. Feilner’s original book quite helpful in giving me a grasp on VPNs, a subject I’d known very little about prior to that point. There were a few things I thought could have been covered better, though, so I was interested to see if those things had been addressed in this updated edition.

As I had more or less noted, the author seemed to slightly prefer SuSE Linux over other versions of Linux, and the Shorewall firewall over other Linux firewall solutions, and (in my opinion) the new book still uses more pages than are really necessary talking about how to set up and configure Shorewall, but at least now the authors do provide some minimal information about the far more popular iptables firewall tool (a little over three pages). It would have been nice to see a more in-depth treatment of this subject, because sometimes setting up iptables correctly is one key to getting your VPN to work as you want it to, particularly if you need or want to do anything more complicated than a simple VPN tunnel. It’s a minor nit, to be sure, because there’s plenty of information on the web about how to set up and configure iptables, but I personally would have given that topic more than three pages.

Then I discovered they’d made one addition that I really wanted to see: A totally new chapter on OpenVPN GUI tools, and in particular, a section on Webmin’s OpenVPN plugin. My disappointment again was that this was not a more exhaustive treatment of the subject. Actually, it’s little more than a mention that the plugin exists, and a few screenshots.  Granted that this was more than appeared in the original volume, and just informing readers of the existence of that plugin is no small thing, but when I did my series on Setting up an OpenVPN tunnel using a CentOS-based system as the server and a router flashed with Tomato firmware as the client, it took me two parts to explain how to configure the Webmin plugin.  That same chapter also talks about some client GUI’s for Linux, but doesn’t spend more than a page or two on any of them.

I’m not really faulting the authors here — it’s very apparent that they write about what they know, and they definitely know their stuff when it comes to OpenVPN, whereas they may not be quite as familiar with Webmin or iptables.  That said, Windows users should find all the information they need to set up an OpenVPN tunnel and then some, and Linux newbies get enough information to at least point them in the right direction. As for Mac users, the coverage there is about the same as in the previous edition, which is to say that there’s about three pages on how to install Tunnelblick.  However, much of the information in the book is not OS specific, and those with some experience with Linux or OS X should have no trouble at all following along.

On a positive note, there are many examples and screenshots in the book, and in this one the screenshots are actually readable (well, I did need my reading glasses for a few of them, but then I’m getting to the point where I need my reading glasses to read the cooking directions on a frozen dinner!). And, the authors’ writing style is clear and easy to understand. Also, there’s a totally new (albeit relatively short) chapter on Mobile Security, which may be of interest to some of the “road warriors” out there.

So, my recommendation is this:  If you read Markus Feilner’s previous book on OpenVPN and liked it, you’re almost certainly going to want to read this one, just to get up to date.  If you didn’t read the previous edition but just want to get up to speed on OpenVPN, this really is one of the better books on the subject, provided that you understand that at times you may have to supplement the book with a bit of additional research on the Web, particularly if you are running OS X or Linux as your operating system (but at least you’ll have a much better handle on topics for additional research).

The reason this is a mini-review and not a full review is because due to personal/family issues I haven’t had time to do much more than skim through the new book, rather than give it a complete read as I normally prefer to do.  But since Packt Publishing kindly sent me the book over a month ago, I feel as though it’s a disservice to both them and to the readers of this blog to delay mentioning it any longer. Despite my comments about the paucity of additional pages on the particular topics I’d hoped to read more about, this is still a great book for those who need to set up and secure an OpenVPN tunnel, particularly if you’re just starting out and know next to nothing about VPNs and/or OpenVPN.

Beginning OpenVPN 2.0.9 by Markus Feilner, Norbert Graf (Amazon affiliate link)

Review of FreePBX 2.5 Powerful Telephony Solutions by Alex Robar (Packt Publishing)

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog. In order to comply with Federal Trade Commission regulations, I am disclosing that he received a free product sample of the item under review prior to writing the review, and that any links to Amazon.com in this article are affiliate links, and if you make a purchase through one of those links I will receive a small commission on the sale.

This article was originally published in September, 2009.

Cover of FreePBX 2.5 Powerful Telephony Solutions
Cover of FreePBX 2.5 Powerful Telephony Solutions

FreePBX 2.5 Powerful Telephony Solutions by Alex Robar (Packt Publishing) explains how to set up, configure, and maintain a powerful VoIP PBX using FreePBX.  For those not familiar with FreePBX, it’s a “front end” for the Asterisk PBX software. Asterisk can be thought of as the “engine” that runs the PBX, but FreePBX is the user interface.  It basically saves you the effort of writing Asterisk configuration files and dial plans by hand.  Instead, you enter all the requisite information in FreePBX’s web-based GUI, and then when you apply the configuration changes (by clicking an orange bar at the top of the screen), FreePBX (re)writes the Asterisk dial plan and configuration files on the fly. This means that making significant changes to the call flow within the PBX, or adding new extensions or trunks, can be accomplished in a matter of seconds or minutes. It also means that you can have a fully functional PBX up and running in a few hours (perhaps even less than an hour if you’re exceptionally quick and it’s not your first installation).

As I like to do in reviews, before I begin I’ll give you a thumbnail description of what’s in each chapter (condensed from information on the Packt Publishing web site):

  • Chapter 1: Installing FreePBX – Installing FreePBX on CentOS 5.2 or Ubuntu Server 8.10
  • Chapter 2: Module Maintenance – how to install and update modules
  • Chapter 3: Devices and Extensions – explains the difference between Extensions mode and DeviceAndUser mode, and explains how to set up extensions and users. Also explains the different types of endpoints, and how to set up voicemail for a user or extension
  • Chapter 4: Trunks – discusses trunk types, setting up a new trunk, and checking trunk status
  • Chapter 5: Basic Call Targets – explains various ways to terminate calls on a FreePBX system, including Extension and Voicemail, Ring Groups, Conferences, Day Night Mode, and Phonebook Directory
  • Chapter 6: Advanced Call Targets – discusses Queues, Time conditions, and the setup of an IVR (Digital Receptionist)
  • Chapter 7: Call Routing – discusses Inbound routing, Follow Me and the VmX Locater, and Outbound routing and Least Cost Routing
  • Chapter 8: Recording Calls – focuses on everything you need to know about recording calls that pass through a FreePBX system
  • Chapter 9: Personalizing Your PBX – discusses Custom Music on Hold, Custom voice prompts, Directory search options, Customizing feature codes, Callback, Direct Inward System Access (DISA), CallerID Lookup Sources, PIN Sets, Misc applications, and Misc Destinations
  • Chapter 10: System Protection, Backup and Restoration – how to protect your system against failure, discussing both hardware methods (a good UPS and redundancy) and backups and restoration
  • Chapter 11: Security and Access Control – explains how to upgrade your operating system and Asterisk, plus various ways to secure your system against attacks

There are also four appendices:

  • Appendix A: FreePBX Modules
  • Appendix B: Feature Codes
  • Appendix C: Voicemail.conf Options
  • Appendix D: Common Trunk Configurations

I’m coming from a slightly different place in my review of this book than with other books I’ve reviewed. In this case I’ve already very familiar with the subject material, having helped set up and configure a FreePBX system that belongs to another member of my family. I was a bit afraid that because I’m already so familiar with the subject, I’d find several glaring errors or oversights. Happily, that proved not to be the case – this book is a good, solid treatment of setting up and configuring a FreePBX system. In fact, the title should have been “How to set up and maintain a FreePBX system”, because that’s exactly what this book explains.

The first thing that impressed me about this book is that there was no “filler” material. Very often, with technical books, the author really only has about 75 to 100 pages of actual material, but because publishers like to publish books that have somewhere around a couple hundred pages, the author will flesh out the book with a history of the software, a profile of the developers, comparisons with competing products, and (if they are really desperate for material) a history of the Internet. 🙂 That is not the case here. After a very short preface, the author jumps right into the subject material, starting with how to install FreePBX and then continuing through subsequent chapters with virtually everything you need to know about configuration. While not every chapter may be meaningful to every reader (personally, I’ve never had the need to record a call — so far — but it’s nice to know that FreePBX can do it), the book at least touches on all the major features of FreePBX.

If I had to make one criticism of the book, it’s that in some places it reads a little bit too much like an instruction manual. And that’s not necessarily a bad thing, because FreePBX has badly needed a good manual to assist first time users in getting it set up and running. This is the manual that should have come with FreePBX. That said, the author really doesn’t touch some of the problems frequently encountered by new users. For example, in the discussion of SIP endpoints, he notes that “SIP can be problematic when traversing firewalls and other NAT devices” and that “Configuration can be particularly troublesome if both the endpoint and the FreePBX system are behind their own firewalls” (p. 44). And there he leaves the reader hanging. There is no discussion of how to overcome the problem, nor is there a pointer to the FreePBX FAQ’s or How-To’s anywhere in the book. While many readers may not encounter this issue, a fair number will, and it would have been nice if they’d been thrown a bone, if only in the form of a pointer to the FreePBX page that addresses the issue.

In my opinion, perhaps the biggest omission is in the discussion of Trunk setup in Chapter 4. This was really the only chapter in which I got the distinct feeling that the author may have been in just a bit over his head, and perhaps did not fully grasp the subject matter covered in the chapter. Not only are there errors in his examples of dial pattern usage (p. 81 – under no circumstances would you use two pipe characters in the same dial pattern, as is shown for some of the toll-free number examples), but when discussing IAX2 and SIP trunks (p. 83), only cursory information is given about how to populate the PEER details and USER details fields. Nor is it explained that with many commercial VoIP providers, the USER context and USER details fields are not used, and should be left blank. However, in the author’s defense, I suspect that I understand why this may have happened — there probably aren’t ten people on the face of the earth that can give you a full explanation of all the options that could possibly be used in the trunk PEER and USER details fields, and when and how each option should be used. Trunk configuration is probably the most difficult part of setting up FreePBX, precisely because there’s no definitive guide on how to do it correctly. In most cases, I suspect that finding the correct options to use with any particular provider is a matter of trial and error — you make educated guesses about which options might be needed and how they should be configured, and if you find a combination that works, perhaps you post it so that others can use it. Some of the known working trunk configuration settings appear in Appendix D of the book, but there are more sample configurations available at the FreePBX web site.

I only mention this because I was hopeful that maybe someone would finally provide a really good how-to on setting up FreePBX trunks, since this is something that almost always confounds new users, and even causes experienced users to get a few (more) gray hairs on occasion. Had I been writing such a book, and had I really understood the subject, I might have given several pages to the subject of trunk configuration in general, and PEER and USER details in particular, not just a few cursory paragraphs. On the other hand, most users will probably seek out a tested and working trunk configuration for whatever provider(s) they use.  It’s not as though there isn’t any online help on the subject, but — and this is another minor criticism — for some reason the book barely mentions the availability of online help (for example, unless I missed it there is no specific mention of the FreePBX How-Tos that address several of the issues encountered by new users). This is why I say that at times the book reads like an instruction manual — it gives you all the basics, but seldom touches the “edge cases”, the little quirks and problems that may be encountered by a significant subset of users, but not by all.

However, I don’t want to leave you with the idea that this book is simply a rehash of information that could be found online — even if that were the case, it presents that information in a logical manner that is easily understandable by the reader. But, many essential functions of maintaining a FreePBX system happen outside of the FreePBX interface. For example, you cannot update your operating system or Asterisk from within the FreePBX GUI, but the book explains how to do both.  Chapters 10 and 11 (on System Protection, Backup and Restoration, and Security and Access Control) deal with functions that are at least partially handled outside of FreePBX.  In some instances the author provides useful shell scripts that automate particular tasks (for example, deleting old, outdated backups to avoid filling up the hard drive). And in many cases, the book does explain things that new users need to know, but might not know that they need to know — for example, the explanation of Codecs and the penalty involved (both in terms of system performance and call latency) in transcoding between codecs.

Anyway, the bottom line is this: Let’s say your boss wants you to set up a new office phone system using Asterisk, and gives you a couple of weeks to do it. If you have no prior experience with Asterisk, you will almost certainly want to use FreePBX (the alternative is writing dial plans and configuration files by hand, and trust me, you don’t want to do that unless you are the sort of person who enjoys writing source code for major projects, and even then you probably don’t want to do it if you’re under any sort of time deadline). And if you’re going to use FreePBX, and you don’t want to spend hours and even days ferreting out information on the Internet, you need this book. Get your boss to buy it (there’s even an e-book version if you need it right now), then just follow the instructions, chapter by chapter. In a few days time, you’ll be well on your way to becoming a FreePBX expert.  That’s partly because FreePBX is so easy to use in the first place, but also because the book tells you pretty much everything you need to know, in a very understandable manner. If you get stuck, help is available at the FreePBX web site and at other various locations on the Internet.

If you are a long-time FreePBX user, you may find that you already know much of what’s in this book, but then again it might surprise you how much can still be learned.  For example, I found several good suggestions for adding additional security to a FreePBX system in Chapter 11 of the book — and let’s face it, many of us are probably a bit lax about securing our systems to the greatest possible extent (and that could be a very costly mistake).

One other point I should make — as the title of the book implies, it deals with a particular version of FreePBX, namely version 2.5.  Of course, as so often happens with a book about software, the ink is barely dry on the paper when a new version comes out.  FreePBX 2.6 has already been offered as a release candidate, and beta versions of FreePBX 3.0 are being made available.  From a user’s standpoint, version 2.6 will be nearly identical to 2.5 – there may be a few added options and such, but for the most part they are not things that you would need to worry about, or that would detract from the accuracy of this book.  However, FreePBX 3.0 will be a major rewrite, but it’s only available in an early beta version, and unless you are an experimenter that wants to be on the bleeding edge, you don’t want it yet.  Whenever you do move to FreePBX version 3.0 — and I’d be very surprised if a full release version is much closer than a year away — much of what you’ve learned about FreePBX 2.5 and subsequent versions will still be applicable (and also, I suspect that people will be using FreePBX 2.x versions for quite some time to come).

FreePBX 2.5 Powerful Telephony Solutions by Alex Robar (Amazon affiliate link)

Setting up an OpenVPN tunnel using a CentOS-based system as the server and a router flashed with Tomato firmware as the client – Part 4

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog. The link to Amazon.com in this article is an affiliate link, and if you make a purchase through that link I will receive a small commission on the sale.

Continued from Part 3

If you have set up an OpenVPN server on your system and are using it regularly, eventually you are going to want to trim the log file. Webmin actually makes that easy. Simply click on System, then Log File Rotation. You should see a bunch of existing log file rotation rules. Up near the top of the page there’s a line that reads:

Select all. | Invert selection. | Add a new log file to rotate.

Click on Add a new log file to rotate. You should get a page that looks like this:

Webmin Log File Rotation - Add New File page
Webmin Log File Rotation - Add New File page

The main thing here is to get the correct log file path into the topmost text area. The path will be something like:

/etc/openvpn/servers/servername/logs/openvpn.log

I generally keep all the default settings except for these two:

Rotate even if log file is empty? (I set to No)
Ignore log file if missing? (I set to Yes)

But you can do as you wish. The important thing is to make sure that the log isn’t simply allowed to grow forever Set it up as you like, click Create, and you’re through.

And now a note for FreePBX and Asterisk users.  When setting up an extension, if you use the permit and deny fields to enhance security, the correct way to fill these out may not be intuitive. For example, if you do sip show peers from the CLI, an extension at the client end of the tunnel may show up with an address in the range of addresses assigned by the client router (such as 192.168.5.x) and yet when you fill out the permit field, using that address may not work.  Asterisk’s log file will generally tell you the address it wants to see, and in our case that was 10.8.0.10! No, I don’t know why, but just wanted to give you a “heads up” on that one.

Deny and Permit fields from FreePBX extension page
Deny and Permit fields from FreePBX extension page

I had mentioned in Part 3 some of the things that needed to be done if, from machines on the server side of the VPN tunnel, you wanted to be able to access machines at the client network (where the router with the Tomato firmware is located) that are on the WAN port side of the router.  Bear in mind that anything connected to one of the LAN ports on the router is considered to be part of your VPN, but sometimes you might wish to access a machine or device (such as an “upstream” router) on the WAN side of the router with the Tomato firmware. To do this, you need to add the route to the WAN side network in the server configuration (in the “up” and “down-pre” script sections at the bottom of the Webmin server’s configuration page, using an additional “route add” and an additional “route delete” statement), and then on the client configuration page you must add an additional iroute statement – all of those take the same format as the lines you added to access the network on the LAN side of your client.  At that point, you can access machines on the WAN port side of the Tomato router, but it’s not reciprocal – they can’t access machines on the server side.

Now, I need to make an important distinction here – I’m talking about machines connected to the WAN side of the Tomato-firmware router.  Anything connected to one of that router’s LAN ports should already have full access to your network (on the server side).  But the thing to remember is that ANY traffic sent out by a client connected to the LAN side will go through the tunnel.  In some cases that may not be the desired behavior – you might have a few devices that should use the local Internet connection for all outgoing traffic (that is, as a rule they DON’T send their traffic through the tunnel), BUT you’d like to make an exception so that they can access only the local network on the server side of the tunnel, so that “local” traffic CAN be routed through the tunnel.  So, you’d have such devices on the WAN port side of the Tomato-firmware router (that is, connected to the same “upstream” router or switch as the Tomato-firmware router) so they don’t use your tunnel for the bulk of their traffic.

So the question then becomes, is it possible to allow those devices to use your tunnel ONLY for traffic to the local network on the server side of your tunnel?  Well, it is, but it’s a bit tricky to set up.  Note that you MUST first have it working in the opposite direction (that is, at a machine connected to the server side of the network, you can reach machines on the WAN port side of your Tomato-firmware router – that’s what I was talking about a couple of paragraphs up).  If you can’t do that, you’re not going to get it working in the opposite direction.  If you CAN do that, then here are the additional steps:

In the Tomato-firmware router, click on “Advanced” (in the left-hand menu), then “Firewall”, then check the box next to “Respond to ICMP ping.” You should now be able to ping the Tomato-firmware router from another device on the WAN side of the network (which may be important for testing and troubleshooting).

Next, click on “Administration”, then “Scripts”, then click the “Firewall” tab.  You should see a big text entry box with (probably) nothing in it.  Enter lines similar to the following:

iptables -t nat -I PREROUTING -s 192.168.10.0/24 -d 192.168.0.0/24 -j ACCEPT
iptables -t filter -A wanin -s 192.168.10.0/24 -d 192.168.0.0/24 -j ACCEPT
iptables -t filter -A wanout -s 192.168.0.0/24 -d 192.168.10.0/24 -j ACCEPT

In this example, addresses on the WAN port side of the Tomato-firmware router are in the 192.168.10.x range, while addresses on the server-side LAN are in the 192.168.0.x range. If either is different on your system, be sure to change all three instances of the appropriate base address.

Then click the Save button at the bottom of the page. After that it should look like this:

Administration | Scripts page | Firewall tab

Reboot the router (or you can ssh in and manually enter each of the lines from a command prompt, if you want to avoid the reboot). Now any traffic for the server-side LAN that reaches the Tomato-firmware router will get passed through the tunnel, but you still need to instruct the individual machines or devices to route that traffic correctly (which may be easier said than done for some machines). I don’t know how you do it from a Windows box, but I can tell you how it’s done on a temporary basis (that is, it survives until the next reboot) on a Linux-based or Mac OS X based machine. For the sake of these examples, assume the Tomato router is at (and can be pinged at) 192.168.10.50:

From a Linux box:
sudo route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.10.50 eth0
(eth0 is the name of the interface used to connect to your local network)

From a Mac OS X box:
At a terminal prompt enter:
sudo route add -net 192.168.0.0 -netmask 255.255.255.0 192.168.10.50
Then, if there are shares on server side of the network that you want to connect to, and you know the host machine’s IP address, open a Finder window, click on “Go” in the top menu bar, and enter this as the destination (substituting the correct IP address for the target machine):
smb://192.168.0.xx:139
Note that in at least some cases, the connect attempt will fail if you don’t explicitly specify the port (:139) – this is apparently some kind of bug in recent versions of OS X.

If anyone knows how this is done on a Windows box, or how to make these route statements persist after a reboot (remember, they must be run by the root user or a user with root-level privileges, which is why the sudo statement is used — and you can’t put sudo in a script because it prompts for a password), please leave a comment and share your knowledge!

If you have followed this series thus far, I should point out that these articles are not static – if I find a mistake, or a better way to do things, they may get changed. On the other hand, since this particular router probably won’t be in my possession much longer, it may be something that I don’t do much more work on.

One thing I had said I would do in this last article is to give you a list of links that I found useful, or at least interesting, while working on this project. I didn’t actually utilize the information in all of these, and some are even a bit off-topic for the subject at hand, but this is just a small fraction of the pages I went through while trying to get this to work:

OpenVPN HOWTO

OpenVPN FAQ

OpenVPN 2.1 man page

The ‘Point and Click’ Home VPN HowTo Guide (this was one of my primary sources)

OpenVPN: Building and Integrating Virtual Private Networks (book – Amazon affiliate link)

Tomato’s Frequently Asked Questions & Tips

Tomato (firmware) page at Wikibooks

An Easy Guide to Installing Tomato on the Asus 520gu

Teddy_bear’s Tomato 1.25 ND USB + FTP/Samba Mod (In my opinion the best firmware mod for Asus WL-520GU – be sure to get the VPN version)

Keith Moyer/SgtPepperKSU’s VPN build with Web GUI (also a great version, particularly if your router isn’t supported by the above version)
His blog

thor2002ro’s SDHC | SNMP | VPN | USB Mod (includes features from both of the above versions plus some additional features, but note that latest versions won’t run on routers with insufficient memory).

Summary of OpenVPN settings in Tomato Firmware

Tomato Firmware forum

Setting Up A Low Cost NAS Using Tomato

Using Tomato QOS

Did I configure QoS VoIP correctly? (message thread)

QOS for SOHO VOIP Solved, Tomato Firmware

Optware installation instructions (supposed to also work with Tomato firmware, potentially allows use of numerous software packages originally written or converted for Linksys NSLU2)

Linux 2.4 NAT HOWTO

OpenVPN IPv6 Tunnel Broker Guide

OpenVPN client configuration for Windows, Linux, Mac OS X and Windows Mobile for Pocket PC

Installing a Virtual Private Network with OpenVPN

EDIT: Create a VPN with the Raspberry Pi

USB disc partitioning utilities available.

“A set of disk utilities that will execute on a Tomato router. With these utilities you can now create ext2 partitions on a USB drive on the router itself, so you don’t have to use a Linux desktop machine to do it anymore.”

“A brief help file is included.”

Download link (filename is “tomato_dskutils.tgz”)
Direct link

And there’s probably plenty of other great links that I’ve missed.

Finally, one more word about the TAP/TUN issue. I would sort have liked to have gotten this working in TAP mode. However when I tried to set it up, OpenVPN (on the server) complained about a missing brctl file. Well, it turned out that the way to get that file was to do yum install bridge-utils – sounds easy, right? I assure you, absolutely nothing about this project was easy, at least not for me.

The problem was that after I had installed the software and switched both sides from TUN to TAP, and then restarted the OpenVPN server, it brought down the entire local network! I mean to tell you, I couldn’t connect to any web pages or do anything else until I physically killed the power to the server box! When I brought it back up and disabled OpenVPN, everything connected to the LAN worked fine again. When I uninstalled bridge-utils and went back to using TUN, the tunnel started working again. I had been up all night, it was coming up on 7:00 AM, and I was just so doggone frustrated by that point that I never even tried to get TAP working again. Besides, I just don’t like doing things that can bring down the entire network. I suspect it was doing some kind of packet flood thing, sort of a denial-of-service attack on my local network – pardon me if I’m not thrilled about the prospect of trying that again!

After some additional online research, I suspect that part of the problem is that after installing bridge-utils, you need to create and/or modify certain files, such as /etc/sysconfig/network-scripts/ifcfg-br0, /etc/sysconfig/network-scripts/ifcfg-eth0, and possibly /etc/sysconfig/network-scripts/ifcfg-eth1 (though I’m not at all sure about that last one). For example, one site I went to (which, for some reason, I could only read by using Google’s cached copy, which is why I’m not giving a link) said, “Configure this server’s network configuration to use a bridge as its primary interface. You do this by bridging the physical ethX and virtual tapX interfaces into one logical br0 interface. The br0 interface will be assigned an IP address, and not the physical or virtual interfaces.” That site also suggests that those files should read as follows (note that I do not recommend following this advice verbatim, see my comments below):

/etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
IPADDR=192.168.0.50 <— local IP of the server
NETMASK=255.255.255.0
ONBOOT=yes

/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=ETHER
BRIDGE=br0
ONBOOT=yes

/etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=tap0
TYPE=ETHER
BRIDGE=br0
ONBOOT=yes

Please note the above is totally untested at this point, and I’m afraid that the advice to modify the existing files (particularly /etc/sysconfig/network-scripts/ifcfg-eth0) may (or may not) be ill-advised. What concerns me is that the /etc/sysconfig/network-scripts/ifcfg-eth0 file seems to contain a lot of essential information that is in effect being thrown out – for example, on our system, it reads as follows:

DEVICE=eth0
BOOTPROTO=static
DHCPCLASS=
HWADDR=00:xx:xx:xx:xx:xx
ONBOOT=yes
TYPE=Ethernet <— NOTE!! 'Ethernet', not 'ETHER'
IPADDR=192.168.0.50
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
NETWORK=192.168.0.0
NOZEROCONF=yes

I’m just not sure what is the proper thing to do here — maybe just add the BRIDGE=br0 line to the existing file? But, if you do decide to try a full replacement of any file, be sure to copy the existing file to a safe location so that if things go badly you can recover your original file!

Some of the comments I have read suggest that TAP mode is not as efficient in transferring data, and/or not as secure (unless you add even more configuration options), so I’m thinking maybe we should leave well enough alone. But, if you have a truly burning desire to get it going, I suggest using the following Google search string for additional information – it may be strange, but it actually produced the most relevant results of all the searches I’ve tried over the last few days:

“/etc/sysconfig/network-scripts/ifcfg-br0” OpenVPN

Hopefully this page won’t show up as the first result! 🙂

If you have any ideas about what went wrong, or in particular, if you manage to get this working in TAP mode, I’d be most interested to hear about it (and how you did it, if you got it working) – the comments are open.

EDIT (November 30, 2011): While I’m not really wanting to reopen this project at this late date (this still remains about the hardest thing I’ve ever tried to do with a computer, and I have a distinct aversion to revisiting it), I did receive an e-mail today from James R, which I will post verbatim here.  NOTE THAT THIS IS NOT TESTED BY ME, SO USE AT YOUR OWN RISK:

From: James R (address redacted)
Subject: OpenVPN in bridged mode
Date: November 30, 2011 11:32:40 AM EST

The following is a script to fix the problems with getting bridged mode OpenVPN working with PBX in a Flash (CentOS 5.7 with Webmin). First you install the third party Webmin OpenVPN module, then use the script below.  I haven’t tested it yet, but I believe it should work if not explain what actions needed to be done to repair it.  Be kind, as my scripting skills are quite poor.


#! /bin/bash

wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm
sleep 30
rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
sleep 1
rpm -K rpmforge-release-0.5.2-2.el5.rf.*.rpm
sleep 1
rpm -i rpmforge-release-0.5.2-2.el5.rf.*.rpm
sleep 1
yum -y install bridge-utils
sleep 30
yum -y install tunctl
sleep 30
yum -y install openvpn
sleep 60

echo "start_cmd=/etc/init.d/openvpn start
openvpn_pid_path=/var/run
openvpn_servers_subdir=servers
zip_cmd=/usr/bin/zip
stop_cmd=/etc/init.d/openvpn stop
openvpn_path=/usr/sbin/openvpn
openvpn_clients_subdir=clients
log_lines=200
openvpn_version=2.0_rc16
openvpn_keys_subdir=keys
openvpn_home=/etc/openvpn
openssl_version=0.9.7e
openssl_path=/usr/bin/openssl
openssl_home=/etc/openvpn/openvpn-ssl.cnf
down_root_plugin=/usr/share/openvpn/plugin/lib/openvpn-down-root.so
br_end_cmd=/usr/libexec/webmin/openvpn/br_scripts/bridge_end
br_start_cmd=/usr/libexec/webmin/openvpn/br_scripts/bridge_start
tail_cmd=
log_refresh=
default_server=
" > /etc/webmin/openvpn/config

cat /usr/libexec/webmin/openvpn/br_scripts/bridge_start | sed
'2iPATH=$PATH:/sbin:/usr/sbin' >
/usr/libexec/webmin/openvpn/br_scripts/bridge_start

cat /usr/libexec/webmin/openvpn/br_scripts/bridge_end | sed
'2iPATH=$PATH:/sbin:/usr/sbin' >
/usr/libexec/webmin/openvpn/br_scripts/bridge_end

(End of James R’s e-mail.  I fixed some punctuation and capitalization in the first paragraph, but otherwise it’s the way he sent it.  I was NOT sure if the final couple of sections were really supposed to be three lines each, or one line each that got broken up by the e-mail software. I suspect the latter, but I’m leaving them as is in case I’m wrong about that. Again, please remember that the above is UNTESTED by me.)

Here’s another bit of information that may be useful for those of you that don’t know much about Linux — here is a very small list of Linux commands that may be useful in diagnosing any problems with your VPN tunnel:

  • ifconfig – shows the current list of  network interfaces.  On both ends of your tunnel you should see a tunx interface when the tunnel is operational. On Windows-based systems a similar command is ipconfig.
  • ip route show – shows current routing information for the system (see also route). ip route list gives a slightly different view.
  • iptables -L – lists the current iptables rules. Add the -v option to get a more verbose display.
  • netstat -r – similar to route but with a slightly different view.
  • ping address – tries to get a response from another connected machine or device.  Note that not all systems or devices will respond to pings.
  • route – shows the current routing tables on the system (see also ip route show).
  • tcpdump -n – this shows a running display of all activity on the network interfaces.  Be careful because this can produce a LOT of output very quickly.  Use Control-C to interrupt, then be prepared to wait until the buffer empties (may take a few seconds).
  • traceroute address – If you run a traceroute to a network address (either on the LAN or on the Internet) it will attempt to show each system the packets pass through on the way to their destination. This can be useful for determining if traffic to a particular destination is actually going through your tunnel. On Windows-based systems use tracert (a holdover from MS-DOS days when filenames were limited to eight characters!).
  • which program-name – not a network command per se, but if you get an error message about a missing program, you can use which program-name to try to determine if the program exists on your system, and the correct path to that program.

Note that there are additional options for most or all of the above commands – read the man page for that command (e.g. man tcpdump) if you are interested, or use a search engine to find more information (yeah, I think most man pages are painful, too). man is short for manual, by the way, not a reference to gender.

Anyway, I’m still trying to catch up on lost sleep, but if I think of anything else pertinent I’ll probably add it to this article, rather than making this series any longer. I hope if you attempt this, it’s not nearly as painful for you as it was for me!

Setting up an OpenVPN tunnel using a CentOS-based system as the server and a router flashed with Tomato firmware as the client – Part 3

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog. The link to Amazon.com in this article is an affiliate link, and if you make a purchase through that link I will receive a small commission on the sale.

Continued from Part 2

Okay, time for the hard part… well, at least it was for me.  Please understand, the instructions at The ‘Point and Click’ Home VPN HowTo Guide, combined with the knowledge I acquired from the book OpenVPN: Building and Integrating Virtual Private Networks (Amazon affiliate link) by Markus Feilner, enabled me to get a tunnel going using a software client with no sweat. But getting it to work with the Tomato VPN client, and in particular, to get it to work the way we needed it to, was a whole other thing. It turned out, as so often happens that some simple configuration changes were all that was needed – but finding the correct configuration changes to make were pure grief.

EDIT: The above-mentioned book has been updated and expanded under a new title — see Mini-review of Beginning OpenVPN 2.0.9 by Markus Feilner and Norbert Graf (Packt Publishing)

I want to digress just a moment to speak about those elitists that seem to frequent certain forums and IRC channels, and just love to tell newbies (often in not so polite terms) that all the answers can be found by using Google. I’ve pretty much figured out that most of the time, the person saying that doesn’t know the answer either, but they are like the schoolyard bully that gets their kicks by picking on others. In this case, Google may have had the answers somewhere, but they sure weren’t showing up in the first few pages of results. Instead, what was showing up was many others who were having the same problems and asking the same questions, but not getting answers! And usually after the first four or five pages of results, the results became even less relevant, if that were possible. Finally, after taking a more or less scattershot approach to seeking help, I came up with a “recipe” that works in this situation. Of course I cannot guarantee it will work for you… heck, I can’t guarantee it will work for me next week… but at least it’s working as I write this. But the next time someone suggests that you should just Google it (or something like that), I suggest you ask them what search terms they would suggest using that will bring you the answer to your question. When whatever they suggest doesn’t work, let them know and ask for more suggestions, and just keep repeating until you find the answer or they get sick of talking to you. If we all did that, I suspect some of the online bullies would discover that maybe they should keep quiet if they don’t know the answer.

Okay, so to begin, let’s make sure we are all on the same page. I assume you’ve installed the Webmin OpenVPN + CA module (again, following the instructions at The ‘Point and Click’ Home VPN HowTo Guide) but if you had difficulty locating the module, try here — as I write this, it appears that the newest version of the module is the OpenVPNadmin WebMin pre-release 2.5 version. And when you try to download it, if you get “Unauthorized access to downloads!”, try a different browser, or make sure JavaScript and cookies are enabled.  You will probably need to download it to your computer first, then upload it to Webmin, if your experience is anything like mine was.

When you go into the module, you’ll initially see a page like this:

OpenVPN administration page
OpenVPN administration page

This is “home base” for this module, so when I say “return to the admin page”, this is the page I mean. It’s also the page you use to create a new Certification Authority (normally you only need to do that once, but if you really want to you can make more). In the upper left corner there is a link labeled “Module Config” – click on it and make sure all the paths are correct:

OpenVPN + CA configuration page
OpenVPN + CA configuration page

A couple notes on this page:  First, although it indicates that “Server Hint for Clients” is a required field, there is no indication of what actually goes there, nor any default value.  Second, the information under “If you use bridge device” is only applicable if you use TAP mode (remember, we’re using TUN), but I do know the defaults are not correct.  Just in case you ever want to try to get TAP mode working, here is what these paths should be (at least on our installation):

Command to start Bridge:
/usr/libexec/webmin/openvpn/br_scripts/bridge_start

Command to stop Bridge:
/usr/libexec/webmin/openvpn/br_scripts/bridge_end

Path to DOWN-ROOT-PLUGIN:
/usr/share/openvpn/plugin/lib/openvpn-down-root.so

Do check the paths on this page, because the defaults aren’t totally correct.  Now let’s return to the admin page.  I probably should have mentioned that you don’t really need to change any of the defaults for making a certificate for just your own use – those values are probably only important if you are creating a certificate that will be used by the public.  Once you have made a certificate, you can click on the Certification Authority List, where you’ll see this page:

OpenVPN Certification Authority page
OpenVPN Certification Authority page

I really don’t know why you can create a new Certification Authority on both this page and the main admin page, but oh well… once you have created one it will show up in the list at the top of the page.  You can click on it to view what you created, but there’s nothing you can change there. The main thing of importance is the “Keys List” link, where you can actually create new keys and view existing ones:

OpenVPN key list and key creation page
OpenVPN key list and key creation page

Okay, now here’s the important thing to remember about key creation: You need one key for your server, and one key for each client.  You will note we have a server key, and client key for the software client (used for testing) and one more for the OpenVPN client on the Asus router.

As you may have surmised, except for the key name field, you can leave everything else at the defaults. However, there is one thing on this page that will lead you astray.  It says, “Server key doesn’t need password!“, which might lead you to think that a client key does need one, but that’s not true.  And if you use a password with your Tomato-based client key, you will never make a successful connection.  The keys are far stronger protection than passwords anyway, so the only reason you might even consider using one is for a software client where you want to keep anyone other than an authorized user from connecting to the VPN tunnel.  Anyway, don’t use a password for your server key or your Tomato OpenVPN client key!!!

Okay, now it’s time to navigate back to the admin page, then click on “VPN list”. Once you have created a server key, you can create your actual server. So click on the New VPN Server button and a page will come up that permits you to create a server configuration.  This is where things get really tricky.  Here is how ours is filled out:

OpenVPN Server page
OpenVPN Server page

Now the above is actually the edit page you get once the server is created and you have returned to edit it.  Note that some values cannot be changed after the initial entry, so be sure you get them right the first time.  In particular, make sure to select tun and not tap. If you do make a mistake, you can always delete the entire server configuration and start over, but that’s a bit of a pain. There are some differences in our configuration and the one at The ‘Point and Click’ Home VPN HowTo Guide, and generally speaking there are good reasons for the differences. But that said, nobody is claiming our configuration is perfect, just that it works! If you see something here you think should be changed, feel free to leave a comment.

Note in particular the text fields at the bottom of the page. Getting those right is the key to making this thing work! So, here’s what’s in each of those:

Additional Configurations:

push “route 192.168.0.0 255.255.255.0”
push redirect-gateway
push “dhcp-option WINS 192.168.0.50”
script-security 2 system

up (script execute after VPN up):

route add -net 192.168.5.0 netmask 255.255.255.0 gw 10.8.0.2 tun0
echo 1 > /proc/sys/net/ipv4/conf/tun0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp

down-pre (script execute before VPN down):

route delete -net 192.168.5.0 netmask 255.255.255.0 gw 10.8.0.2 tun0

Of course, in the Additional Configurations section you want the line push “dhcp-option WINS 192.168.0.50” to point to a WINS server on your network, if you have one (if you don’t, just leave that line out).

In the up and down-pre scripts, if you want to be able to reach the local network behind the WAN port of the router on the client side, you should add additional route add and route delete lines in a format similar to those above, but substituting that network’s address range.

Now, once again, I’m NOT saying this is a perfect configuration, just that it works for us. However, if you notice something that just doesn’t look right, feel free to leave a comment. Much of the added configuration was put in so that traffic from the primary LAN to addresses in the 192.168.5.x address space would actually go through the tunnel – that was the hardest part. It was (relatively) easy to create a tunnel in the first place, but getting packets to and from their intended destinations was another matter entirely.

When you have configured your server and clicked “Save”, it should show up in your server list:

OpenVPN Server List page
OpenVPN Server List page

Now click on “Clients List” – there will be a button labeled “New VPN Client” (no screenshot, it’s just a button to click at this point).  Click that button and you will be presented with a client configuration page.  Here’s the one we created for our Tomato OpenVPN client running on the Asus router (again, this is actually the edit page, since the client is already created on our system):

OpenVPN Client Configuration page
OpenVPN Client Configuration page

Most of the settings here will be the defaults but there are two things to pay particular attention to:  First, the “Remote IP” must be the external address of your server – remember that this is the configuration that goes to the client. And second, notice the ccd file content box at the bottom – it is crucial that this be filled in correctly. In our case, we used this line:

iroute 192.168.5.0 255.255.255.0

If you miss this – and I speak from experience on this one – the packets from the Internet or your local LAN just aren’t going to get back to the client end of the tunnel! And remember to add an additional, similar line if you also want to be able to reach the network connected to the WAN port at the client router, substituting the base address of that network for the 192.168.5.0.

Once you have saved this, it should appear in the VPN client list:

OpenVPN Client List page
OpenVPN Client List page

Once you have configured a client, the next step is to export its configuration, particularly the certificate and key files, to your computer using the “Export” link – all the necessary files will be packed up in a ZIP file.  The instructions at The ‘Point and Click’ Home VPN HowTo Guide tell you how to use this file with a software client, but with your Tomato firmware you will have to unzip the file and then open each of the three files (ca.crt, plus the client certificate and key files), in a text editor or viewer. Only those three files are used with the Tomato OpenVPN client; the others in the ZIP archive are not. Then you will need to cut and paste the contents of those files into the three fields that appear under VPN Tunneling | Client | Keys tab in the Tomato firmware (see the screenshot of that page in Part 1 if you’re not sure what file’s contents goes where). With regard to the Client Certificate, there is some extra information at the top of the file that does not need to be pasted into the text field – you only need the two lines —–BEGIN CERTIFICATE—– and —–END CERTIFICATE—– plus all the lines in between those two tags. On an Asus WL-520GU router it doesn’t matter much, but there have been cases with some other makes of router where leaving that excess information in was just enough excess data to “brick” the router! So if in doubt, leave the data above the —–BEGIN CERTIFICATE—– line out.

Once you have everything ready, you can go to the OpenVPN admin page in Webmin and start the server, then in your Tomato firmware start the client.  HOPEFULLY the client and server will connect and start communicating.  You can check from the server’s  admin page by clicking on “Active Connection” – hopefully you will see something like this:

OpenVPN Active Connections page
OpenVPN Active Connections page

If you do, congratulations! If not, you have some troubleshooting to do. On the server, take a look at the log file: /etc/openvpn/servers/servername/logs/openvpn.log. On the client, click on Logs (under Status in the left-hand menu) and look at the last several lines. OpenVPN usually doesn’t suffer in silence — when something isn’t working, chances are one or both logs will be filled with messages that may or may not be helpful. You can always try going to Google and using OpenVPN plus the actual error message text (enclosed in quotation marks); once in a while that will actually bring up something useful.

Still stuck? My plan is to add a Part 4 to this series, that will provide links to some of the most useful resources I’ve collected along this journey.  But you can certainly help — if I’ve made any errors in these instructions (not at all unlikely given the sleep I’ve missed during this project), and you find them and can figure out what was incorrect, PLEASE leave a comment. I will warn you that writing to me with your error message will probably get you nowhere – I can definitely play the part of the blind leading the blind, so to speak, but first I have to heal from all the bruises encountered on this journey! 🙂

I sincerely hope these posts have been useful to you! In Part 4 I’ll wrap this up with brief instructions for rotating the log file so it doesn’t grow forever, provide the aforementioned list of links, and give you a bit more insight into why I set this up using TUN mode even though I’d probably have preferred to use TAP.

Setting up an OpenVPN tunnel using a CentOS-based system as the server and a router flashed with Tomato firmware as the client – Part 2

 

Important
This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission. Comments dated before the year 2013 were originally posted to his blog.
Continued from Part 1

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:

wget download.webmin.com/devel/rpm/webmin-current.rpm
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):

net.ipv4.ip_forward=1

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:

touch /etc/yum.repos.d/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:

[dag]
name=Dag RPM Repository for Red Hat Enterprise Linux
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
enabled=1

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
Incoming interface Equals 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
Outgoing interface Equals eth0

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:

Firewall rule: Accept If input interface is tun0
Firewall rule: Accept If input interface is tun0
Firewall rule: Masquerade If source is 10.8.0.0/24 and output interface is eth0
Firewall rule: Masquerade If source is 10.8.0.0/24 and output interface is eth0

(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!!!