Asterisk and Openser in WAN Environment

I spent the greater part of the last two years developing software to integrate with Asterisk and my most recent achievement was completely integrating OpenSER and Asterisk for use in a WAN environment. Due to the lack of any howto documentation or specific help in implementing such a network, I felt the need to write an article on the subject. This is my first attempt at technical writing so please be nice and any construtive feedback is most welcome.

The target audience for this article is assumed to have a reasonable understanding of VOIP protocols, in particular SIP or Session Initiaed Protocol. If you are just starting out in this arena, I suggest you might want to polish up on the basics. There is plently of information out there to help you gain a solid understanding of SIP so I won’t be going over any of the details regarding the protocol, nor will I be explaing where and how to get Asterisk, OpenSER and Mediaproxy.

Lets begin with the problem. The SIP protocol was not designed to run in a WAN or Wide Area Network environment. Ip Addressing information is sent via the protocol internally, and while your standing routing and NAT solutions allow the actual packet to reach its destination, it isn’t of much use as it contains registration or contact details of the sending unit using private IP ranges. There are a number of solutions to combat this issue and there are even features built into most SIP phones and into Asterisk to aide the registration problem, but I was never able to
connect multiple handsets to Asterisk with full functionality. The main problem I came up against was multiple handsets on a single given private network weren’t able to call each other and there was a limit of one call at a time.

Further research led me SIP proxy solutions, firstly I used SER and Mediaproxy, then later on OpenSER. Using this setup, you give OpenSER the responsibility of handling Registrations, CDR’s, call routing, overflow and most importantly when combined with Mediaproxy – media stream negotiation. Using the getting started guide by the guys at onsip.org I succeeded in allowing a single network with one public IP to have multiple handsets all with the ability to call externally, call each other and receive calls, through and from asterisk without any limitations on the number of simultaneous calls. However, I then discovered that all the ‘cool’ features that I was aiming to gain by using Asterisk were not working or available – Music on Hold, Conference Calls and Call Transfers.

These features are provided by a PABX and if you connect your SIP handset directly to an Asterisk PABX in a private network environment, all these features are available without any fuss. So this became the goal line for the product, to have full PABX features in a WAN environment without deploying Asterisk PABX’s at each site. This was the hard part I couldn’t find any open source solutions online, and the actual problem was a complex issue. The core problem, as already mentioned, lies in the SIP protocol. OpenSER inspects the registration and invite datagrams and modifies it to public ip’s as needed giving us the standard functionality, but when a handset sends a Hold request, it has embedded private ip information in the packet and I was unable to find any way for OpenSER to catch and modify these types of packets.

This leads us onto the solution – bring asterisk into every call leg once it has been ‘fixed’ by OpenSER – meaning after the private ip’s have been removed.

Now onto the HOWTO section, it took me a few weeks of hand crafting to build my working OpenSER config and it is in production and licensed by a company – so I cannot give it away.

I can tell you how to write the bits you will need. Firstly build a fresh new config – I use the tool config generator from sipwise. Build your new config using the template ‘SIP Proxy/Registrar with Mediaproxy’, and make sure you include the sections about offnet routing. Once you have the basic system up and running you should have your OpenSER
proxy modifying and redirecting INVITES to your Asterisk gateway based on the uri. Your Asterisk server and OpenSER proxy server should be both listening on different ip addresses (note: virtual interfaces sufficed for me). In the environment I built, there was a seperate Asterisk PABX handling border control for the SIP trunk, and therefore the Asterisk server which OpenSER connected to then had to do another forward on to the Asterisk border server.

The default config needs to be modified to redirect valid sip calls to the asterisk machine, and then onwards to your pstn gateway or back to openser if the call is destined for a sip extension. You can achieve this by locating the section labelled

######################################################################## # Request route 'invite-find-callee' ######################################################################## route[5]

In this route, modify the doesuriexist() if block to rewritehostport to the asterisk server ONLY if the domain of the caller matchs the domains of extensions we allow to register on OpenSER. If you neglect this, you will create a loop when the asterisk server tries to dial back to the original extension. This affects extension -> extension calls by forcing them to talk through asterisk.

if(doesuriexist()) { xlog("L_INFO", "Callee is local - M=$rm RURI=$ru F=$fu T=$tu IP=$si ID=$cin"); # check where the request is from? if($fd == "sip.domain") { # forward to asterisk rewritehostport("192.168.0.1"); route(3); } else { route(6); } }

Now in your asterisk configs you will need to configure your sip.conf to accept calls from your OpenSER server, and then in extensions.conf, you will need to add an extension dialling rule to dial the original extension back through OpenSER.

sip.conf extract:

; this is our openSER gateway. we need to accept calls from him! [192.168.0.2] type=friend ; seperate context for our OpenSER server context=outgoing insecure=very host=192.168.0.2 disallow=all allow=alaw

extensions.conf extract:

; OpenSER [outgoing] ; local sip phones exten => _1XXX,1,ringing exten => _1XXX,2,wait(0) exten => _1XXX,3,Dial(${EXTEN}@192.168.0.2) exten => _1XXX,4,Hangup

The rest of your OpenSER config is up to you how you customise it, In my environment all that was needed was a few uri based conditional statements with rewritehostport commands to the relevant pstn gateways. You can put these in the else statement for the doesuriexist() statement. However you choose to configure it, if you can invole Asterisk in each leg of the call, you will get your PABX features, so this also applies to inbound calls from my pstn gateways. They all redirect to the asterisk server first, which then fowards onto the OpenSER server.

I hope this article helps you build a fully functional Virtual PABX setup in a WAN environment, please leave a comment if you found this article useful or if you have any problems or bugs please let me know.

Don’t have the time or resources to build this yourself, or you just can’t get it working? Contact me for a quote on setting it all up for you, or
take a look at our selection of Virtual products built with the same technology.