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