Thursday, November 13, 2008

Getting SipX and Asterisk to work on the same box

OK, so I'm one of those data guys who know better than to mess with this dreaded stuff called VoIP. But money talks and there is a certain amount of adventure in making this stuff work.

I've had a Trixbox working for about 2 or 3 years now. Big deal, download the iso, install and configure. It's really pretty easy to do with all the HOW-To's out on the web. I've even been talked into installing a 100 extension set up at a church. And to be honest, besides the pain of dealing with Cisco 7961 phones it wasn't too bad. But it wasn't enough to convert me to a phone guy.

But now that same person who talked me into doing the system at the church has persuaded me to do a system at another 2 sites this isn't going away. This time he wants to use SipXecs instead because it is supposed to be a more sip compliant solution with some high availability features. That's all fine and dandy except it seems that SipX doesn't traverse NAT worth a darn. At least not in the current 3.10 version and not __MY__ NAT. When I tried the upcoming 4.0 release well.... I couldn't even get my Polycom phones to register so maybe it's not ready for me. Remember I'm a data guy.

OK. Trixbox has worked fine with my NAT set up at the house. Since SipX doesn't work with my NAT setup I tried routing my calls from SipX through Trixbox out to my ITSP and into the PSTN. It worked! But I think it's a little clunky to have to install 2 machines just to use SipX for a small site. Especially when Trixbox could probably do most of what they want without the hassle of SipX. So the goal was to get Asterisk, not Trixbox, installed on the same machine as SipX without using any virtual machines or anything of the sort. And I can say after 2 days of trial and error I've done it. Here's what I did:

Start off by installing the SipX/CentOS iso from their site. You can use Fedora or Suse if you want but I did this with CentOS and it works for me...

After install, log in as root and run 'yum update' to get any system updates available.

Follow the various how-to's for SipX to get your phones working and the basic system configured. But hold off on setting up your gateway just yet, I'll talk about that after we get Asterisk installed. In the mean time though you should be able to call the voicemail system and play with the auto attendant.

add an alias ip address to the system. I did it the lazy way by copying /etc/sysconfig/network-scripts/ifcfg-eth0 to ifcfg-eth0:1 and then edited the file. Here's what it looked like after I was done

DEVICE=eth0:1
BOOTPROTO=none
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.0.13
NETMASK=255.255.255.0
GATEWAY=172.10.0.1

and my original ifcfg-eth0 file:

DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.0.12
NETMASK=255.255.255.0
GATEWAY=172.10.0.1


Then just restart the network with 'service network restart'

Next install a few packages for compiling asterisk,  'yum install gcc gcc-c++ ncurses-devel'   and whatever dependencies yum finds.

Now download asterisk to your /usr/src directory. I used asterisk-1.6.0.1 as it was the latest at the time.

extract the file and cd into the asterisk-1.6.0.1

I ran './configure'  followed by 'make install'  and 'make samples'

copy contrib/init.d/rc.redhat.asterisk to /etc/init.d/asterisk

then run 'chkconfig --add asterisk'

now asterisk will start automatically for you when you reboot, but first we have to configure it so don't go starting it just yet.

cd  to /etc/asterisk  and create a directory called samples and move ALL the files into it.

Now we can start with a basic config. copy the sip.conf, rtp.conf, modules.conf, features.conf and extensions.conf into /etc/asterisk from the /etc/asterisk/samples directory.

here's what my sip.conf looks like:

;
; SIP Configuration for Asterisk
;

[general]
context=default ; Default context for incoming calls
allowoverlap=no ; Disable overlap dialing support. (Default is yes)
bindaddr=192.168.0.13:5060 ; IP address to bind UDP listen socket to (0.0.0.0 binds to all)
; You can specify port here too, like 123.123.123.123:5080


; Need this for NAT to work correctly. VERY Important!
externip = My External IP
localnet = 192.168.0.0/255.255.255.0


; See qos.tex or Quality of Service section of asterisk.pdf for a description of these parameters.
tos_sip=cs3 ; Sets TOS for SIP packets.
tos_audio=ef ; Sets TOS for RTP audio packets.
cos_sip=3 ; Sets 802.1p priority for SIP packets.
cos_audio=5 ; Sets 802.1p priority for RTP audio packets.

;-----------------------------------------------------------------------------------


; An ITSP connection that requires a register line
;[regitsp]
;host=x.x.x.x
;username=xxxxxxxxx
;secret=xxxxxxxx
;type=peer
;dtmfmode=inband
;disallow=all
;context=from-pstn
;allow=ulaw
;qualify=yes

;register=xxxxx:xxxxx@x.x.x.x

; My ITSP
[itsp]
username=xxxxxxx
type=friend
insecure=invite
host=x.x.x.x
dtmfmode=inband
disallow=all
context=from-pstn
allow=ulaw
canreinvite=no


; SipXecs connection
[sipxecs]
type=peer
insecure=invite
host=192.168.0.12
dtmfmode=inband
disallow=all
context=from-sip
allow=ulaw
canreinvite=no



and my extensions.conf

[general]
autofallthrough=yes


[default]
exten => _X.,1,NoOp(Got Unsolicited SIP Request)
exten => _X.,n,Congestion(5)
exten => _X.,n,Hangup


[from-pstn]
exten => 1234567890,1,Dial(SIP/sipxecs/4250) ; not my real DID
exten => 2345678901,1,Dial(SIP/4260@sipxecs) ; not my real DID
exten => 3456789012,1,Dial(SIP/4260@sipxecs) ; not my real DID


[from-sip]
exten => _X.,1,Dial(SIP/itsp/${EXTEN})



and in modules.conf I added this stuff to the bottom to cut down on all the modules that got loaded, you could probably skip this if you wanted to

noload => chan_iax2.so


noload => res_ael_share.so
noload => res_phoneprov.so
noload => res_speech.so
noload => res_musiconhold.so
noload => app_transfer.so
noload => app_parkandannounce.so
noload => app_privacy.so
noload => app_speech_utils.so
noload => func_vmcount.so
noload => app_voicemail.so
noload => app_sendtext.so
noload => app_url.so
noload => func_db.so
noload => app_playback.so
noload => pbx_spool.so
noload => func_blacklist.so
noload => app_minivm.so
noload => app_ices.so
noload => app_morsecode.so
noload => app_chanspy.so
noload => chan_mgcp.so
noload => app_dictate.so
noload => pbx_loopback.so
noload => app_disa.so
noload => app_zapateller.so
noload => app_forkcdr.so
noload => app_mp3.so
noload => app_db.so
noload => app_sms.so
noload => app_nbscat.so
noload => app_externalivr.so
noload => format_jpeg.so



I left the features.conf and rtp.conf files untouched. 

The key to my success was in the sip.conf file. I added externip and localnet entries. These allowed asterisk to figure out how to write the SIP headers correctly when traversing my IPCop firewall. The other important entry in the file was the bindaddress=192.168.0.13.  What I did there was to bind Asterisk to the aliased IP on the server and not the primary IP which SipX had already been bound to. (I tried just moving port to something else like 5560 but that didn't seem to work right).

With your new configs in place you should be able to start asterisk with a command like 'asterisk -vvvc'

Of course you need to configure your gateway in SipX now. Do so by going to Devices -> Gateway and add a Sip Trunk.  Be sure to use the aliased IP you bound asterisk to in the sip.conf file, in my case that was 192.168.0.13.

Next add the gateway to the appropriate dial plan rules and remember to click activate when you are done. I forgot this a few times and it caused me to waste some time trying to figure out why my changes didn't work.

And you'll need to add some port forwarding rules to your firewall to help with incoming calls. Forwards upd ports 5060 and 10,000-20,000 to the ip that you have asterisk bound to, 192.168.0.13 in my case.

Well this certainly isn't a step by step guide on how to set up a complete SipX/Asterisk server but it does highlight the difficult things that took me 2 days to solve. Hopefully it helps someone else too (or me when I forget this next week)