giovedì 26 giugno 2014

The simplest Click2Dial implementation EVER

Here's a really lightweight implementation of the Click to Dial feature for softphones, brought you by the flexibility of Asterisk and Linux shell scripting.

Prerequisites:

- Apache and Sudo are installed
- All Iax and Sip peers defined in iax.conf and sip.conf do require to qualify with the QUALIFY=X directive.
- The pbx_spool.so module is loaded (it is required to use Asterisk call files)

Here's the procedure:

nano /etc/sudoers

comment out this line:

Default requiretty

and append this line:

apache ALL=(ALL) NOPASSWD: ALL

at the end of file (THIS IS INSECURE!!!).


# nano /var/www/cgi-bin/index.cgi (NO CUSTOMIZATION NEEDED!)

#!/bin/bash
echo Content-type: text/html
echo ""
echo "<html><head><title>Click2Call</title></head><body>"


rm -rf /tmp/peers
sudo asterisk -rx 'iax2 show peers' | grep 'ms)' | awk  -F' ' 'BEGIN{OFS=FS;} {print $1,$2;}' | awk -F"/" '{print "iax2",$2;}' >>/tmp/peers
sudo asterisk -rx 'sip show peers' | grep 'ms)' | awk  -F' ' 'BEGIN{OFS=FS;} {print $1,$2;}' | awk -F"/" '{print "sip",$2;}' >>/tmp/peers


a=`sudo asterisk -rx 'iax2 show peers' | grep 'ms)' | awk -F "/" '{printf $1"\n";}'`
for dummy in $a
do
   echo "<a href="http://n.n.n.n/cgi-bin/call.sh?iax2/$dummy">$dummy</a href><br>"
done


a=`sudo asterisk -rx 'sip show peers' | grep 'ms)' | awk -F "/" '{printf $1"\n";}'`
for dummy in $a
do
   echo "<a href="http://n.n.n.n/cgi-bin/call.sh?sip/$dummy">$dummy</a href><br>"
done


# chmod +x /var/www/cgi-bin/index.cgi

# nano /var/www/cgi-bin/call.sh (NO CUSTOMIZATION NEEDED!)


#!/bin/bash
echo "Content-type: text/plain"
echo ""
echo "executed";


caller=`cat /tmp/peers | grep -w $REMOTE_ADDR | cut -d' ' -f2`
tech=`cat /tmp/peers | grep -w $REMOTE_ADDR | cut -d' ' -f1`


echo "Channel: $tech/$caller" >/tmp/do.call
echo "Application: Dial" >>/tmp/do.call
echo "Data: $1" >>/tmp/do.call
sudo cp /tmp/do.call /var/spool/asterisk/outgoing

# chmod +x /var/www/cgi-bin/call.sh

# sed -i 's/n.n.n.n/[YOUR_SERVER_IP]/' /var/www/cgi-bin/index.cgi


That's all. You can now navigate to this page:


http://[YOUR_SERVER_IP]/cgi-bin/index.cgi


And CLICK TO DIAL any sip or iax user currently registered to your machine. Your softphone will ring: answer the call and get automatically connected to the requested user!



mercoledì 11 giugno 2014

Dynamically update externip without Dyndns.org or similar

About a month ago, Dyndns.org shut down his free dynamic dns service, disrupting service to hundreds of thousands of home server installations, shame on them!

Many Asterisk setups relied on this to overcome nat problems with dynamically assigned WAN ips (using the externhost=xyz.dyndns.org directive)

Here's a tiny shell script to automatically update your externip directive from sip.conf reflecting your actual WAN ip address:

# nano /root/spinach.sh

#!/bin/bash
doreload=0
wanip=`curl -q tnx.nl/ip`
if [ -f /tmp/oldip.txt ]; then
   oldip=`cat /tmp/oldip.txt`
   [ "$wanip" != "$oldip" ] && doreload=1
else
   doreload=1
fi
echo $wanip > /tmp/oldip.txt
if [ $doreload -eq 1 ]; then
      sed -i 's/externip=.*/externip='"$wanip"'/' /etc/asterisk/sip.conf
      asterisk -rx 'sip reload'
fi

# crontab -e

* * * * * /root/./spinach.sh

From now on, your sip.conf externip=* directive will be checked every minute.

Note: reloading Sip should not drop any outgoing or incoming call!

martedì 7 gennaio 2014

Automate IAX peers provisioning via email

In this post I share the code behind a simple idea: provision IAX peers and extensions by sending an email to the Asterisk server! This works only in the private 192.168.1.0/24 lan.

From the user perspective, the procedure is very simple:
1) send an email to provision@192.168.1.201 with your desired IAX username as the subject.
2) receive back your credentials and extension.

For a real linux-savvy sysadmin this should be business as usual! :)
1) install Postfix on the same machine where Asterisk is running
2) customize Postfix to trigger a linux script when an email is received by editing MASTER.CF:

under this line
smtp      inet  n       -       n       -       -       smtpd

add this:
   -o content_filter=myhook:dummy

and this at the end of the file:
myhook unix - n n - - pipe
  flags=F user=puppet argv=/usr/bin/sudo bash /root/processmail.sh ${sender} ${size} ${recipient}

Puppet is a standard unpriviledged user added with the USERADD command. You need this because Postfix won't allow you to run a script with root priviledges. To overcome this limit security feature we use sudo, properly configured by adding this line in the sudoers file:
puppet ALL=(ALL) NOPASSWD: ALL

3) At the end of your extensions.conf you should manually add this context and the 6300 dummy extension:

[isolated]
exten => 6300,1,Playback(vm-goodbye)

4) Processmail.sh is the script located on the /root directory that will do the magic:

#!/bin/bash
rm -rf /root/mail.dump
while read LINE; do
   echo ${LINE} >> /root/mail.dump
done

subject=`cat /root/mail.dump | grep Subject | cut -d' ' -f2 | tr A-Z a-z`
sender=`cat /root/mail.dump | grep -m 1 From | cut -d' ' -f2`
pword=`</dev/urandom tr -dc '0123456789qwertyuiopasdfghjklzxcvbnm' | head -c8; echo ""`

if grep -q $subject /etc/asterisk/iax.conf; then echo "registration failed" | mail -S from=provision@192.168.1.201 -s "ERROR - DUPLICATE USERNAME" $sender; exit 0; fi
if echo $subject | grep -q "[^0-9a-z]"; then echo -e "registration failed" | mail -S from=provision@192.168.1.201 -s "ERROR - INVALID CHARACHTER IN USERNAME" $sender; exit 0; fi 
echo "" >>/etc/asterisk/iax.conf
echo ";`date` $sender" >>/etc/asterisk/iax.conf
echo "[$subject]" >>/etc/asterisk/iax.conf
echo "callerid=$subject" >>/etc/asterisk/iax.conf
echo "username=$subject" >>/etc/asterisk/iax.conf
echo "secret=$pword" >>/etc/asterisk/iax.conf
echo "type=friend" >>/etc/asterisk/iax.conf
echo "host=dynamic" >>/etc/asterisk/iax.conf
echo "context=isolated" >>/etc/asterisk/iax.conf
echo "qualify=1000" >>/etc/asterisk/iax.conf

extension=`tail -n1 /etc/asterisk/extensions.conf | awk '{ FS = " "; s +=$3; } END { print (s+1)}'`
echo "exten => $extension,1,Dial(IAX2/$subject,30)" >>/etc/asterisk/extensions.conf 

/usr/sbin/asterisk -rx "iax2 reload"
sleep 1
/usr/sbin/asterisk -rx "dialplan reload"

echo -e "username: $subject\npassword: $pword\nextension: $extension" | mail -S from="provision@192.168.1.201" -s "ACCOUNT SUCCESSFULLY CREATED" $sender
exit 0

Any icoming mail (even to a NON EXISTING USER like "provision") will be dumped in the /root/mail.dump file. The script checks for duplicates usernames or for usernames containing invalid characters.

If everything is ok, the script will add these lines to iax.conf (we assume that the sender's chosen username is "jwalker"):

;Sat Jan  4 05:15:40 CET 2014 j.walker@yourdomain.com
[jwalker]
callerid=jwalker
username=jwalker
secret=somerandomness
type=friend
host=dynamic
context=isolated
qualify=1000

And add the jwalker dial string at the end of extensions.conf:

exten => 6301,1,Dial(IAX2/jwalker,30)

The sender is notified with his randomly generated password and his extension, in this case 6301. The script also reloads the iax stack and the dialplan.
Now the user can configure his softphone with his brand new credentials and call all his colleagues in the [isolated] context!

NOTES: Don't do this in any production machine, build a test environment with Vmware or similar!

venerdì 3 gennaio 2014

NAT: IAX beats SIP 6-0-6-0-6-0

In my opinion the biggest advantage of IAX is the ability to adapt to any network topology. As Mark Spencer states:

IAX's unified signaling and audio paths permit it to transparently navigate NAT's and provide a firewall administrator only a SINGLE port to have to open to permit its use. It requires an IAX client to know absolutely nothing about the network that it is on to operate. More clearly stated, there is NEVER a situation that can be created with a firewall in which IAX cannot complete a call nor be unable to pass audio (except of course if there was insufficient bandwidth).
And regarding bandwidth:

IAX is more efficient on the wire than RTP for any number of calls, any codec. The benefit is anywhere from 2.4k for a single call to approximately tripling the number of calls per megabit for G.729 when measured to the MAC level when running trunk mode.

More info here: http://www.voip-info.org/wiki/view/IAX+versus+SIP

lunedì 23 dicembre 2013

901901, The killer extension

You may want to configure a cool "reboot extension" to your box. This modification to your extensions.conf will do the trick:

exten => 901901,1,Answer
exten => 901901,n,Authenticate(2345)
exten => 901901,n,Playback(vm-goodbye)
exten => 901901,n,System(/sbin/shutdown -r now)
exten => 901901,n,Hangup()

By calling the 901901 extension your system will reboot (password "2345" is required). The Hangup() command makes sense since Asterisk is cleanly dying!

Spaghetti core sounds

Here is how to get your system to speak italian language in exactly 2 minutes:

mkdir it

cd it/

wget http://downloads.asterisk.org/pub/telephony/sounds/asterisk-core-sounds-it-ulaw-current.tar.gz

tar zxvf asterisk-core-sounds-it-ulaw-current.tar.gz

rm -rf asterisk-core-sounds-it-ulaw-current.tar.gz

cd ..

mv it/ /var/lib/asterisk/sounds/

nano /etc/asterisk/asterisk.conf

uncomment:

languageprefix=yes

modify:

defaultlanguage=it

save, exit and

shutdown -r now

1'58''.....1'59''.....DONE!

Built-in call park feature

Add this line to any of your contexts

include => parkedcalls

And reload the dialplan by typing

asterisk -rx "dialplan reload"

Call any extension, say 6001, then transfer the call to extension 700. The system will output the "parking lot" where the call has been parked, say 701. Now any user can pick up the call by calling extension 701.