How I upgrade Asterisk 1.8

 

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.

Note: This article was originally posted in August, 2011 and is very out-of-date.

This is just one of those things that I figured it might not hurt to put into a blog post so I can find it later if I ever need to.  This is the procedure I use to upgrade Asterisk 1.8 when a new release appears that has a fix that I feel I need, or that closes a security hole.  PBX in a Flash users should NOT do this, and FreePBX Distro users probably shouldn’t do this either, as you have your own respective upgrade mechanisms.  This is for folks who have either built a system from scratch, or who (like me) started out with a distro but the decided to go your own way as far as upgrades are concerned.  Note that I am only saying that this is how I do it.  I am NOT telling you to do it this way, and if you do so you do it at your own risk.

There are the steps from the CentOS Linux command prompt.  Some of them need further explanation and those have a footnote number next to them.  Do NOT enter the footnote number from the command prompt! Also, in these examples I’m using Asterisk 1.8.5.0 (the current release version as I write this) as the version I’m installing, but you should go to http://downloads.asterisk.org/pub/telephony/asterisk/releases/ and find the current version and use that instead.  If the lines overflow the width of the column, you should probably copy and paste the entire block into a text editor so that you can see the complete lines and know where the line breaks are supposed to be.

cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-1.8.5.0.tar.gz ¹
tar xvfz asterisk-1.8.5.0.tar.gz ¹
cd /usr/src/asterisk-1.8.5.0 ¹
make clean
contrib/scripts/get_mp3_source.sh
./configure
make menuselect ²
/root/stopnoise ³
make
make install

After doing this I find it’s easiest to just reboot the system to nip any “weirdness” in the bud. Some Linux purists will hate that idea (it seems to be a badge of pride among some of them to see how many days they can run a system without rebooting), and if you don’t want to reboot, feel free not to — it’s your system. Many people will stop Asterisk before starting the upgrade procedure by doing amportal stop at the beginning, and amportal start at the end, but since I usually reboot anyway I’ve never found the need to do that (the upgrade seems to go just fine even if Asterisk is running at the time, so I’m not sure why so many people think they have to stop Asterisk first — probably a case of one person did it, so everyone else follows like lemmings to the sea). However, if you don’t plan on rebooting, then you must stop and restart Asterisk to get it to use the upgraded version.  If I want to only restart Asterisk for some reason, I usually go into the Asterisk CLI and do “core restart when convenient” so that the system will restart as soon as there are no calls in progress.

I do NOT use the flite synthesized voices (I can’t stand them; they are far too mechanical for my taste) so you won’t find any instructions here pertaining to those.

Now the footnotes:

¹ Use the correct version number for the version of Asterisk you are installing in place of 1.8.5.0

² When you run “make menuselect” it will bring up a menu that lets you select various options. You will want to pay attention to what is selected and what is not. Typically I need to make these changes:

Under Add-ons, I select everything EXCEPT chan_ooh323 — most of the others are required for FreePBX to function properly. Under Applications, I use the defaults. Under Bridging Modules through PBX Modules, everything that is not X’ed out is selected. Under Resource Modules everything that is not X’ed out is selected except res_pktccops (NOTE: If res_srtp has XXX next to it and you would like to enable SRTP support, stop here and read the note at the bottom of this article). Under Test Modules NOTHING is selected. Under Compiler Flags, LOADABLE_MODULES is selected by default and in addition I select G711_NEW_ALGORITHM and G711_REDUCED_BRANCHING. Under Voicemail Build Options through Module Embedding I just accept the defaults. Under Core Sound Packages through Extras Sound Packages I accept the defaults and also add the sounds corresponding to the language and codecs I use on my system (in my case the *-EN-WAV and *-EN-ULAW packages, and if I had any wideband endpoints I’d also use the *-EN-G722 packages). So, the only screens on which I make changes (in other words, I don’t just accept the defaults) are the Add-ons, Compiler Flags, and the three sound-related screens. Note that the Compiler Flags are just a personal preference (I just think the new algorithm may make G.711 calls a bit clearer) and the sounds MAY not need to be reloaded on every upgrade, but I’d rather be safe and include them, just in case some of the sound files have been updated.

³ This is a bash script I have in my /root directory that contained the following three lines prior to Asterisk 1.8.12.0:

#!/bin/bash
sed -i 's/ast_verb(4, "ast_get_srv: SRV lookup for/ast_verb(11, "ast_get_srv: SRV lookup for/' main/srv.c
sed -i 's/ast_verb(4, "doing dnsmgr_lookup for/ast_verb(11, "doing dnsmgr_lookup for/' main/dnsmgr.c

Starting with Asterisk 1.8.12.0 it appears they changed the default value in the last line, so now I use this:

#!/bin/bash
sed -i 's/ast_verb(4, "ast_get_srv: SRV lookup for/ast_verb(11, "ast_get_srv: SRV lookup for/' main/srv.c
sed -i 's/ast_verb(6, "doing dnsmgr_lookup for/ast_verb(11, "doing dnsmgr_lookup for/' main/dnsmgr.c

If either or both of the phrases “doing dnsmgr_lookup for …” and/or “ast_get_srv: SRV lookup for …” are familiar (and annoying) to you, then you may want to use this script. Otherwise, you can just skip this instruction. For more information, see this thread in the PBX in a Flash forum.

NOTE REGARDING MISSING SRTP SUPPORT: It is possible to add this by following this procedure:

In your browser go to ftp://ftp.owlriver.com/pub/local/ORC/srtp/ (your browser must support the ftp protocol – try Firefox if yours doesn’t). You should see a file named srtp-1.4.4-1orc.src.rpm or perhaps a newer version. Download it and then move it to a directory (such as /tmp or /root) on your Asterisk server. Then do this, changing the version number if you got a different one:

cd (whatever directory you put the file into)
rpm -ivh srtp-1.44-1orc.src.rpm
cd /usr/src/redhat/SOURCES/srtp

(If the srtp directory does not exist then cd /usr/src/redhat/SOURCES/ and tar xvf srtp-1.4.4.tgz)
./configure
make
make install

Then go back and restart the upgrade procedure, starting at the second cd … command and make clean. When you get to make menuselect, res_srtp should now be enabled. Note that this is not the only thing you need to do to make SRTP functional; at a bare minimum you would beed to add the line encryption=yes to the extension’s configuration, and even that would not be sufficient for some devices due to a so far unpatched bug in Asterisk. But, that is beyond the scope of this article.

How to block a single extension’s ability to make outgoing toll calls in FreePBX

 

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.
Courtesy Phone
Image by zacklur via Flickr

EDIT (May, 2018): FreePBX and Asterisk users that wish to continue using Google Voice after Google drops XMPP support should go here: How to use Google Voice with FreePBX and Asterisk without using XMPP or buying new hardware.

This question comes up a lot and rather than having to re-type the answer each time I see it posted in some forum, I decided to put it here, where I can just link to it.  If you want to know why this works, read my previous article, Asterisk hiding a useful feature in plain sight by giving it a “cute” name.

Many organizations have a single extension that is a “house phone” for visitors, and they don’t want anyone to be able to use that phone to make “off-site” calls.  The thing you must decide is, do you want your users to only be able to make in-house calls, or do you want to in addition allow calls to local and toll-free numbers? It makes a bit of difference in how you do this.  And remember, in most places, by law you MUST allow calls to 911 or whatever your local emergency number might be — if you block emergency calls and someone tries to use that phone to summon an ambulance or get other necessary emergency help and is unsuccessful in doing so, then prepare to have your butt sued off (and possibly even serve some time in prison), and I don’t have a bit of sympathy for you.  I don’t care what reasons you may think you have for wanting to block emergency calls, just DON’T DO IT.

Anyway, here’s the basic technique:

1.  Create a Trunk: (EDIT: This step is unnecessary in the most recent versions of FreePBX). If you want to allow “free” off-premises calls, then the easiest thing to do is create an ENUM trunk, if you haven’t done so already.  If you DON’T want to allow free calls, then create a “dummy” trunk for the purpose.  Create a CUSTOM trunk (not SIP or IAX2, etc.), name it Blocked, and make the Custom Dial String Local/congestion@app-blackhole — that’s all you have to do. For extra safety, you can also check the “Disable Trunk” checkbox (this should play a recording saying that all circuits are busy, or something to that effect, whereas leaving the trunk enabled would play “fast busy” tones). Then submit the changes.

2.  Create an Outbound Route: Give the Outbound Route any name you like. In the “Dial Patterns that will use this Route” section, enter the patterns you do NOT want the extension to be able to dial (in the third field of a pattern if using FreePBX 2.8 or higher) followed by the extension number that you want to restrict (in the fourth field in FreePBX 2.8 or higher, or after a forward slash character if using a lower version).  I’m going to show the following examples in the syntax used in FreePBX 2.7 (EDIT: you would also use this syntax in FreePBX 12 or later, if under Settings | Advanced Settings, in the “GUI Behavior” section you have set Enable The Old Style FreePBX Dial Patterns Textarea to True).  Let’s say you want to block calls from extension 234:

To block all calls of 11 digits or more (in case you have “local” 10 digit dialing):
XXXXXXXXXXX!/234

To block all calls of 8 digits or more (allowing 7 digit local calls):
XXXXXXXX!/234

To block all calls of 4 digits or more (in case you have three-digit extensions and want to allow in-house and 911 calls only):
XXXX!/234

In the Outbound Route trunk selection, (EDIT: if you have a recent version of FreePBX, simply do not select any trunks at all in the “Trunk Sequence for Matched Routes” section of the Outbound Route, and then optionally select a failure announcement or whatever treatment you want to give the call in the “Optional Destination on Congestion” section. Otherwise, if you are still running an older version of FreePBX) select whichever trunk you created in Step 1 (ENUM or Blocked).  Select only that one trunk.  Note that if you “disabled” the Blocked trunk it may be grayed out, but you still should be able to select it as a trunk choice, and that should be sufficient to keep FreePBX from complaining that you haven’t made a trunk selection.

Priority is important! Make sure this Outbound Route appears in your list of Outbound Routes BELOW any routes that handle calls you want to allow (your emergency route(s) for sure, and possibly routes that handle Toll-Free calls if you want to allow those), but ABOVE any routes that would normally be used for the type of calls you want to restrict.  Remember that this route will only restrict calls that match the patterns, so if you only restrict calls that are 8 digits or more and you have a lower-priority route that handles 7-digit local calls, those calls should still go out.

Just a note about use of an ENUM trunk (EDIT: Optional and not necessary in newer versions of FreePBX).  If someone calls a number that is registered as an ENUM number, it will go out as a direct SIP call, bypassing your normal SIP or IAX providers, so it won’t cost you a dime.  The vast majority of numbers are NOT reachable via ENUM so if you use an ENUM trunk as your “blocker” trunk, it will be a very rare thing if a call actually connects that way, but if it does you won’t be paying for it.  Sometimes U.S. or Canada Toll-Free numbers are reachable via ENUM and sometimes they are not — it’s actually pretty much a crap shoot whether it will even work at all.  So if you want to specifically allow toll-free calls, don’t count on ENUM to handle them, but be aware that in some cases they might go through via ENUM, at no cost to you (other than whatever you may pay for your Internet connection, of course).

Be sure to make some test calls from the extension to make sure everything works as you expect.  And double-check to make sure you have not blocked emergency (911, or whatever your local number is) calls!

If you need to do blocking for more than one extension, you can either use patterns (rather than single extension numbers) after the forward slash, or simply add new blocking rules.  For example, you could do this:

Block all calls of 4 digits or more from extension 234 or 235:
XXXX!/23[45]

Block all calls of 4 digits or more from extension 230 through 239:
XXXX!/23X

Block all calls of 4 digits or more from extension 234, and block all calls to 1-900 numbers from extension 288:
XXXX!/234
1900XXXXXXX/288
900XXXXXXX/288

 

Asterisk hiding a useful feature in plain sight by giving it a "cute" name

 

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.
easter eggs in the stage of painting
Easter Eggs (Image via Wikipedia)

Somewhere in FreePBX 2.7 or thereabouts, it became know that there was a feature of FreePBX Outbound Route dial patterns, were you could use a /CallerID extension. This (among other things) basically lets you limit the use of an Outbound Route to a particular extension or group of extensions.  It’s a very useful feature, but wasn’t widely announced or promoted at the time.  I finally figured out why.

Thing is, it’s NOT a FreePBX feature, it’s a feature of Asterisk.  Anywhere in an Asterisk dial plan where you have a line that starts with

exten => _somepattern,…

you can use the Caller ID modifier, like this:

exten => _somepattern/callerid,…

In which case the pattern won’t be matched unless the current Caller ID number (which on an internal call is the number of the calling extension) matches whatever you’ve replaced callerid with.  Callerid can itself be a number or a pattern.

The real kick in the head is that it appears this feature has been around for a LONG time.  It was definitely in Asterisk 1.4.  Yet virtually none of the documentation you see on Asterisk even mentions this feature.  It might as well have been an “Easter Egg” hidden in the software, for all anyone knew of it.  Well, I finally figured out why — the Asterisk folks hung a “cute” name on it, and it stuck.

They called it ex-girlfriend logic.  The idea is that you can use it to stop an ex-girlfriend from bothering a particular user on your system (at least in raw Asterisk, though I don’t think that’s directly supported in FreePBX).  Besides being a bit sexist, it’s also about the last terminology anyone would think to Google on if they were trying to find out about this feature.  So while people were writing third-party modules like Custom Contexts and Outbound Route Permissions in FreePBX, it now turns out that essentially the same basic functionality was there all along, but hardly anyone (at least in the FreePBX world) knew about it until around about the time of FreePBX 2.7 or so.  If you can find anything at all about this feature in “official” Asterisk documentation (that doesn’t include third-party sites!), you’re a better searcher than I.

Makes you wonder if there are any OTHER cool features in Asterisk that are hidden in plain sight, under unfortunate descriptive names that no one would ever think to use when searching for such a feature!

 

Link: FreePBX security advisory – SIP extension types

 

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.
We can set defaults for all these, so why not extension type?
We can set defaults for all these, so why not extension type?

The SysAdminMan blog has posted a new article related to FreePBX security, that I strongly urge you to read if you are running FreePBX or any FreePBX-based distribution:

FreePBX security advisory – SIP extension types

The basic issue is that by default, FreePBX sets extensions to type=friend rather than the more secure type=peer.  The article says it’s for historical reasons but I suspect there have been other reasons at play here (pure stubbornness, perhaps?).  But with the growing body of evidence that type=friend is bad, and because FreePBX now has an Advanced Settings module that allows you to to change certain defaults (though not yet this one), I have put in a Feature Request asking that system administrators be allowed to select a default type for extensions.  We’ll see if it goes anywhere (and it might help if anyone who supports this idea would add a comment to that ticket), but given that in the past they’ve been reluctant to even entertain the idea of changing the default, I fear that they may once again refuse to even consider it.  And for those of us who want to keep our systems as secure as reasonably possible, that would be a real shame.

Using a dynamic DNS (DDNS) to solve the problem of keeping a firewall open to remote users at changeable IP addresses

 

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.

(Updated July 1, 2011 to include rudimentary test for string returned that doesn’t contain an actual IP address)

One problem faced by Asterisk users (and probably also users of other software PBX’s) is that you want to secure your system by not opening ports up to the entire Internet, but if you have remote users (users not on the same local network as your Asterisk server) you need to make an exception for them to allow them to penetrate your firewall.  If all your external users have fixed IP addresses, it’s not a problem — you simply add a specific rule in your firewall to permit access from each user’s IP address.  However, if their ISP changes their IP address frequently, or if they are using a softphone on a laptop computer, then you can’t just assume they will constantly be at same IP.  And if one of those users happens to be your boss or your mother, they are not going to be happy if they can’t use the phone until they make contact with you, and you enter their new IP address in the firewall.  And they’re probably not going to be real happy if they have to go to a web site or take some other action before they can make and receive calls.

This solution will work for many users in this situation, provided that you are using the iptables firewall. Again, the goal is to keep all your ports closed to outsiders, except for your authorized users. But if you can get each user to set up a Dynamic DNS account and then set their router to do the Dynamic DNS updates (as described here for DD-WRT users), OR failing that if you can get them to install a software Dynamic DNS client on their computer (which is a poorer choice because the computer has to be on for updates to occur), then you can run a script on your Asterisk box every five minutes to check to see if their IP address has changed, and if so, update iptables. I have one script that is called as a cron job every five minutes, and looks like this:

#!/bin/bash
/root/firewall-dynhosts.sh someaddress.afraid.org
/root/firewall-dynhosts.sh someotheraddress.afraid.org
/root/firewall-dynhosts.sh someaddress.no-ip.com

In other words it has one line for each Dynamic DNS host I want to check. For each host it calls a script named firewall-dynhosts.sh which in turn contains this:

#!/bin/bash
# filename: firewall-dynhosts.sh
#
# A script to update iptable records for dynamic dns hosts.
# Written by: Dave Horner (http://dave.thehorners.com)
# Released into public domain.
#
# Run this script in your cron table to update ips.
#
# You might want to put all your dynamic hosts in a sep. chain.
# That way you can easily see what dynamic hosts are trusted.
#
# create the chain in iptables.
# /sbin/iptables -N dynamichosts
# insert the chain into the input chain @ the head of the list.
# /sbin/iptables -I INPUT 1 -j dynamichosts
# flush all the rules in the chain
# /sbin/iptables -F dynamichosts

HOST=$1
HOSTFILE=”/root/dynhosts/host-$HOST”
CHAIN=”dynamichosts” # change this to whatever chain you want.
IPTABLES=”/sbin/iptables”

# check to make sure we have enough args passed.
if [ “${#@}” -ne “1” ]; then
echo “$0 hostname”
echo “You must supply a hostname to update in iptables.”
exit
fi

# lookup host name from dns tables
IP=`/usr/bin/dig +short $HOST | /usr/bin/tail -n 1`
if [ “${#IP}” = “0” ]; then
echo “Couldn’t lookup hostname for $HOST, failed.”
exit
fi

if [ ! `expr “$IP” : ‘([1-9])’` ]; then
echo “Did not return valid IP address, failed.”
exit
fi

OLDIP=””
if [ -a $HOSTFILE ]; then
OLDIP=`cat $HOSTFILE`
# echo “CAT returned: $?”
fi

# has address changed?
if [ “$OLDIP” == “$IP” ]; then
echo “Old and new IP addresses match.”
exit
fi

# save off new ip.
echo $IP>$HOSTFILE

echo “Updating $HOST in iptables.”
if [ “${#OLDIP}” != “0” ]; then
echo “Removing old rule ($OLDIP)”
`$IPTABLES -D $CHAIN -s $OLDIP/32 -j ACCEPT`
fi
echo “Inserting new rule ($IP)”
`$IPTABLES -A $CHAIN -s $IP/32 -j ACCEPT`

echo “Changing rule in /etc/sysconfig/iptables”
sed -i “0,/-A\sdynamichosts\s-s\s$OLDIP\s-j\sACCEPT/s//-A dynamichosts -s $IP -j ACCEPT/” /etc/sysconfig/iptables
# sed -i “s/-A\sdynamichosts\s-s\s$OLDIP\s-j\sACCEPT/-A dynamichosts -s $IP -j ACCEPT/g” /etc/sysconfig/iptables

echo “Sending e-mail notification”
`echo “This is an automated message – please do not reply. The address of dynamic host $HOST has been changed from $OLDIP to $IP. You may need to change the dynamichosts chain in Webmin’s Linux Firewall configuration.” | mail -s “IP address of dynamic host changed on machine name recipient@someaddress.com,anotherrecipient@someaddress.net`

As always, copy and paste the above script, so you can see where the line breaks are really supposed to be (the last line in particular is quite long, and will likely be broken up into four or five lines on the screen). Also, beware of WordPress or other software changing the single or double quotation marks to “prettified” versions — only the plain text normal quotation marks will work.

Note that prior to the first run of the script you will need to run the three commented-out commands shown near the top of the script, right after “create the chain in iptables”, to create the chain. For your convenience here they all are in one place, without the interleaved comment lines:

/sbin/iptables -N dynamichosts
/sbin/iptables -I INPUT 1 -j dynamichosts
/sbin/iptables -F dynamichosts

The lines in blue in firewall-dynhosts.sh are custom additions by me. Just in case something goes wrong, I suggest you make a backup copy of /etc/sysconfig/iptables in a safe place before running this script.  My first addition checks the first character of the string returned in $IP to make sure it is actually a number.  This was a quick and dirty addition to keep it from trying to use a string like ;; connection timed out; no servers could be reached as a valid IP address (yes, it really did that).  I’m sure that the test there could be improved upon (for example, to do a full check for a valid IP address rather than just checking the first digit) but as I say this was a quick and dirty fix.  If you have any suggestions on how to improve it, please leave a comment.  I did find this article, Validating an IP Address in a Bash Script, but it seemed like a bit of overkill considering that in this case what I’m really trying to do is simply weed out error messages.

The second set of additions change the address in the dynamichosts chain of /etc/sysconfig/iptables. Please note that this file may be at a different location in some versions of Linux (such as /etc/iptables.up.rules), if so you will need to change this accordingly. This is particularly important if you run both Webmin and fail2ban. If fail2ban is running it will add some lines to the in-memory version of iptables, so you don’t want to do a simple commit to save the in-memory version back to the iptables file. But at the same time, if you use Webmin’s “Linux Firewall” module to maintain iptables, you want any changes in IP addresses to show up the next time you call up Webmin’s Linux Firewall page. So this simply does a search and replace in /etc/sysconfig/iptables on the rule containing the old IP address, and replaces it with the new one. There are two lines in that section that contain the sed command, the first one will replace only the first instance of the old IP address if it’s in iptables more than once, while the second (which is commented out) would replace all instances of the old IP address. Uncomment whichever you prefer and leave the other commented out, but bear in mind that if two or more of your remote extensions might ever be at the same IP address at the same time, you want the first version (the one that is uncommented above) so that when one of those extensions moves to a different IP address it doesn’t change the IP address for all of the extensions.

Note there’s still a possibility of missing a change if you are actually working in Webmin when a change occurs (since you’ll already have loaded a copy of iptables, and if you then make changes and save it out it could overwrite any change made by the script). But, the last two lines of the script send you an e-mail to alert you to that possibility. If you don’t use Webmin and don’t need or want an e-mail notification for some other reason, you can omit those last two lines, otherwise change the parts in red text to sane values for your situation. While editing, pay attention to the backtick at the end of the line (it’s easy to accidentally delete it when editing an e-mail address — don’t do that!).

When you’re all finished, make sure both scripts are executable and the permissions are correct, then create a cron job to call the first script every five minutes.

The only slight drawback to this method is that when an IP address changes it can take up to ten minutes to update (five for the Dynamic DNS to pick it up, and five more for the cron job to fire that gets it from the Dynamic DNS). Fortunately, most ISP’s tend to change IP address assignments in the middle of the night. Note that using the wrong DNS servers can cause the updates to take significantly longer; I set my computers to use Google’s DNS (8.8.8.8 and 8.8.4.4) and that works fairly well. Note that if ALL your Dynamic DNS addresses are from freedns.afraid.org then you may want to change one line in the above script, from

IP=`/usr/bin/dig +short $HOST | /usr/bin/tail -n 1`

to

IP=`/usr/bin/dig +short @ns1.afraid.org $HOST | /usr/bin/tail -n 1`

This change will specify that the afraid.org DNS server is to be used for these lookups (and ONLY for these lookups, not for every DNS request your system makes – don’t want to overload the servers of this free service!). This may be particularly important if the DNS server you normally use is a caching server that doesn’t always do real-time lookups for each DNS request (for example, if you have installed the BIND DNS Server on your system). If some of the Dynamic DNS addresses come from other services then you could use a similar modification that checks a public DNS service that does not cache entries for long periods of time; as I write this Google’s DNS servers seem to update in near real time.

One thing some may not like is that this script basically hands the “keys to the kingdom” to your authorized users, by giving them access to all ports, or at least all ports not explicitly denied by rules higher in priority. It would be easy enough to change the rule that is written to iptables, or even add additional ones, in the above script, so that you could specify access to individual ports. The other problem is it works great for those external users at fixed locations that don’t move around a lot. It might not work quite as well as well for softphone users on laptops due to the delay between the time they turn on the laptop and the time your Asterisk server picks up the new address.

This has actually worked the best for me of anything I’ve tried so far because once you get the external user’s router set up to do the Dynamic DNS updates, they don’t have to think about doing anything else prior to making a call.

EDIT (December, 2015): If it is not possible or appropriate to update the dynamic DNS automatically from the users’ router, there may be another option. If any of your users have Obihai devices (or possibly another brand of VoIP device that includes an accessible “Auto Provisioning” feature that is not currently being utilized), you may want to know that they do not need to run a separate client to update their dynu.com or freedns.afraid.org dynamic IP address, because an Obihai device (and possibly some other brands of VoIP devices) can do that automatically. This is NOT a recommendation for Obihai devices, but if you or one of your users happens to already have one, here is the information as originally found in this thread on the Obihai forum, posted by user giqcass, who wrote:

Rough Draft for hackish DNS updates:

This hack will let your OBi update Dynamic DNS. It isn’t perfect but it works very well. It’s as simple as calling a url to update the DNS at afraid.org. I believe it would be a simple task to add this feature to the OBi firmware directly. So please add this OBiHai. Pretty please. Until then here you go.

Set up a Dynamic DNS host at http://freedns.afraid.org/
Go to the Dynamic DNS tab.
Copy the “direct” update url link.
Open your Obi admin page.
Click the System management page.
Click Auto Provisioning.
Under “ITSP Provisioning” Change the following.
Method = Periodically
Interval = This setting must be greater then 400 so not to over use resources. I use 3667.
ConfigURL = Paste the update link you got from afraid.org (use http://… not https://…)

Press Submit at the bottom of the page. Restart you OBi.

If you use choose to use dynu.com instead of freedns.afraid.org (which you might because dynu.com doesn’t force you to visit their web site periodically to keep your domain), the procedure is the same (after the first line), except that for the ConfigURL you would use:

http://api.dynu.com/nic/update?hostname=YOUR_DYNU_DYNAMIC_DNS&username=YOUR_DYNU_USERNAME&password=MD5_HASH_OF_PASSWORD

Replace YOUR_DYNU_DYNAMIC_DNS with your dynamic DNS domain name, YOUR_DYNU_USERNAME with the username you use to log into your dynu.com account, and MD5_HASH_OF_PASSWORD with the MD5 hash of your dynu.com password OR your IP Update Password if you have set one (which is recommended). To get the MD5 hash of the password you can enter it on this page. To set or update your IP Update Password, use this page.

The advantage of this is that if one of your users travels and takes their VoIP device with them, it would be able to change the dynamic DNS each time they plug in at a new location (not immediately, but after several minutes at most), so that if you use the technique outlined in this article your server will recognize their current address and permit access. Remember that it’s okay to use more than one Dynamic DNS service simultaneously, in case you or your user are already using a different one that doesn’t provide a simple update URL like dynu.com and freedns.afraid.org do. Other brands of VoIP adapters that have a similar “Auto Provisioning” feature may be able to do this as well, but we don’t have specific information for any of them. If you do, please feel free to add that information in a comment.

Note that we are not recommending any particular free dynamic DNS service. If you want to know what your options are, there is an article on the Best Free Dynamic DNS Services that will show you some options. You want one that is reliable and that will not disappear in a few months, but since we don’t have a crystal ball, we can’t tell you which ones might fit that criteria.

A Perl script to send Caller ID popups from Asterisk to computers running Notify OSD (such as Ubuntu Linux) or any command-line invoked notification system

 

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 is basically an update to my article, A Perl script to send Caller ID popups from Asterisk to computers running Growl under OS X on a Mac or Growl for Windows, and you should still use that article if you are sending notifications to a computer on your local network that runs Growl or Growl for Windows as the notification system.

I wanted to find a way to send Caller ID popups to a Ubuntu Linux box, and in the process I discovered a different method of sending such notifications.  There are pros and cons to using the new method, so let me explain those first:

Pros:

  • Can send notifications to any computer that supports command line generated notifications (so it could also be used with Growl, if you can use growlnotify from a command prompt to generate a notification).
  • Can send notifications to any computer that you can SSH into, provided you have it set up to use public/private key authentication rather than password authentication.

Cons:

  • Notifications typically display a couple of seconds later than under the previous method.  I suspect this is due to the SSH authentication taking a second or two.
  • It’s a little bit more complicated to set this up, though not horribly so.
  • Because this uses SSH and requires that Asterisk be granted permission to establish an SSH connection as the super user (by using sudo), there may be unforeseen security risks.

Read that last point again, and please understand that as with all projects on this site, I offer this for experimental purposes only.  I explicitly do not warrant this method as being 100% secure, nor will I tell you that it could not be exploited to do bad things on your system.  I don’t think it can (and feel free to leave a comment if you think I’m wrong), but I just don’t know that for sure.  So, if you decide to use anything in this article, you agree to assume all risks. If you’re the type that likes to sue other people when something goes wrong, then you do not have permission to use this code.  We’re all experimenters here, so no guarantees!

As with the previous method, you must have the Perl language installed on your Asterisk server, and you must have the Asterisk::AGI module 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.

There’s one additional thing you must do on the Asterisk server before this will run, and that’s allow Asterisk to run the ssh command as root. So, add this to your /etc/sudoers file (probably at the very end, but in any case it should be obvious where to add this because it will be in a section where Asterisk is granted similar privileges with regard to other programs):

asterisk ALL = NOPASSWD: /usr/bin/ssh

Next you want to copy and paste the following Perl script to the filename /var/lib/asterisk/agi-bin/notifysend.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 have modified.

#!/usr/bin/perl
use strict;
use warnings;
use Asterisk::AGI;
my $agi = new Asterisk::AGI;
my %input = $agi->ReadParse();

# Next two lines fork the process so Asterisk can get on with handling the call
open STDOUT, '>/dev/null';
fork and exit;

my $num = $input{'callerid'};
my $name = $input{'calleridname'};
my $ext = $input{'extension'};
my $user = $ARGV[0];
my $ip = $ARGV[1];

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

# OMIT this section if you don't want IP address
# checking (e.g. you want to use foo.bar.com)
unless ( $ip =~ /^(d+).(d+).(d+).(d+)$/ ) {
    exit;
}

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

my @months = (
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
);
my @weekdays = (
    "Sunday", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday"
);
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/;

my $cmd = qq(./remotenotify.sh "$name" "$num calling $ext at $fulldate");
$cmd = "sudo ssh $user@$ip '$cmd'";
exec "$cmd";

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 (if you have not already done so when using the previous method). Note that if you have a mix of computers on your network and you are using both the new and old methods, you only need to do this once — it works with both methods (hence the reference to “growlsend” in the database and “gshelper” as the name of this script). Call it /var/lib/asterisk/agi-bin/gshelper.agi and note that there is a line within it that you may need to change to reflect the scope of your local network:

#!/usr/bin/perl
use strict;
use warnings;
my ($prev, @mac, @ip);
# Change the 192.168.0.0/24 in the following line to reflect the scope of your local network, if necessary
my @nmap = `nmap -sP 192.168.0.0/24|grep -B 1 MAC`;
foreach (@nmap) {
    if (index($_, "MAC Address:") >= 0) {
        @mac = split(" ");
        @ip = split(" ",$prev);
        `/usr/sbin/asterisk -rx "database put growlsend $mac[2] $ip[1]"`;
    }
    $prev=$_;
}

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 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). However, note that the syntax used in extensions_custom.conf differs from what is shown there, depending on whether you are specifying an IP address or a MAC address to identify the target computer.

First, if you are specifying the IP address of the target computer, then instead of using this syntax:

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

You will need to use this:

exten => ****525,1,AGI(notifysend.agi,username,192.168.0.123,525)

Note that username is the account name you use when doing an ssh login into the destination system, and it should also be the desktop user on the system (not root!). Let’s say that the system is currently at IP address 192.168.0.123. In order for this to work, you need to be able to ssh into your Ubuntu box from your Asterisk server, using the following command from the Asterisk server’s command line:

ssh username@192.168.0.123

If it asks for a password, then you need to follow the instructions at Stop entering passwords: How to set up ssh public/private key authentication for connections to a remote server, and get it set up so that it will not ask for a password (if you don’t like my article, maybe this one will make it clearer).

It’s probably easiest to configure each computer that is to receive notifications to use a static IP address. 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(notifysend.agi,username,01:23:45:AB:CD:EF,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 (from gshelper.agi) 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(notifysend.agi,username,192.168.0.123,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.

Now is where it gets just a bit more complicated than in the original method. If you have followed the above instructions, you’ll be able to send the notifications to the remote system using SSH, but there will be nothing there to receive them. So we have to create a small script on the receiving system to do something with the received notifications. That script will vary depending on the receiving system, but it must be named remotenotify.sh and it must be placed in the destination user’s home directory, and don’t forget to make it executable! Here’s one that will work in most Ubuntu installations that have Notify OSD installed:

export DISPLAY=:0
notify-send --urgency="critical" --icon="phone" "$1" "$2"

Those two lines are all you need. On a different type of system (or if you have multiple displays) you may need to or wish to do something different. For example, as I mentioned above, if the destination system is running Growl then your remotenotify.sh script will need to call growlnotify, but beyond that I wouldn’t know what to use there (EDIT: But if the target system is a Mac that is running OS X, a pretty good guess would probably be that you’d only need one line, something like this:

growlnotify -s -p 1 -a Telephone -m "$2" $1

In this case it should make the notification sticky until dismissed by the user, give it a priority of 1 — the default is 0 — and use the application icon from the “Telephone” application if you have it installed. Instead of -a to specify an application’s icon you could use -I followed by a path to an .icns file that contains an icon you want to use.  Type growlnotify –help to see all the growlnotify options.  Oh, and before you can make an SSH connection to a Mac you have to go into System Preferences | Sharing and turn on Remote Login).

The beauty of this approach is that you can make the remotenotify.sh script as simple or as complicated as you need — you could even make it forward a notification to other devices if you wish, but figuring out how to do that is up to you (if you come up with something good, please leave a comment and tell us about it!).

If you’re running Ubuntu on the target system, here’s a few articles you may wish to use to help you get your notifications to look the way you want them to appear:

Tweak The NotifyOSD Notifications In Ubuntu 10.10 Maverick Meerkat [Patched NotifyOSD PPA Updated]
Get Notifications With A Close Button In Ubuntu
Configurable NotifyOSD Bubbles For Ubuntu 11.04: Move, Close On Click, Change Colors And More

If you want to be able to review missed notifications, you may be able to use this (as a side note, why don’t they have something like this for Growl?):

Never Miss A NotifyOSD Notification With “Recent Notifications” GNOME Applet

The idea behind the shell script that runs on the target system was found in a comment on the following article, which may be of special interest to MythTV users:

Send OSD notification messages to all systems on a network

There are links to other original sources throughout the article, so feel free to follow those if you want more in-depth commentary.

How to export Outbound Route Dial Patterns and Trunk Dialed Number Manipulation Rules to a CSV file in FreePBX

 

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.

If you use a recent version of FreePBX, you are familiar with the new and tedious method of entering Outbound Route Dial Patterns and Trunk Dialed Number Manipulation Rules.  Fortunately, version 2.9 and above offer a way to import a list of patterns from a CSV file (there’s a way to patch FreePBX 2.8 to get this functionality as well — see Ticket #4691).

What they don’t give you is a way to export a list of patterns once you have them installed.  So if you want to clone a route and you’ve lost your original CSV file (or never had one to begin with because FreePBX converted your existing routes and trunks when you upgraded from version 2.7), what do you do?  Fear not, because it actually is possible, if not exactly the most straightforward process.

EDIT: Now there is an easy way around all this — see this thread on the FreePBX Swiss Army Knife Module.  If you use that module, you don’t need to read the rest of this article (although, you might be interested in the part about editing CSV files). Unfortunately, it is reported that the module does not work with FreePBX 2.10 or above, and the author has said he will not fix it to work with newer versions. It is possible that the ability to export outbound route and trunk data to a CSV file may be present in the newest version(s) of FreePBX.

EDIT: Steps 1 and 2 involve using a Database editor module to export the data to a CSV file.  Unfortunately, one commenter says that this module no longer works with FreePBX 2.9.  There are other ways to accomplish the same thing — see the edit at the end of this article to use Webmin or phpMyAdmin instead of the Database editor module.  If you export the data using one of those other programs, then skip to step 3 below.

Step 1: Go to the FreePBX bug tracker and look for Ticket #4793 — Database editor module (like phpMyAdmin for FreePBX).  On that page you’ll find a download link for dbeditor-1.0.tgz which (at the time of this writing) is the only version of this software available. Download and install it as you would any third-party module (download it to your computer, then in FreePBX’s GUI navigate to Module Admin and then click the “Upload Module” link, then upload the module and follow the directions to complete the install).

Step 2: Once you have the Database Editor installed, it will appear under the FreePBX “Tools” tab, in the “System Administration” section. Click on the “Database Editor” link, and you should see a list of database tables used by FreePBX. The two you are interested in are called outbound_route_patterns and trunk_dialpatterns. Near each pattern name you will see two links for “Export” and “Drop” — do not click either of those (especially be careful not to click drop!), because the “Export” here will export the table in MySQL format, which is not what you want. Instead, click on the name of the table (that is, click on either outbound_route_patterns or trunk_dialpatterns) and a new page will open. Near the top of the page you will see a place where it says, “Export to CSV: pipe – tab – comma – semicolon” — click on comma and it should bring up a file save dialog that will let you save the file to your system.

Step 3. Load the downloaded file into any text editor that can deal with Linux/Unix-style line endings and not change them (so, don’t use Notepad!), or better yet, use a CSV editor if you have one (an excellent free one is CSVed, which runs under Windows but will also install and run under CodeWeavers’ CrossOver on a Mac, which tends to make me think it would probably also run under WINE on a Linux or Mac OS X computer). I do NOT recommend opening the file in a spreadsheet application such as Excel, because if you have any patterns that start with one or more leading zeroes, those might be removed, and it’s also possible that any non-numeric characters may be misinterpreted or removed.

The first number in each line is associated with a particular outbound route or trunk, so, you want to cut out the lines not applicable to the route or trunk you want to keep. Don’t erase the top (header) line. If you have many routes or trunks, it may be a bit tricky to figure out which is which, since the numbers don’t tell you the name of the route or trunk they are associated with.

Deleting columns using CSVed

After you do that, you also have to get rid if the first column in each line. So let’s say you are using route 3, and each line starts with 3,. What you want to do is a search and replace on <newline>3, (or expressed as a regular expression: n3,) and replace it with a newline only (n as a regular expression). In a CSV editor you may be able to just delete the first column. For a trunk, the principle is the same except that you will need to remove the first AND last columns, leaving only the middle three.

While you’re at it, it’s also possible to use search and replace in other ways. For example, if you are duplicating list of outbound route patterns but need to change the extension field pattern in all lines, you could do that using search and replace, if you understand what you’re doing.

Step 4. Once you have edited out all the lines except the ones pertaining to the route or trunk you want, you need to change the header line at the top. It’s important to get this right. For an outbound route you want to change it from this:

route_id,match_pattern_prefix,match_pattern_pass,match_cid,prepend_digits

(Note that the route_id may be missing after the previous edit) to this:

prefix,match pattern,callerid,prepend

Visually inspect the lines following the header to make sure you have four fields separated by exactly three commas.

For a trunk, you will need to change the first header line from this:

trunkid,match_pattern_prefix,match_pattern_pass,prepend_digits,seq

(Note that the trunkid and seq may be missing after the previous edit) to this:

prefix,match pattern,prepend

Visually inspect the lines following the header to make sure you have three fields separated by exactly two commas. Also, and this applies to trunks only, if it is important that trunk dial patterns be in a particular order then you will want to check to make sure they are in the correct order in the CSV file, since the “seq” column is not preserved. In many situations this is not an issue but in certain special cases the order of trunk dial patterns can make a difference in how they are processed.

Step 5: Save the modified file to a file with the .csv extension (if using a CSV editor make sure you are saving in comma-delimited format). Again, try to make sure your editor doesn’t change the line endings – I don’t know for certain that it would make a difference, but it might.

Step 6: Now you can create a new route or trunk, and in the “Dial patterns wizards” or “Dial Rules Wizards” dropdown select “Upload from CSV” and select your file to upload. Note that if you are using a beta version of FreePBX 2.9, it may complain if you try to submit an outbound route with no patterns, even if you are uploading a CSV file. In that case, just put a single “X” in the “match pattern” field. After you submit changes, be sure to scroll through the patterns to make sure they appear to be correct. In particular, make sure that all values are in the correct fields.

There are probably other ways to accomplish this, and maybe eventually the FreePBX developers will add an export function on the route and trunk pages (obviously, it would probably not be a good idea for me to request it, and besides, it appears that someone already has).

EDIT:  Here is a way to export the data using Webmin or phpMyAdmin (replacing steps 1 and 2 above).  Use Webmin if you have it, because it produces cleaner output:

If using Webmin, from the main Webmin page, go to “Servers”, then “MySQL Database Server.”  Under “MySQL Databases”, click on “asterisk”, and it should take you to the “Edit Database” page (be very careful from here on out because if you do the wrong thing you could really mess up your system).  In the “Edit table” dropdown, select either outbound_route_patterns or trunk_dialpatterns, depending on which you want to work with.  That should take you to an “Edit table” page, but at the bottom of that page you should see a button labeled “Export as CSV.” Click on that button, and it will take you to a “CSV export options” page.  You want to select the following:

  • CSV with quotes
  • Yes to “Include column names in CSV?”
  • For export destination, use whichever is more convenient for you (note that if you “Save to file” it will be placed in a directory on your server, so you might find it easier to display it in a browser window and then save it from there).
  • Export all rows
  • Leave all columns selected in “Columns to include in CSV” (you’ll discard the first column in step 3, but you’ll still need it to allow you to determine which rows to keep for each route or trunk)

Then click the “Export Now” button.  If you exported to a browser window, use Ctrl-A to select all the lines, and Ctrl-C to copy them (⌘A and ⌘C on a Mac), then proceed with Step 3 above (except use Ctrl-V or ⌘V to paste the lines into the text editor). Or, if you prefer to use a CSV editor, then in your browser simply go to File | Save Page As… and save the entire page as a plain text file with a .csv extension to your local machine, and then proceed with Step 3 above.

If using phpMyAdmin, from the main page select “asterisk” in the left-hand column, then (still in the left-hand column) either outbound_route_patterns or trunk_dialpatterns, depending on which you want to work with. Then click the “Export” tab in the main window, and then under “View dump (schema) of table”, in the “Export” section select CSV.  The view should change to show an “Options” section, and there you want to change “Fields terminated by:” from a semicolon to a comma, and then check the “Put fields names in the first row” checkbox.   Then click the “Go” button and it should display the data in a format that can be copied and pasted into a text editor. Sorry, that’s the best I can advise you with regard to phpMyAdmin, since I seldom use that program (and I may have an older version, so things might have changed slightly).

FreePBX voicemail hacks

 

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 January, 2011 and may contain outdated information.

Motel Phone
Image by Andreas_MB via Flickr

A few things you should know about FreePBX voicemail:

• If you are not receiving voicemail notifications (stutter dial tone, message waiting indication on certain phones, etc.) there are two things to check.  One is to go into /etc/asterisk/vm_general.inc and see if there is a line of the form ;pollmailboxes=yes — if it is commented out (semicolon in front), uncomment it by removing the semicolon.  The other is to go to the /var/spool/asterisk/voicemail directory and make sure that you have directories there called default and device, and that one is symlinked to the other (generally default is the “real” directory and device is the symlink). If the device directory is missing, make sure you’re in the voicemail directory and do this:  ln -s default device

• If you have users in different time zones, you can have the voicemail “envelope” information say the correct time by creating a [zonemessages] context at the end of /etc/asterisk/vm_general.inc (in later versions of FreePBX you can also enter these in the Timezone Definitions section of the Voicemail Admin module) — here’s a simple one showing the four major time zones in the continental United States (I know this is not complete, it’s just an example):

[zonemessages] eastern=America/New_York|'vm-received' Q 'digits/at' IMp
central=America/Chicago|'vm-received' Q 'digits/at' IMp
mountain=America/Denver|'vm-received' Q 'digits/at' IMp
pacific=America/Los_Angeles|'vm-received' Q 'digits/at' IMp

Then, on each extension setup page in FreePBX, find the Voicemail & Directory section, and under that the VM Options.  In the VM Options add a tz= option for each user (for example, tz=eastern), using one of the zones you defined under [zonemessages] in /etc/asterisk/vm_general.inc.  Note that multiple options in VM Options must be separated by the | (vertical bar) character (not that you’re likely to have multiple options, but I mention it just in case).

• If your system is not used in a large office, or some other location where not all users can be trusted, you can disable the requirement to enter a PIN when using *97 to pickup voicemail for your own extension.  To do that, add the following context to /etc/asterisk/extensions_custom.conf:

NOTE: This is the original code for older versions of FreePBX:

[custom-voicemail-retrieve] exten => s,1,Answer
exten => s,n,Wait(1)
exten => s,n,Macro(user-callerid,)
exten => s,n,Macro(get-vmcontext,${CALLERID(num)})
exten => s,n,VoiceMailMain(${CALLERID(num)}@${VMCONTEXT},s)
exten => s,n,Macro(hangupcall,)
exten => h,1,Macro(hangupcall,)

In newer versions of FreePBX (probably 2.9 and later) use this instead:

[custom-voicemail-retrieve] exten => s,1,Answer
exten => s,n,Wait(1)
exten => s,n,Macro(user-callerid,)
exten => s,n,Macro(get-vmcontext,${AMPUSER})
exten => s,n(check),Set(VMBOXEXISTSSTATUS=${IF(${MAILBOX_EXISTS(${AMPUSER}@${VMCONTEXT})}?SUCCESS:FAILED)})
exten => s,n,GotoIf($["${VMBOXEXISTSSTATUS}" = "SUCCESS"]?mbexist)
exten => s,n,VoiceMailMain()
exten => s,n,GotoIf($["${IVR_RETVM}" = "RETURN" & "${IVR_CONTEXT}" != ""]?playret)
exten => s,n,Macro(hangupcall,)
exten => s,check+101(mbexist),VoiceMailMain(${AMPUSER}@${VMCONTEXT},s)
exten => s,n,GotoIf($["${IVR_RETVM}" = "RETURN" & "${IVR_CONTEXT}" != ""]?playret)
exten => s,n,Macro(hangupcall,)
exten => s,n(playret),Playback(beep&you-will-be-transfered-menu&silence/1)
exten => s,n,Goto(${IVR_CONTEXT},return,1)
exten => h,1,Macro(hangupcall,)

Then do the following in FreePBX’s GUI (do these steps in the order shown):

Go to Feature Codes and under Voicemail, disable “My Voicemail” (*97) using the dropdown, then Submit Changes.

Go to Custom Destinations (under the Tools tab) and create a new Custom Destination:  custom-voicemail-retrieve,s,1 — then Submit Changes.

Go to Misc. Applications and add a new Misc. Application. Make the feature code *97 and the destination the Custom Destination you created in the previous step, then Submit Changes.

Finally do an “orange bar reload” in FreePBX. Now when your users dial *97, it will assume they are authorized to pick up the voicemail for the extension they’re calling from. Obviously, this is probably not a good idea in any kind of office setting.

Got any other FreePBX voicemail hacks you like?

Asterisk 1.8.x and FreePBX users: How to NOT answer Google Voice calls UNTIL the called extension answers

 

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.

EDIT (May, 2018): FreePBX and Asterisk users that wish to continue using Google Voice after Google drops XMPP support should go here: How to use Google Voice with FreePBX and Asterisk without using XMPP or buying new hardware.

This article was originally published in December, 2010 and may contain out-of-date information.

Many folks are experimenting with Asterisk 1.8.x and Google Voice.  In most cases the way it’s set up is that when a Google Voice call arrives, Asterisk answers the call, then sends a touch-tone digit “1” to Google Voice to answer the call, then proceeds to ring the destination extension.  This is necessary because when you configure Google Voice to use a Gtalk destination, they require you to press “1” to accept the call, even if you’ve configured Google Voice not to require that.  I don’t know if this is a bug in Google Voice or if they did it that way deliberately for some reason, but answering the call and accepting it upon arrival at the PBX has a few unintended side effects:

  • If your callers pay for long distance by the minute, they get charged from the moment the called extension begins ringing – even if you never answer the call.
  • You can’t use Google Voice’s Voicemail, nor their transcription service, because you’ve already answered the call.
  • Callers may hear a confusing double ringing tone at the start of ringing — one ring from Google Voice and the rest from Asterisk.

On the other hand, there are some advantages to doing it that way:

  • Because you’ve answered the call, you can let the extension ring as long as you like before sending it to voicemail, and Google Voice won’t snatch it away in 25 seconds and send it to their voicemail.
  • You can use Asterisk’s voicemail, if that’s what you prefer.

For those who’d prefer to let Google Voice handle their voicemail, or who object to making callers pay to listen to up to 25 seconds of ringing, there is a way to not answer the call and send the touch tone “1” until  after the destination extension has actually picked up the call.  If you are using plain vanilla Asterisk, all you have to do is make sure your Dial() command contains two additional options.  Consider this example line of Asterisk dialplan:

exten => gvoicein,n,Dial(SIP/1004,35,rTWtwaD(:1))

The important part here is the aD(:1) — the other options can be whatever you’d normally use, if any, but it’s the aD(:1) that does the magic. Now at this point, if you’re a FreePBX user you may be wondering how on earth you can modify the Dial() string, since the code that generates it is buried deep within the bowels of FreePBX. Fortunately, there is a way. Consider the following piece of code that might be used in extensions_custom.conf to bring in Google Voice calls:

[googlein]
exten => _[0-9a-z].,1,Noop(Incoming Google Voice call for ${EXTEN})
exten => _[0-9a-z].,n,Set(CALLERID(name)=${CUT(CALLERID(name),@,1)})
exten => _[0-9a-z].,n,GotoIf($["${CALLERID(name):0:2}" != "+1"]?notrim)
exten => _[0-9a-z].,n,Set(CALLERID(name)=${CALLERID(name):2})
exten => _[0-9a-z].,n(notrim),Set(CALLERID(number)=${CALLERID(name)})
exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,Answer
exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,SendDTMF(1)
exten => _[0-9a-z].,n,Goto(from-trunk,gv-incoming-${CUT(EXTEN,@,1)},1)
exten => h,1,Macro(hangupcall,)

With this context you’d use gv-incoming-username (where username is the part of the associated gmail address before the @) as the DID in your inbound route — a DID doesn’t have to be numeric even if FreePBX whines about it, and the advantage is you only need one context to handle incoming calls for all your Google Voice accounts.  This particular context is slightly modified from one found in the PBX in a Flash forum, but note that it contains these four lines that wait ONE second, answer the call, wait ONE second (you do NOT have to wait two seconds, despite what any other article may say, and in fact the one second wait might be unnecessary), and then send the touch tone digit 1:

exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,Answer
exten => _[0-9a-z].,n,Wait(1)
exten => _[0-9a-z].,n,SendDTMF(1)

You will find those four lines, or some variation on them (sometimes just the last three), in just about every published method for using Google Voice with Asterisk and FreePBX.  But, in FreePBX at least, you can replace them with this:

exten => _[0-9a-z].,n,Set(DIAL_OPTIONS=${DIAL_OPTIONS}aD(:1))

This slides the aD(:1) into the options that will be used with the Dial command, so when the extension answers, the call will be answered and then the touch tone “1” will be immediately sent to Google Voice, and then the audio between Google Voice and the called extension will be bridged as usual.

Unfortunately, or maybe fortunately depending on your point of view, it appears that if the call should go to Asterisk’s voicemail, the call will not be answered and the DTMF 1 will never be sent.  This means that if, for whatever reason, you don’t answer the incoming call, after 25 seconds it will go to Google’s voicemail.  There are doubtless ways around that (and if anyone’s truly interested, leave a comment and I’ll suggest a way that may work, that involves routing the incoming call to a ring group first) but I suspect that the majority of people who want to do this will be doing it because they want to use Gmail’s voicemail.

I’ve tested this and it works for me, though I would not use it on a regular basis because I prefer Asterisk’s voicemail.  If it doesn’t work for you for some reason, the only suggestion I can offer is adding a w before the :1, so the added options look like aD(w:1) – that will add a one-half second delay before the “1” is sent, and more than likely it won’t help one bit, but may cause callers to not hear your “hello” or other greeting.  But, you can try it and see — at least one user has reported it to be necessary.  If that doesn’t work, I probably won’t be able to help you but if you leave a comment, maybe someone else can.

And, should anyone from Google Voice read this, it would be really helpful if you’d do two things:

  1. Give us a way to disable Google Voice’s voicemail so we don’t have to resort to hacks like this to discourage callers from leaving a message there.
  2. Fix the bug (or “feature”) so that when we turn off call screening, it’s off for ALL destinations, including Gtalk!

Link: Interesting security technique for Asterisk and FreePBX users (may work with other SIP-based PBX’s also)

 

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 November, 2010.

NOTE: For some reason WordPress absolutely hates it when I try to edit this post, and turns links and other things into piles of steaming poo.  If things don’t look right here please e-mail me or leave a comment and I’ll check it out.  WordPress, I KNOW how I want my articles to look, why can’t you just leave them alone?

One problem faced by some SIP-based VoIP PBX administrators is the issue of security when you have external extensions (that is, extensions located anywhere in the world that’s not a part of your local network). You want to allow those extensions (the ones you’ve authorized) to connect to your system, but you prefer to keep everyone else out, and preferably not even tip them off that there’s a PBX there. The idea is, if the bad guys that would like to break into PBX’s don’t even realize that there is a PBX at your IP address, they won’t waste any time trying to crack into your system.

There have been other suggestions for how to handle this but many of them require your users to take some additional action(s) that they would not normally have to take, and users hate having to lift a finger to do anything to enhance their security. Which brings us to a rather clever technique that doesn’t require user to do anything other than use their phones as they normally would. It might be a tiny bit of a pain to set up initially, but the results may be worth it. I would call this medium level security because if someone is sniffing your packets, this alone may not keep them out, but most of the lowlifes that try to break into PBX’s don’t actually have sufficient access to sniff your packet stream (and also, they’d have to know the exact technique you’re using to be able to crack this). So without further ado…

Secure your VoIP server with the SunshineNetworks knock

(As of October 24, 2012, the above link appears to be DEAD — see the edit at the end of this article)

Note that while the article recommends changing the SIP port to something other than 5060, their basic technique (the “knock”) should still work even if you feel you need to stay on 5060. My only fear about changing the SIP port would be the possibility of losing communications with VoIP providers and with other systems I legitimately send/receive voice traffic to/from. They’re probably going to keep using 5060 even if I don’t. EDIT: My concern here may be unfounded — note the comment below from Alex of Sunshine Networks, who said that “changing the SIP port is quite safe. Your SIP server will send this SIP port along in it’s first SIP invite registration to the VoIP provider. So unless your VoIP provider is actively blocking out anything else than port 5060, it should work fine. We use this technique with 3 different major SIP providers in Australia and never had problems. So far we haven’t seen any unintended consequences.”

I haven’t personally tested this, so if you do, please consider leaving a comment to let me know how it worked for you. The two things I wonder are, do these rules survive a reboot, and can you have more than one secret phrase that would let people in (in case you want to use a different one for each external extension)? EDIT: Those questions are also addressed in Alex’s comment below. Also, those of you running PBX in a Flash should take note of Ward Mundy’s comment about changing an entry in /etc/sysconfig/iptables in this thread. In that same thread, there appears a method to view the “knock” each extension is currently sending — just do “sip debug” from the Asterisk CLI for an hour or so (long enough for all your endpoints to register, after which you can use “sip no debug” to turn it off), then run this at the Linux command prompt (not from the CLI!):

grep "From: " /var/log/asterisk/full|cut -f1 --delimiter=; | sort -u

For each of your remote extensions, you’ll see a line that looks something like this:

From: The Knock <sip:234@nn.nn.nn.nn>

“The Knock” may or may not be enclosed in quotation marks, but it apparently doesn’t matter (you don’t include them in the iptables rules). If you haven’t used a specific “knock”, it could be the actual user’s name, if you set that up when you first set up the endpoint. Anyway, I’d suggest running this BEFORE you actually implement the iptables rules, so you know ahead of time what each endpoint is sending.

EDIT (Added January 8, 2012): I am now using a slight variation on this technique on one of the systems I administer. Without going into too many specifics, I will just note that some SIP devices and VoIP adapters actually already send a unique string that you can use as a “knock” – you do not have to configure a new one, you just need to find out what the device is already sending and use that. For example, let’s say you have an VoIP device connecting to your Asterisk server as extension 234. All you have to do is go to the Asterisk CLI (NOT the Linux command prompt) and enter this:

sip set debug peer 234

(Replace 234 with the actual extension number). Now, assuming that the device is connecting to your server, you will start to see SIP packets scroll across your screen. Within a few minutes you should see one like this (IP addresses have been xx’ed out):

<--- SIP read from UDP:xx.xx.xx.xx:5061 --->

REGISTER sip:xx.xx.xx.xx:5060 SIP/2.0
Call-ID: e10700c2@xx.xx.xx.xx
Content-Length: 0
CSeq: 56790 REGISTER
From: <sip:234@xx.xx.xx.xx>;tag=SP8f427e45f1e19cb24
Max-Forwards: 70
To: <sip:234@xx.xx.xx.xx>
Via: SIP/2.0/UDP xx.xx.xx.xx:5061;branch=z4b9hGK-4f0473a8;rport
Authorization: DIGEST algorithm=MD5,nonce=”37cd169d”,realm=”asterisk”,response=”a726bfed5db321a7bc967b997b5157c2″,uri=”sip:xx.xx.xx.xx:5060″,username=”234″
User-Agent: xxxxxx/xxxxxx-x.x.x.x
Contact: <sip:234@xx.xx.xx.xx:5061>;expires=60;+sip.instance=”<urn:uuid:nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn>”
Allow: ACK,BYE,CANCEL,INFO,INVITE,NOTIFY,OPTIONS,REFER
Supported: replaces

<————->

If you don’t see this you may need to increase the debug level. After you see a packet like this, you can turn off sip debugging:

sip set debug off

The string you are looking for is in the Contact: string above (the nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn is replaced by a unique string). So, where in the instructions for the “knock” they show a sample string such as:

iptables -I door 1 -p udp --dport 5060 -m string --string "mysecretpass" --algo bm -m recent --set --name portisnowopen

I would change the --dport parameter to 5060:5061 (since an VoIP adapter sometimes uses port 5061 for the second service provider — for an device that allows up to fours service providers, use 5060:5063) and the --string parameter to “<urn:uuid:nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn>”, but using the actual string sent by the device, of course. I know the Sunshine Network people recommend using something other than port 5060 but I just can’t bring myself to go quite that far, and even their examples show 5060.

Some other SIP-compliant devices also send unique strings in their REGISTER packets. One that does NOT do so, as far as I am aware, is the venerable Linksys PAP2. And I also do not believe that any of the Sipura line of devices send such a unique string.

Naturally, if an intruder KNOWS you are using that technique, they could try a brute-force attack on the unique string. So I recommend only using this with “uncommon” extension numbers (not 200 or 1000, for example) and with a VERY strong secret/password on the SIP connection. But it is another line of defense against would-be intruders!

EDIT (Added October 24, 2012): The original article, and most of the original site for that matter, seems to have gone offline. While I’m not going to repost the original article here without permission, I will give you a few more details and a couple of excerpts. First, they advised that you change the SIP port to something other than 5060 – they suggested using something in the range 20001 through 49000, though I am not sure why. They uses port 34122 in their examples, and noted that if you are running PBX software that has a “SIP Settings” module, if your find a setting for “Bind Port”, that would be the one to change. Of course if you do this, you then have to change the SIP port on ALL your SIP-based phones and VoIP adapters.

With regard to the “knock” itself, they said this:

Technical information :
… Technically, our knock consists of a secret passphrase which is sent together with the first SIP packet from the phone to the server. SIP packets are text files, very much readable like http packets are. The SIP headers in a REGISTER invite packet have a lot of information, and one of those headers is called the “Display Name”. This display name is used only internally in your Asterisk server and has no other use, so we figured we could fill in anything and the Asterisk functionality would still work fine. We decided to use it as a port knock password.

How does it work :
The Asterisk administrator sets up a simple iptables rule. The iptables rule checks for a secret phrase inside packets sent to the SIP port ( 5060 by default, 34122 after having changed it ). Unless it finds this secret phrase, it will drop the packets to this port. All the remote phone has to do is fill in the “User Name” SIP property on his SIP phone with the secret phrase, and he will be able to connect.

What you then needed to do was to go to into your Asterisk server and from a Linux command prompt, issue the following command:

iptables -N door

Then for EACH “knock” string you want to use, you would do this from the command prompt (note this is only one line, and note that 34122 is the example port and “mykn0ckstr1ng” is an example “knock”):

iptables -I door 1 -p udp –dport 34122 -m string –string “mykn0ckstr1ng” –algo bm -m recent –set –name portisnowopen

If you have anyone that needs to register with your server but cannot send the “knock”, but is at a fixed IP address, you’d add a line like this for each instance (again the port and ip address would probably need to be changed, and note that an entire subnet can be specified as in this example — just leave off the /24 if it’s a single ip address):

iptables -A INPUT -p udp –dport 34122 –source 10.10.1.0/24 -j ACCEPT

Then you would enter these three lines, but again using the correct port rather than 34122. In the first line you see the number 4000 — that is amount of time in seconds that the port will be open, and should be greater than 3600 because that’s the default registration timeout for many sip phones and VoIP adapters. The original article notes that you could use 86400, which is a full day:

iptables -A INPUT -p udp –dport 34122 -m recent –rcheck –seconds 4000 –name portisnowopen -j ACCEPT
iptables -A INPUT -p udp –dport 34122 -j door
iptables -A INPUT -p udp –dport 34122 -j DROP

And finally, to make iptables use these rules, you’d enter:

service iptables save

The original Sunshine Networks article notes that…

This code keeps port 34122 closed ( DROP ) unless someone has opened the door ( door ) in which case they are allowed to pass the door for a little more than 1 hour ( 4000 seconds ). Each time the phone re-registers , the SIP secret pass header is sent, and the door is reopened for 4000 seconds. Since the default SIP reregistration time on many phones is 3600, the 4000 seconds will make sure that as long as the phone is connected to the SIP server, or needs to be connected, the dynamic firewall rule is always active.

Once you have done this, if you configure the Display Name or User Name setting with the “knock” string, it should be able to get through your firewall. Any phone that doesn’t have this string won’t. Of course you can always make the “knock” something that a phone already sends (in a SIP register packet), as noted in the previous edit, and then you don’t have to reconfigure the phone at all. If a phone or device tries to connect without sending the “knock”, the firewall won’t allow it (assuming you haven’t previously created some other rule that allows the traffic to pass) and the connection will fail, or at least that is how it’s supposed to work (I make no guarantees because I didn’t come up with this).

If you enter the command cat /proc/net/ipt_recent/portisnowopen you will get a list of IP addresses that have successfully used the “knock” to connect. Remember that after you implement this, it can take up to an hour for a device to attempt to reconnect.

If anyone ever spots the original article back online, please let me know and I’ll remove this edit. I’d rather you get the information direct from the original source anyway, and the short excerpts I have provided here don’t give the complete overview that the original article provided.

EDIT (February 23, 2014): It appears that there is an archived copy of that original article on the Wayback Machine, although we do not know if it is the most recent edit of that article prior to the site disappearing.