Tuesday, December 21, 2010

Asterisk Fixes Google Voice Out

This release fixes the Google Voice out bug. So this would then supersede any patching needed to get Google Voice working on Asterisk 1.8

Get it from asterisk.org


Sunday, December 19, 2010

Nagios Bulk Host Creator (and other bulk operations, if you wish) straight into nagios format

I was at the office today and had to create more than 150 hosts and to create it one by one even with a text editor or WUIs, it can be very taxing. So being the lazy guy that i am, i created this script to generate as many hosts and as an addon, create hostgroup list so that you just need to copy and paste into the hostgroup definition.
This is to create the first of steps when defining Nagios hosts. It of course can be used to generate similar items if they are repeated.
1) You need csvtool (apt-get install csvtool or yum)
So, in essence here are the steps
1) Create a CSV file (in excel or in text editor) with at least 3 fields, hostname, description and IP address. This is probably what your customer had given or your existing inventory.
MIS-M-3-ASW,MIS Admin Switch 3,
Where, MIS-M-3-ASW is the hostname, MIS Admin Switch 3 is the description and of course is that hosts IP address

2) Create a script as seen below #nano ngenerator.sh and make it executable #chmod +x ngenerator.sh

###START ###
# sanjay@astiostech.com
hosttemplate=switches-host # nagios template to use
inputfile=master.csv # inputfile in csv format only
outputhost=hosts.txt # the output for hosts definition which you can copy paste into nagios
outputservices=services.txt # the output for services (all these hosts) definition which you can copy paste into nagios
columns="1-3" #define like 3-4 to read column 3-4 etc

#start check tool
testcsvtool=`which csvtool`
if [[ $? == "1" ]]; then
    echo "ERROR"
    echo "No csvtool software found, do a 'apt-get install csvtool' or 'yum install csvtool'"
    exit 1

#start script
listdata=`csvtool -t ',' col $columns $inputfile`
IFS=`echo -en "\n\b"`
echo "" > $outputhost

# to add all this in hosts.cfg
# modify accordingly
for i in $listdata; do
    #set these
    field1=`echo $i | cut -d "," -f 1`
    field2=`echo $i | cut -d "," -f 2`
    field3=`echo $i | cut -d "," -f 3`

    echo "" >> $outputhost
    echo "# $field1" >> $outputhost
    echo "#----------------------------------------------------------------------" >> $outputhost
    echo "" >> $outputhost
    echo "define host{" >> $outputhost
    echo "        use                        $hosttemplate" >> $outputhost
    echo "        host_name                $field1" >> $outputhost
    echo "        alias                   $field2" >> $outputhost
    echo "        display_name            $field2" >> $outputhost
    echo "        address                    $field3" >> $outputhost
    echo "}" >> $outputhost
    echo "#----------------------------------------------------------------------" >> $outputhost
    echo "" >> $outputhost

# to add all this in services.cfg
echo "" > $outputservices
for i in $listdata; do
field1=`echo $i | cut -d "," -f 1`
    echo -n "$field1," >> $outputservices
exit 0

3) Define settings like the hosttemplate name you already created, inputfile file name (the csv file), the outputhost file name (will be the file you use to copy and paste into Nagios, outputservices file where you can use this that lists all the hosts that were imported from your CSV file (you can use e.g. to add to hostgroup or a minimum ping for instance) and the columns in the csv. If you have more than 3 values in your CSV you need to adjust this value and also the amount of fields you wish to import (field1, field2, field3 is currently defined).
4) Run the script and it will take the input csv file and generate your output files hosts.txt and services.txt
5) Paste into your actual nagios host configuration directly, restart nagios daemon.
You can of course define a lot of other stuff if you wish. Just get a little creative. But this script should already help you a lot a little with the initial script creation.

Monday, December 13, 2010

Unified Communications?– Use Google and Asterisk!

Over the past two weekends, I've dwelled in some not-so-light weighted testing of the spanking new Asterisk 1. 8 PBX. While honestly, there’s not a world of improvements from its already awesome predecessors but heck, its technically only a minor version update from the powerhouses 1.4 and 1.6. While there are many tiny yet significant changes, the ones that I've had a chance to work on (as also seen in this blog) are;
1) Google Talk/Voice (and oh, jabber)
2) Calendaring
3) Festival Text To Speech Engine
See, in contrast these three alone, comprise of probably 90% of what those big boys like Microsoft, Cisco and Ayava would claim Unified Communications on their offerings and thus swoop your left leg out of your budget should you then want/need it. Fret not homies, read on..there’s hope with quality and just about nothing spent on software!
Google boasts it’s business apps which is free for 200 users, mostly useless, but some really cool and completely integrated! Like GMail, Google Calendaring, Google Chat, Google Talk and Google Voice!
The missing link here, is, corporatization of these services and not pocketed or isolations.
Office PBXes are probably the first “corporatization” of a communication medium, next to email (but even that’s sometimes are disparate). People don’t really care if you are from @somedomain vs @someotherdomain, as long as you have a domain, you are regarded a more “serious” fish in the sea.
Now, lets jive!. Imagine, if you have a corporate PBX that can integrate with Google Business Apps! Imagine these;
1) Being able to make calls to the rest of the millions of Google (Talk) users worldwide for completely free
2) Send and receive messages via Google, route them through your cellphone and let your phone read that message to you and vis-a-viz reply a person from your cellphone back!
3) Let your PBX read out your calendar events and write impromptu events when on the GO
4) Put yourself as “busy” on your Google status and all calls now go to your voicemail
5) When a call comes to you, let the PBX decide, how to reach you? Your desk phone, cellphone, skype, google-talk, send you an SMS or an instant message that you got a call, do what ever. You can be reached and the lowest cost is decided by the system!
6) Send Fax? Sure, but its only the most ancient way of communicating, hah! But yea go crazy, how do you wish it delivered? Read it to you over the phone? Sure. Print out straight to your printer/fax, easy!. Send it as an email, anytime!
7) With a Text-To-Speech engine and the capability to do just about any dial-plan, use your PBX to read not only calendars, but things like your email, your tasks, your RSS feeds…google docs? yea, that also…
8) With Google, you have a single UI when you sign in, to call/chat/email friends straight from your browser and integrates with your PBX or the other way around
I am tickled silly with these capabilities. It really lies in the mind what you wish to build. The rest, coding etc, get a guy Smile
I hope organizations will soon come to realize the power of Asterisk 1.8 with its partner in crime Google Apps! Happy building.
From the Astiostechtech Geek (engineering) Office,

Sunday, December 12, 2010

Asterisk 1.8 Calendaring with text to speech reading out your calendar info

The Asterisk Calendaring API aims to be a generic interface for integrating Asterisk with various calendaring technologies. The goal is to be able to support reading and writing of calendar events as well as allowing notification of pending events through the Asterisk dialplan.
There are three calendaring modules that ship with Asterisk that provide support for iCalendar, CalDAV, and Microsoft Exchange Server calendars. All three modules support event notification. Both CalDAV and Exchange support reading and writing calendars, while iCalendar is a read-only format.
NOTE: This is for Debians alike. Please modify accordingly for your own distros.
What we are attempting here to do is to read the calendar event on an and in this example/setup a Google Calendar using its iCal link and read the event to the user of his latest schedule.
The Google iCal is currently set to a public accessible link showing Malaysian holidays: (IN HTML FORMAT)
Part 1 – Getting calendar for ical to work on Asterisk
You need to get Asterisk 1.8.
Go to your preferred source directory, extract Asterisk source
1) wget http://sourceforge.net/projects/freeassociation/files/libical/libical-0.44/libical-0.44.tar.gz/download
2)  tar -zxvf libical-0.44.tar.gz
3 cd libical-0.44
4) ./configure
5) make && make install
6) apt-get install libneon27 # or use yum
7) apt-get install libneon27-dev # or use yum
8)  (Re)compile and install asterisk (not going to show how here), do a “make menuselect” to ensure that Calendar and Internet Calendar Icalendar is enabled/selected
9) nano /etc/asterisk/calendar.conf # add a sample, like below from google’s malaysia holidays ical file
type = ical
url =
refresh = 15
timeframe = 1576800

Part 2 – Getting festival (the free text to speech engine), parts taken off a guide from here
1) apt-get install festival # install it with apt or yum
2) nano /etc/festival.scm # modify some configs on how to parse the audio files
3) Add the following inside this file (below), check to ensure the texts are properly copied, i had issues with that causing festival not to start and listen on TCP port 1314.
;; Enable access to localhost (needed by debian users)
(set! server_access_list '("localhost\\.localdomain" "localhost"))

;; set italian voice (comment the following 2 lines to use british_american)
;;; Command for Asterisk begin

(define (tts_textasterisk string mode)
"(tts_textasterisk STRING MODE)
Apply tts to STRING. This function is specifically designed for
use in server mode so a single function call may synthesize the string.
This function name may be added to the server safe functions."
(let ((wholeutt (utt.synth (eval (list 'Utterance 'Text string)))))
(utt.wave.resample wholeutt 8000)
(utt.wave.rescale wholeutt 5)
(utt.send.wave.client wholeutt)))

;;; Command for Asterisk end
4) Copy the init script (so it will auto run next time you reboot)
5) cp /usr/share/doc/festival/examples/festival.init /etc/init.d/festival
6) chmod +x /etc/init.d/festival
7)  update-rc.d festival defaults
8) nano /etc/default/festival # add the line below inside
10) nano /etc/asterisk/festival.conf # configure asterisk to use festival, make sure that cache directory exists and permission are okay
festivalcommand=(tts_textasterisk "%s" 'file)(quit)\n

11)  /etc/init.d/festival start # start festival
12)  netstat -an |grep 1314 # it must exist with TCP listening on, otherwise, can try starting it manually to see any error # /usr/bin/festival --server --script /etc/festival.scm   this is also good for debugging if the text file is sent to the festival server from asterisk
12) Now, create some dialplans in /etc/asterisk/extensions.conf or anywhere related (like in freepbx would be /etc/asterisk/extension_custom.conf)
exten => gc*cal,1,Answer
exten => gc*cal,n,Set(i=${MATH(${EPOCH}+1576800,int)}) ; 1576800 is about half a year EPOCH
exten => gc*cal,n,NoOp(Math func addon is ${i})
exten => gc*cal,n,Set(id=${CALENDAR_QUERY(myholidays,${EPOCH},${i})})
exten => gc*cal,n,NoOp(Event NoOp ${CALENDAR_QUERY_RESULT(${id},summary)})
exten => gc*cal,n,Set(es=$[${CALENDAR_QUERY_RESULT(${id},summary)}])
exten => gc*cal,n,Set(es=$[${CALENDAR_QUERY_RESULT(${id},summary)}])
exten => gc*cal,n,Festival(Event type is)
exten => gc*cal,n,Festival(${es})
exten => gc*cal,n,Set(epochstart=${CALENDAR_QUERY_RESULT(${id},start)})
exten => gc*cal,n,set(startdate=${STRFTIME(${epochstart},,%A%t %e%t %B%t %G%t)})
exten => gc*cal,n,set(starttime=${STRFTIME(${epochstart},,%H%t %M%t)}) 
exten => gc*cal,n,Festival(start date)
exten => gc*cal,n,Festival(${startdate})
exten => gc*cal,n,Festival(start time)
exten => gc*cal,n,Festival(${starttime} hours)
exten => gc*cal,n,Set(epochend=${CALENDAR_QUERY_RESULT(${id},end)})
exten => gc*cal,n,set(enddate=${STRFTIME(${epochend},,%A%t %e%t %B%t %G%t)})
exten => gc*cal,n,set(endtime=${STRFTIME(${epochend},,%H%t %M%t)}) 
exten => gc*cal,n,Festival(end date)
exten => gc*cal,n,Festival(${enddate})
exten => gc*cal,n,Festival(end time)
exten => gc*cal,n,Festival(${endtime} hours)
exten => gc*cal,n,Hangup

13) Remember to restart asterisk at least once for all these to work, as we are loading the calendar module and dialplans in it.
14) You would need a phone that’s capable to dial letters (or change that dialplan to dial a number instead like exten => 1000
15) Dial from your phone gc*cal

Saturday, December 11, 2010

Google Voice on Asterisk 1.8 bug is now fixed!

When Asterisk 1.8 was released, it had a perfect integration with Google Voice @voice.google.com service. Sometime in the 4th week of November, this broke and Gtalk worked (calling other google accounts) but calling Google Voice (e.g calling to US numbers for Free), didn’t.
I just saw this fixed in Digium’s bug tracker here
Here’s how i got my current working Asterisk to apply the patch. I am sure there are more “polished” ways but this just worked for me
1) Go to your Asterisk source directory, mine is #cd /usr/src/asterisk-1.8.0
2) Go to the channels directory #cd channels
3) Backup the original chan_gtalk.c to somewhere # mv chan_gtalk.c /usr/src/somebackup
4) Get the patch # wget http://svnview.digium.com/svn/asterisk/trunk/channels/chan_gtalk.c?revision=297958&pathrev=297958
5) Rename it #mv chan_gtalk.c\?revision\=297958 chan_gtalk.c
6) Go back to asterisk source main directory #cd ..
7) # ./configure
8) make && make install
9) Stop and restart asterisk # asterisk –rx “core stop now”
And voila! Google Voice worked again, just dialed a friend in US for free <joy>, my dialplan had exten => _1. I dial straight from my Deskphone!
Perfect! now lets enjoy our weekend,
PS> If you want some (flexible) dialplans, here an article that can help you. Go to http://highsecurity.blogspot.com/2010/11/googlevoice-asterisk-18-with-freepbx.html

Tuesday, December 7, 2010

Asterisk Script for Recordings to Move or Copy -n- number of days old (an archiving tool if you may)

Here’s' a script that moves or copies certain files (in my case Asterisk recordings) of anything above a certain date (as defined in the CLI) to a destination you pick.
You must first define the sourcepath, sourcefilename, destination and an option to flag move or just copy.
Place it anywhere and execute ./archivefiles 10
-> which means move/copy files that are over 10 days old from date to a desired location.
You could of course run it in cron if you like on a regular basis. Say you run ./
Here’s the script. Copy from the start till the end.
1) nano /usr/bin/archivefiles # create it
2) paste start –> end of script below # copy the script
3) chmod +x /usr/bin/archivefiles # make it executable
NOTE: Make sure your date/time in server is consistent/correct.
# sanjay@astiostech.com
# usage #archivefiles 10 (meaning archivefiles will find files older than 10 days to do a move or copy)
SOURCEPATH=/var/spool/asterisk/monitor/                                 # With trailing / (slash )
SOURCEFILENAME=*.wav                                                 # filetype
DEST=/usr/src/mytestdst/                                                 # With trailing / (slash )
MOVE=0                                                                # NOTE:0 - copy, 1 - move
if [[ $OLDERTHAN = "" ]]; then
        echo "Define a period. Like 10 for 10 days"
    exit 1
        echo ""
if [ $OLDERTHAN ]; then
    if [ ! $(echo "$OLDERTHAN" | grep -E "^[0-9]+$") ]; then
        echo $OLDERTHAN is not a valid integer.
        exit 1
    if ! [ $OLDERTHAN -ge 0 ] || ! [ $OLDERTHAN -le 10000 ]; then
        echo $OLDERTHAN is an invalid value. Range is [1-10000]
        exit 1
if [[ -d $SOURCEPATH ]]; then
        echo "OK - Source directory exits"
        cd $SOURCEPATH
        echo "Source Directory not found, check your settings... quitting"
        exit 1
grabfiles=`ls -l  $SOURCEPATH$SOURCEFILENAME | head -n 1 | grep -c "\-r"`
if [[ $grabfiles != "0" ]]; then
        echo "OK - Source files exist"
        echo "Oops, no source files, check your settings...quitting"
        exit 1
if [ -d $DEST ]; then
    echo "OK - Destination directory exits"
    echo "Destination directory not found, check your settings... quitting"
    exit 1
if [[ $MOVE = "1"  ]];then
    find  $SOURCEPATH$SOURCEFILENAME -mtime +$OLDERTHAN -exec mv -f {} $DEST \;
    find  $SOURCEPATH$SOURCEFILENAME -mtime +$OLDERTHAN -exec cp -fpr {} $DEST \;

Tuesday, November 30, 2010

FreePBX slow “Apply Configuration”

Some may have problems loading FreePBX that takes a few minutes esp with larger number of extensions.
This is actually addressed in this article in FreePBX.org http://www.freepbx.org/trac/ticket/4435 but if you just want to fix it and don’t read all the stories there, read on.
NOTE: This article is ala-debian, so please do your due diligence for non-debians.
Make sure you do all updates of modules to the latest minor version (upgrade all) before doing this below In future when you upgrade the CORE and FRAMEWORK, this below patch will be overwritten, so you need to do this again.
For clusters setups, please note if you already replicate certain directories of Asterisk/WWW, this may only needed to be done on the Master (or active) node.
Here’s the step by step:
Patch php-asmanager.php
cd /var/www/html/admin/common/
cp php-asmanager.php ./php-asmanager.php-original
patch php-asmanager.php astdb_cache.diff
chown asterisk:asterisk php-asmanager.php
Patch retrieve_conf
cd /var/lib/asterisk/bin
cp retrieve_conf ./retrieve_conf-original
patch retrieve_conf retrieve_conf.diff
chown asterisk:asterisk retrieve_conf
cp /etc/php5/apache2/php.ini /etc/php5/apache2/php.ini-orig
sed -i "s/upload_max_filesize = 20M/upload_max_filesize = 120M/" /etc/php5/apache2/php.ini
sed -i "s/upload_max_filesize = 2M/upload_max_filesize = 120M/" /etc/php5/apache2/php.ini
sed -i "s/magic_quotes_gpc = On/magic_quotes_gpc = Off/" /etc/php5/apache2/php.ini
sed -i "s/memory_limit = 16M/memory_limit = 100M/" /etc/php5/apache2/php.ini
sed -i "s/memory_limit = 32M/memory_limit = 100M/" /etc/php5/apache2/php.ini
RESTART apache.
/etc/init.d/apache2 restart
Now, try modifying something and do your apply.

Sunday, November 28, 2010

Asterisk 1.8 Google Talk Inbound Caller ID (CallerID)

If you need to send the proper calling party’s caller ID to a phone when using GoogleTalk, follow the below dialplan. Without any setting, the caller number is set to UNKNOWN and only the CALLERID(name) field is sent with something like sanjayws@gmail.com/Talk.v10471914EB6E. So we tweak the dialplan to show the correct caller ID. Put this dialplan anywhere in your Google incoming dialplan and you should see the calling party just nicely.

exten => stunningsimplicity@gmail.com,n,Set(Thiscallchan=${CALLERID(name)})

exten => stunningsimplicity@gmail.com,n,Set(CALLERID(name)=${CUT(Thiscallchan,/,1)})

exten => stunningsimplicity@gmail.com,n,Set(CALLERID(num)=${CUT(CALLERID(name),@,1)})

Here’s what you will see


**Assuming here, that your diaplan starts with the email address like in a post i did previously below, otherwise, change that accordingly, or change stunningsimplicity to any incoming GoogleVoice email that is expected to land on asterisk.

We remove @gmail.com as it will not quite work with your phones as it will try to do a SIP/IAX @ gmail call.

It’s best to prefix some characters for gmail outbound calling, and in my sample configuration below, i do a g* followed by a google name to dial as we add @gmail in our outbound dialplan. So you can add for incoming a g* automatically like below

exten => stunningsimplicity@gmail.com,n,Set(CALLERID(num)=g*${CUT(CALLERID(name),@,1)})

And so because we add a g* the CallerID(num) field will change to g*sanjayws (where sanjayws is the calling party from an original string received like sanjayws@gmail.com/Talk.v10471914EB6E). Now a person receiving the call can simply redial.

Saturday, November 27, 2010

Google Voice Talk on Asterisk 1.8 (with FreePBX) and a flexible dialplan

Google Voice Talk on Asterisk 1.8 (with FreePBX) and a flexible dialplan [Updated 12-04-2012]
Ok so you’ve got a 1.4 or 1.6 Asterisk with FreePBX running somewhere? Now you wish to use GoogleVoice/Talk with Asterisk 1.8. Here’s how.
This guide is more for a Debian system, so if you are running other than, do a little google.
Firstly, get your FreePBX updated to v2.8, other versions apparently won’t support Asterisk 1.8.
After that, start the Asterisk upgrade process. (from Mikael Carlsson, FreePBX Development Team @ this article) and the necessary dependencies for Asterisk’s chan_gtalk and chan_jabber
  • cd /usr/src
  • wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz
  • tar -zxvf iksemel-1.4.tar.gz
  • cd iksemel-1.4
  • ./configure
  • make && make all && make install
  • wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-1.8-current.tar.gz
  • tar xvfz asterisk-1.8-current.tar.gz
  • cd asterisk-1.8.0
  • contrib/scripts/get_mp3_source.sh
  • ./configure
  • make menuconfig
  • Goto Add-ons and select –> app_mysqp, app_saycountpl, cdr_mysql, format_mp3, res_config_mysql
  • Goto Extra-Sound-Packages and Select –> EXTRA-SOUNDS-<Yourlanguage>-GSM
  • Goto Channel Drivers and ensure that > chan_gtalk and chan_jingle are selected
  • Save and exit
  • ./configure
  • make && make install
  • amportal stop
  • amportal start
You’ve done your 1.8 setup which is ready for google voice/talk
Now, here are some configuration files you can simply copy paste in /etc/asterisk/. You can follow exactly the same as i have to make things work first.
Edit /etc/asterisk/gtalk.conf, paste the following, modify accordingly. Note, for newer versions of FreePBX, it supports inbound routes with names (typically it would be numbers). So you can actually send the call to for example from-pstn or from-dahdi or from-trunnk, then you can add this "inbound route to route to a specific extension” as you would do with a normal DID for instance.
context=google-incoming ;;##use from-trunk if using newer FBX 2.8 or higher
context=google-incoming ;;##use from-trunk if using newer FBX 2.8 or higher

Save and exit.
Now, edit, /etc/asterisk/jabber.conf, paste the following, modify accordingly



And finally, edit your custom dialplan e.g. /etc/asterisk/extensions_custom.conf, paste the following, modify accordingly. Yo u only do this below if you are not using FreePBX latest version 2.8 or higher. For FreePBX 2.8 or higher, see below this dialplan.
include => google-outgoing

;this for internal gmail user highsecurity@gmail.com, ring her 1001 extension
exten => highsecurity@gmail.com,1,Macro(user-callerid,)
exten => highsecurity@gmail.com,n,Answer()
exten => highsecurity@gmail.com,n,Wait(2)
exten => highsecurity@gmail.com,n,Set(Thiscallchan=${CALLERID(name)})
exten => highsecurity@gmail.com,n,Set(CALLERID(name)=${CUT(Thiscallchan,/,1)})
exten => highsecurity@gmail.com,n,Set(CALLERID(num)=g*${CUT(CALLERID(name),@,1)})
exten => highsecurity@gmail.com,n,SendDTMF(1)
exten => highsecurity@gmail.com,n,Goto(from-internal,1001,1) or ,n,DIAL(SIP/1001)
; end gmail user highsecurity@gmail.com

;this for internal gmail user stunningsimplicity@gmail.com, ring her 1002 extension
exten => stunningsimplicity@gmail.com,1,Answer()
exten => stunningsimplicity@gmail.com,n,Wait(2)
exten => stunningsimplicity@gmail.com,n,Set(Thiscallchan=${CALLERID(name)})
exten => stunningsimplicity@gmail.com,n,Set(CALLERID(name)=${CUT(Thiscallchan,/,1)})
exten => stunningsimplicity@gmail.com,n,Set(CALLERID(num)=g*${CUT(CALLERID(name),@,1)})
exten => stunningsimplicity@gmail.com,n,SendDTMF(1)
exten => stunningsimplicity@gmail.com,n,Goto(from-internal,1002,1) # or ,n,DIAL(SIP/1002)
; end gmail user stunningsimplicity@gmail.com

; Set the outgoing account per jabber.conf
exten => _g*.,1,Macro(user-callerid,SKIPTTL)
; Add more users here
exten => _g*.,n,ExecIf($["${AMPUSER}" = "1001"]?Set(gmailoutaccount=sanjay-ac1))
exten => _g*.,n,ExecIf($["${AMPUSER}" = "1002"]?Set(gmailoutaccount=sanjay-ac2))
; Normal outbound calling, g is prefixed so it will call google talk,
; and call other places using google voice, like below, a US number
exten => _g*.,n,Dial(gtalk/${gmailoutaccount}/${EXTEN:2}@gmail.com)
exten => _1XXXXXXXXXX,n,Dial(gtalk/${gmailoutaccount}/${EXTEN}@voice.google.com)
; Dialplan for sending messages
exten => _t*.,1,Macro(user-callerid,SKIPTTL)
exten => _t*.,n,ExecIf($["${AMPUSER}" = "1001"]?Set(gmailoutaccount=sanjay-ac1))
exten => _t*.,n,ExecIf($["${AMPUSER}" = "1002"]?Set(gmailoutaccount=sanjay-ac2))
exten => _t*.,n,JABBERSend(${gmailoutaccount},sanjayws@gmail.com,"${EXTEN:2}")
exten => h,1,(Hangup)

At this point be sure to stop and start Asterisk (amportal kill / amportal start). Infact most settings made on gtalk.conf needs to restart Asterisk, not just reload.
With FreePBX 
When using FreePBX 2.8 or higher, you don’t need to write manual dialplans for INBOUND (incoming) calls. You only need to customize the dialplan if you are planning to make outbound calls on Gtalk through Asterisk. Here below is a sample inbound route created in FreePBX.
Remember, this is for INCOMING only that will be handled by FreePBX, here any calls destined to highsecurity@gmail.com I will attempt to send to an extension (or anywhere as you please). As you can see below, if I set the context to from-trunk, I will see it like below in my cli
Notice the DID value there is highsecurity@gmail.com which mean, it is as simple as adding an Inbound Route in FreePBX like below;
Extra information manual dialplan creation
1) You must specify incoming and outgoing google accounts.
2) Incoming connections will dial internal extensions or just about anywhere you have designed in FreePBX, in this case, they are extensions.
3) Outgoing calls are matched based on the extension that is dialling (supports user/device mode as well) so that if extension 1001 is dialing out, the recipient will see highsecurity calling and if extension 1002 dialling, he/she will see stunningsimplicity
4) Anyone without that specific dialplan set for outbound can be limited to a failurecode (not defined in this sample here).
5) If someone wants to dial out, he/she dial g*<user> like for example gs*anjayws will dial the gmail user sanjayws. The g* is used as a prefix for dialling out so it is a clear path to dial google.  To make redials easier, when an incoming call comes through the dialplan, we’ve added the g* at the begining of the callerID(name) field so that when a person redials, it will engage the outbound route. Notice that we do a CUT in there and that is to remove certain characters through a delimiter character.
6) Of course, you can also specify calling to other google voice numbers if you have google voice credits to those outgoing accounts created in jabber.conf. This example above, does US calls as it is free for now. Feel free to add any other calling matches to use google voice.
Do send your feedback to sanjay@astiostech.com
Thank you.

Thursday, November 25, 2010

Fail2ban Manual Unban Single Host (for iptables)

UPDATE: Starting with version 0.8.8, the unban operations are now built-in, it is executed through the fail2ban-client app like this

# fail2ban-client set [ban-name] unbanip [ip]
# e.g. fail2ban-client set asterisk-iptables unbanip 8.8.8.

Check out the changelog here. Get version 0.8.8 here.  You really should be upgrading your fail2ban to that above version and use the built-in tool.




Fail2Ban is a great way to protect your server from malicious attempts of brute force and other events that are deemed a problem. It does by very smartly checking your logs and if a particular event is repeated n number of times, you can set actions such as blocking or unblocking using software such as iptables based or software based firewalls or even write scripts to modify an external firewall.

There’s one drawback about it and that is the ability to unban just one IP (many reasons why that might be needed). Just follow these instructions and get the necessary script and you will have an idea or a fully working unban function (if you use iptables to ban)
Version that you MUST USE: Fail2Ban v0.8.4. Download and install Fail2Ban version 0.8.4, for Asterisk fail2banning for SIP brute force attack. Some help with installation

This guide was designed on a Debian system. Customization may be required. You can check the version after installing via cli like below
# fail2ban-client –V

Create the unban script, you may need to modify certain settings that would then match your jail setting, actions (in this script its for iptables) and logging options.
# cd /usr/src
# wget
# chmod +x unban

Now, we change or manipulate the actions.py file from Fail2ban for proper handling of unban script unbanning. You may need to modify this if it is not IPtables you use for banning action. See the section def __checkBan in actions.py there’s a modification of an external check command there called mycheck. If mycheck condition is true (returned value 0) it will proceed to ban that IP. The issue we had by just unbaning using the unban script was that fail2ban didn’t know we unban manually using cli. This caused fail2ban to never ban again the IP you just banned because it think that IP is still in its ban list. This “fix” ensures that the process/procedure will check against iptables (or any of your ban action) and reissue a ban if it doesn’t have the IP in its entry (like doing a iptables –n –-list)

# cd /usr/share/fail2ban/server/
# mv actions.py actions.py.original
# wget

# /etc/init.d/fail2ban restart

Try it out for yourself to unban some IP
# unban

If you do not specify an IP, it will list all banned IPs inside the Jailed context.

Sunday, October 17, 2010

Yealink IP Phone corporate directory integrated into FreePBX

Newer firmware of Yealink IP phones allows you to perform searches within the “Remote Directory” setup screen. Instead of just having a static file, users can search just about any parts of the name field and voila, the results are shown on the display.
Here, we take this functionality and add it to the FreePBX directory meaning, it is truly realtime to the adding and removal of users in FreePBX as it uses the asterisk.users directory in FreePBX MySQL table.
Test on:
1) FreePBX 2.x
2) Debian 5
3) Asterisk 1.6 (versions of Asterisk doesn’t really matter)
NOTE: If the codes appear truncated, simply copy the whole table and paste into a text editor
  • Wildcard searching capability using backend PHP engine
  • Searches directly from FreePBX no need to maintain separate DB/files, thus making it dynamic
  • Some security tips plus Database access is limited with very low privileges for the user that connects to FreePBX / MySQL
  • May work for just about any type of phones that support the search function
Security Notice
Do not allow this file to be exposed in the public domain it can disclose your corporate directory and users/people

- Enforce ACL on this website/page so that only internal users can enumerate
- Try to use a complex name for the php file so that it’s difficult for someone to guess it.
Tested on Debian5, FreePBX2.8, Asterisk1.6, MySQL5,Apache2 (PHP5)
1) You have a running apache server which support PHP5 and does not force SSL.
2) Apache runs as asterisk in group asterisk
3) There's no other service listening on port 80
4) Use freepbx asterisk database with users table found (default)
5) Using IP as example web server
6) Newer Yealink firmware allows searching functionality, get that to use with this function
We will use a very low privileged user for this requests.
Create DB user with very low privileges (change the username and password accordingly to connect to your MySQL box, here, its a local box). This below is give access to the database asterisk, table user and column name.
mysql -h localhost -u root -ppassword  mysql --execute="GRANT SELECT (name) ON asterisk.users TO directory@localhost IDENTIFIED BY ‘p@ssword1';"

mysql -h localhost -u root -ppassword  mysql --execute="GRANT SELECT (extension) ON asterisk.users TO directory@localhost IDENTIFIED BY 'p@ssword1';"

Create PHP to XML transformation file that will retrieve info directly from FreePBX's user table in the database asterisk (created by FreePBX)

SECURITY TIP: Use an odd name only you would know. Common names can be guessed and then information enumerated.
nano /var/www/directory/search.php
Paste into file, read the file headers and change where appropriate.
// with credit to JOYCE CR, s.r.o. http://www.joyce.cz/produkt-soubory/searching_remote_phonebook_manual.pdf
// Make sure you configure the allowable settings only
// This script directly integrates with FreePBX and picksup the asterisk.users table
// Should work for both device-user mode or extensions mode
// Works by searching from anywhere of the person's name
// feedback to sanjay@astiostech.com
// Change here to match the webaddress absolute path
$URL = '';
// Choose how many results to return if search term produces a lot of output
$per_page = '10';
// Change here to match your own passwords
$mysql_conn = mysql_connect('localhost', 'directory', 'p@ssword1');
// Dont change anything from here unless you know what you are doing
mysql_select_db('asterisk', $mysql_conn );
if ( ($FROM=='') and ($TO=='') )
   //check to see how many
   $result= mysql_query("SELECT count(users.name) as total
                         FROM users
                         WHERE users.name LIKE '%$NAME%' ", $mysql_conn);
   $howmany = mysql_fetch_row($result);
   if ($howmany[0] > $per_page)
    $start = 0;
    $index = 0;
    $total = $howmany[0];
    $remain = $per_page;
    while ($start < ($total + 1))
      $limitstart = 'LIMIT '.$start.','.$per_page;
      $result = mysql_query("SELECT name,extension
                             FROM users
                             WHERE name LIKE '%$NAME%' ORDER BY name $limitstart", $mysql_conn);
      $row = mysql_fetch_row($result);
      $from = $row[0];
      if (($total - $start) < $per_page) { $remain = $total - $start; }
      for ($i = 1; $i < $remain; ++$i) { $row = mysql_fetch_row($result); }
      $to = $row[0];
      $start = $start + $per_page;
      $index = $index+1;
   } else {
    $result = mysql_query("SELECT name,extension,extension
                           FROM users
                           WHERE users.name LIKE '%$NAME%'
                           ORDER BY name ", $mysql_conn);
    while($row = mysql_fetch_row($result))
      print($row[0]."- ".$row[1] );
} else {
  $result = mysql_query("SELECT name,extension,extension
                         FROM users
                         WHERE name>='$FROM' AND name<='$TO'
                         ORDER BY name", $mysql_conn);
   while($row = mysql_fetch_row($result))
     print($row[0]."- ".$row[1] );
Save and close. Give proper permissions to the file
chown asterisk:asterisk /var/www/directory/search.php
Try on browser, assuming a user Sanjay is being searched for, you can also use ja, nj, as long as it's within the correct sequence
An output should look something like this:
Sanjay WS- 1000 1000
Now, on your Yealink:
Go to yealink admin page | Contacts | Remote Phone Book
Name this entry like “Corporate Directory” and what not.
Now, save, hit Dir, scrolls to the newly created “Corporate Directory” and a search function should show up. IF you search, enter the relevent text or if you don’t it will enumerate all list of directory entries limited by the number of pages specified in the php script above.
Do test it out and let us know.

Asterisk + FreePBX - Removing queue members with logout *12

Some organizations probably need this, so we thought of sharing.
The requirements form one of client is to “auto” logout someone from an Asterisk/FreePBX queue module when he/she logout from the user/device mode.
This script uses AGI. I have tested this on;
1) Debian 5
2) FreePBX 2.8 and below
3) Asterisk 1.6 (may work for 1.4- need to probably tweak the script)
NOTE: If the codes appear truncated, simply copy the whole table and paste into a text editor
Firstly, we use the override function in FreePBX to override the macro-user-logoff directive
nano /etc/asterisk/extensions_override_freepbx.conf
Enter the following code;
; check device type
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)})
exten => s,n,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1)
exten => s,n,Set(dev=${DB(DEVICE/${CALLERID(num)}/user})
exten => s,n,AGI(kick.sh,${dev})
exten => s,n,AGI(user_login_out.agi,logout,${CALLERID(number)})
exten => s,n(done),Playback(vm-goodbye)
exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged out of)
exten => s-FIXED,n,Playback(an-error-has-occured&vm-goodbye)
exten => s-FIXED,n,Hangup
The two items highlighted in bold are basically the ones we add to an existing macro-user-logoff function in FreePBX
Now, create the AGI / bash script that will do the trick
nano /var/lib/asterisk/agi-bin/kick.sh
Paste the following code in the editor, MAKE SURE YOU MODIFY YOUR QUEUE NUMBERS show in “queuenumbers”
# script by Sanjay Willie
# v0.1-beta
# tested on Asterisk 1.6/FreePBX 2.8/Debian 5.06
# maintainer: sanjay@astiostech.com
# the directory /tmp should exist and can be accessible by user asterisk and group asterisk
# NOTE: FILES IN /tmp normally gets flushed on restarts
# On grabbing agent number, should look exactly like "Local/1000@from-queue" eventually and should not contain any preceding or trailing characters
# the extraction of agents in the script in the line "for agents..." may or not yield output, so test it out.
# The sed part is to remove brackets from the output in the front and back (seen in FBX 2.8)
# if the sed isn't required (like in FreePBX 2.7 and below) you can remove it, also lookout for the print $3, in FreePBX 2.7 and below its print $1, so test it out first
datenano=`date +%N-%F`
regulardate=`date +%F-%T`
queuenumbers="4001 4002 4003 5001 5002 5003 4021 4022 4023 5021 5022 5023"
while [ "$stdin" != "" ]
                read stdin
                if [ "$stdin" != EOF ]
                        echo $stdin | grep agi_arg_1 | awk {'print $2'} >> $gennum
include=`cat $gennum`
cleanup=`rm -v /tmp/$gennum`
#echo $cleanup >> /tmp/cleanup
if [[ "$include" == "" ]] ; then
        echo Nothing to do, quitting
for queue in $queuenumbers; do
        #echo $queue >> /tmp/logfile.txt
        # see NOTES above
        #for agents in `asterisk -rx "queue show $queue" | grep from-queue | awk '{print $3}' | grep -w "$include" | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`; do # freePBX 2.8 or higher
        for agents in `asterisk -rx "queue show $queue" | grep from-queue | awk '{print $1}' | grep -w "$include"`; do
                #echo $agents >> /tmp/logfile.txt
                asterisk -rx "queue remove member $agents from $queue"
                echo "we remove $agents in $queue"
                echo $regulardate - Attempt removing agent $agents from queue $queue >> /tmp/agentremover.log
exit 0
This code does this;
1) Once the Asterisk dial plan calls the script, it will parse the user into bash and we will remove that user with a script that walks through all queues you have specified looking for this user and does a removal using asterisk –rx
2) Stores a simple log in /tmp
Make it executable, chmod +x /var/lib/asterisk/agi-bin/kick.sh and make sure the asterisk user can read/run the file, chown asterisk:asterisk /var/lib/asterisk/agi-bin/kick.sh
Reload the dialplan
asterisk -rx "dialplan reload"
Go ahead and test it…
Let us know if this worked out. For help, write to sanjay@astiostech.com

Friday, July 2, 2010

Checking Windows Clusters / Cluster Resources Using Existing Check Plugins for Nagios

Now we all know when it comes to clustering its basically one up and the other down. So monitoring, say Exchange or SQL on the live or active one is just fine with all the disk checked and all the services are UP (while set to manual). Problem is when it comes to the passive server, how do we check for just about anything?

Simple. Try using this custom script i’ve written.

Here’s the script snippet.




# Debug
# hostname=
# servicename="SQL Server (YOG)"

# We check if the quorum is running or not first
# assuming quorum is on Q drive

getoutput=`/usr/local/nagios/libexec/check_nrpe -H $hostname  -t 50 -c CheckDriveSize -a ShowAll=long MinWarnFree=10% MinCritFree=5% Drive=q: | grep -c "The system cannot find the path specified"`

# echo $getoutput

if [[ "$getoutput" == "1" ]]; then

    echo "OK: Clustered service is not failed over. We will not check this service now."
    exit 0


    /usr/local/nagios/libexec/check_nrpe -H $hostname -t 50 -c checkServiceState -a ShowAll "$servicename"


The idea of this script is to:

1) Check certain resources on the Cluster only if the quorum is alive!

2) If it’s not, send an OK value back to Nagios but in the comment section, mention that “its not failed over” or something.

3) Send fake performance data not to break the Performance Data values.

This value,

getoutput=`/usr/local/nagios/libexec/check_nrpe -H $hostname  -t 50 -c CheckDriveSize -a ShowAll=long MinWarnFree=10% MinCritFree=5% Drive=q: | grep -c "The system cannot find the path specified"`

This above checks if the quorum is alive. It is normally the first resource that will fail over. In our case it was drive q!. So, when we are satisfied that the output of the plugin isn’t “…cannot find path”…only then we execute just about any plugin. And in this example above, check the services that are cluster monitored/managed.

Now, to execute the script on commands.cfg, is something like this.

# Check Clustered Services:
# ---------------------------------------------------------------------

define command{
        command_name    check_floating_services
        command_line    $USER1$/check_floating_services $HOSTADDRESS$ $ARG1$


On command line, you can simple parse

./check_floating_services <hostname/ip> <servicename>

And there you have it, cluster “enable” plugins.


Tuesday, May 25, 2010

Nagios + PNP graphs PDF reports generator and emailer

We made a small script that we use in our customer’s site to basically pull out the PNP generated graphs through the Nagios Action Items icon. This script will basically download the current report output into PDF and emails them out based on the configuration found on the script header.
  • This script does a simple task of creating PDF files via PNP url and emails it out
  • This script must be executed as root
  • This script may contain sensitive information such as usernames and passwords, so ensure only root has access to it
  • The script works with the extra-option URL only to generate PDF graphs or MRTG, typically /pnp/index.php
  • Make the script executable, i.e. chmod +x pnp_emailer.sh
The solution requires Cleancode’s CLI based email client. All instructions to install and get it up and running is available in the script’s header.
It has basic options currently but you may extend the use of it to just about anything else you wish for it to do.
Eventually, run lines of the scripts as a cron job executed on a timely manner to generate in time reports.
The script is then executed with options at CLI that includes the servername and servicename as defined in the Nagios .CFG files.
Here’s the script. And as usual, your feedback is mucho appreciated.
With best,
Sanjay & all Astiostechers!

Wednesday, April 14, 2010

free SIP phone for Windows mobile

We like and use the PortSIP SDK for our softphone development (yes Astiostech’s coming up with one real soon). I downloaded and tried their softphone for Windows, softphone for Windows Mobile version 5 and 6 and i found it absolutely touch (like HTC touchscreens) and look quite similar to HTC’s Manila/Touch interface dialpads etc.

I highly recommend you to use this, sounds great on the earpiece, just like using a normal phone, has buttons to enable speakermode etc...
Works great on WiFi or GSM (3G). Do note, with GSM/EDGE there’s some latency, naturally. So, whenever possible, use 3G/HSDPA
Download here: http://www.portsip.com/downloads.htm