[asterisk-dev] AstriDevCon Follow Up - Asterisk and Kamailio - smoother integration

Daniel-Constantin Mierla miconda at gmail.com
Tue Mar 10 10:43:50 CDT 2015


Good to see the discussion had more people and wider approach on
different levels, covering pure agnostic signaling up to specific
application constraints.

While being somehow silent, I worked to make a concrete step forward,
developing a new module for kamailio named auth_xkeys -- for those
interested, some details here:

  * http://kamailio.org/docs/modules/devel/modules/auth_xkeys.html

Specifically, the issue I wanted to solve with this one is the
elasticity of authentication/trust relations between the nodes of a VoIP
platform.

So far most of authorization between Kamailio and Asterisk relies on IP
addresses, but those need to be provisioned one by one in both sides.
The new module is practically adding a custom header with a hash over
parts of the message or other environment attributes (eg., IP address)
and a shared secret. The www-digest with username and password has the
overhead of an extra round of signaling messages, but also the
constraint on CSeq increment after the challenge. Also, the MD5 is
rather week hashing these days.

Imagine I have a cloud of 200 asterisk/kamailio application servers and
I want to add another Kamailio edge proxy/load balancer in Singapore to
collect the traffic from the area based on DNS. Will require an update
to 200 nodes for adding a new trusted IP. With a shared secret to build
the auth key, that is transparent. Think about that you need to
orchestrate the number of application servers and edge proxy dynamically
to be able to cope with special situations (DDoS attacks, unexpected
emergencies for lot of people (earthquake, etc...) or days of the year
with lot of traffic (christmas, new year)).

What I implemented with auth_xkeys is not something new, it is used a
lot by the API web services (e.g., github) and I think it is good for
SIP networks as well. It is more about secret keys management.

What Asterisk devs think about it? Does it sound useful to get a similar
mechanism in Asterisk? I can provide more tech details if needed, just ask.

Now some remarks on different points discussed by others here before:

- to confirm: dispatcher can take the algorithm and destination set id
from variables, those values can be taken from anywhere (db, via some
api, etc)
- DNS is good for discovery, but propagation is unreliable over the
public networks
- using an embedded language to create all the attributes needed for the
context of the call is ok as long as it doesn't do any other network
communication. There is already a sip packet sent between the nodes. If
the sender has to do some network transmission to prepare the receiver,
it adds another set of troubles: delays, connection failures, incomplete
transmissions, etc. - it is not helping much with scalability. In other
words, ideally I am looking for something like: you got the INVITE
request from a trusted proxy, all needed for routing should be inside it
+ some config templates.

Daniel

On 24/02/15 17:58, Matthew Jordan wrote:
>
>
> On Mon, Feb 23, 2015 at 2:07 PM, Olle E. Johansson <oej at edvina.net
> <mailto:oej at edvina.net>> wrote:
>
>
>     On 23 Feb 2015, at 20:10, Matthew Jordan <mjordan at digium.com
>     <mailto:mjordan at digium.com>> wrote:
>
>>
>>
>>     On Mon, Feb 23, 2015 at 11:16 AM, James Cloos <cloos at jhcloos.com
>>     <mailto:cloos at jhcloos.com>> wrote:
>>
>>         >>>>> "MJ" == Matthew Jordan <mjordan at digium.com
>>         <mailto:mjordan at digium.com>> writes:
>>
>>         MJ> What I'm trying to reason out is: given a set of routing
>>         constraints -
>>         MJ> which includes not only load balancing but also
>>         "application" level routing
>>         MJ> decisions - what's the appropriate place for that
>>         information to live?
>>         MJ> Particularly when you want your entire system - not just
>>         Asterisk - to be
>>         MJ> scalable?
>>
>>         You need to use something to keep track of whether each box
>>         is reachable
>>         and what each is doing.  There a lots of ways of doing that,
>>         including
>>         custom network applications, shared networkable databases,
>>         shared nfs,
>>         et alia.
>>
>>         Then each node needs a bit of logic to use that data to
>>         determine what
>>         to do with any given event.
>>
>>         As one example, if a sip server gets an invite which directs
>>         on to an
>>         existing conference, it needs to know which asterisk is
>>         handling that
>>         conference, so that it can send the invite there.
>>
>>         A shared database is required, but whether it is a custom
>>         application, a
>>         networkable db or a local db stored on a networked file
>>         systems is
>>         something anyone writing the code needs to choose.
>>
>>
>>     Completely agree.
>>
>>     What I'm driving towards - albeit in something of a roundabout
>>     fashion - are two notions:
>>     (1) Hard coding logic in application configuration does not lend
>>     itself well to scalability. Kamailio lessens the pain in certain
>>     ways - you're typically going to have fewer proxies than
>>     application servers (although, I suppose that depends on what you
>>     are doing). Also, as Olle pointed out, you can replicate
>>     information out using an htable. Or use a database. To some
>>     extent though, this is not much different than using func_odbc
>>     with Asterisk (a concept many people miss often.) At the same
>>     time, requiring direct access to a database from my routing
>>     engine/media application server does not lend itself well to
>>     expressive logic. While I've managed to push the data out of the
>>     application, I haven't necessarily done the same with the
>>     business rules.
>>
>>     If you approach the problem purely from a "how horizontally
>>     scalable can I make this," then ideally most of your business
>>     logic would lie outside of the routing engine (Kamailio) or the
>>     media application server (Asterisk). That may mean a web
>>     microservice architecture that exposes REST APIs for the
>>     real-time component to consume. That may mean something else. As
>>     Daniel noted, the more REST APIs you hit using a cURL module (or
>>     what have you), the slower things get in Kamailio. The same is
>>     true for Asterisk. What I'm trying to fish for is where that
>>     dividing line should occur - that is, what properly belongs to
>>     Kamailio (routing decisions) and what properly belongs to
>>     something else.
>>
>>     (2) Domain specific languages require domain specific knowledge.
>>     This is not necessarily a bad thing. At the same time, it's far
>>     easier to parallelize the problem of application development if
>>     you can split tasks into well defined domains that make use of
>>     tools that have a wider base of knowledge. If, for example, the
>>     logic of "who is in a conference on which server" can be answered
>>     by a REST API written in Python, or JavaScript, or something else
>>     - and does not even live on the Kamailio server - then not only
>>     does the job of the Kamailio integrator become easier, it is also
>>     becomes easier to find multiple people to help write the services
>>     that it integrates with.
>
>     Kamailio really doesn't need to know as long as Asterisk knows...
>     You are trying to solve something that is not really a problem,
>     Matt. I have tried this path before with conferences and ended up
>     with something too complex. Went back to
>     forking, if a server responded with 200 OK I added a temporary
>     state in an autoexpire hashtable so I remembered for next call
>     which did not need to fork. Simple. Fast. No distributed states.
>
>     The real key to scalability is keeping it simple and keeping
>     states local. As soon as you start trying to synch or distribute
>     states it gets very complex and you loose a lot of scalability.
>     Asterisk is filled with all kinds of states, keep it there as much
>     as possible and be smart with your signalling. You want to be able
>     to restart Kamailio anytime without loosing states and without
>     disrupting any single call. As soon as you start adding call
>     states, server states and conference server states you loose a lot
>     of that and end up with replication in databases and other complex
>     schemes.
>
>
> Really, distributing the state in Asterisk is not much of a problem in
> this scenario. Sure, if the application in question is ConfBridge, or
> Queue, or some other dialplan application, then the difficulty of
> sharing that state across clustered Asterisk instances is non-trivial.
> However, in a system where the application state lives off of the
> Asterisk boxes - that is, where ARI is used to control the Asterisk
> instances and an external process (or set of processes - everyone must
> scale!) manages the application state - then the question of how the
> application state distributed is solved.
>
> That is: I'm not really questioning where the application state lives.
> I'm questioning how routing decisions - which may be impacted by that
> application state - should be made. It sounds like the answer is
> "don't worry, and just use Kamailio's built-in routing mechansims."
> Which is an acceptable answer - there's ways to work with that answer
> in a clustered Asterisk environment.
>
>  
>
>     Forking doesn't cost much, really. Using SIP makes life simple.
>     The network flow is already established.
>
>
> Forking to all Asterisk servers is certainly a solution. I could also
> 302 the INVITE request or send a REFER request to the initiator to
> move the session to another Asterisk server if the one it lands on
> isn't the one that is "correct" based on some application state.
> Handling that at the application level is relatively straight forward;
> my line of questioning was really to make sure that there isn't some
> mechanism in Kamailio that would be more appropriate.
>
>  
>
>     If you are looking for restful interfaces, Kamailio has an
>     embedded HTTP server you can use for quite a lot compared with the
>     Asterisk one. The HTTP requests are as configurable and routable
>     as the SIP requests... Quite cool.
>
>
> You do know we built all of ARI on the internal Asterisk HTTP server,
> right? :-)
>
> Of course, the request callbacks aren't exposed to the dialplan - but
> then again, that's not really a concept that the Asterisk dialplan
> syntax would handle well.
>  
>
>     There are a few applications that require more states, like trying
>     to build a PBX in Kamailio. - but why try that when Asterisk has
>     all the functionality you need? :-)
>
>     Keep the states where they belong. 
>
>     Now for load balancing, we could add a module to Asterisk that
>     sends simple SIP messages with an attachment that describes
>     current call load and maybe a few global variables that I
>     configure. application/asteriskstate - simple json structure that
>     we can parse in Kamailio and use for load balancing on call and
>     cpu load. This could be a subscribe/notify event package that
>     Kamailio feeds into the DMQ cluster.
>
>
> Since this would be consumable in Kamailio, a spec on the event
> package would be handy.
>
> I noticed that there are some RFCs for this already. Most are
> informational, although RFC 7200 looks to take things to quite a
> logical extreme. Any thoughts on these?
>
> * RFC 5390: Requirements for Management of Overload in the Session
> Initiation Protocol - https://tools.ietf.org/html/rfc5390
> * RFC 6357: Design Considerations for Session Initiation Protocol
> (SIP) Overload Control - https://tools.ietf.org/html/rfc6357
> * RFC 7200: A Session Initiation Protocol (SIP) Load-Control Event
> Package - https://tools.ietf.org/html/rfc7200
>
>
>  
>
>     Another thing would be to have events triggered on startup of
>     asterisk and shutdown - maybe something as simple as a REGISTER.
>     These could be used to enable and disable one  Asterisk server in
>     a dispatcher set.
>
>
>
> I would imagine that in any clustered scenario, you would want
> Asterisk to REGISTER to Kamailio to notify it of its existence. If a
> SUBSCRIBE/NOTIFY scheme were used to inform Kamailio of the loaded
> status of the Asterisk instances, Kamailio could then SUBSCRIBE to
> Asterisk and start receiving subsequent NOTIFY requests.
>
> -- 
> Matthew Jordan
> Digium, Inc. | Director of Technology
> 445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
> Check us out at: http://digium.com & http://asterisk.org
>
>

-- 
Daniel-Constantin Mierla
http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda
Kamailio World Conference, May 27-29, 2015
Berlin, Germany - http://www.kamailioworld.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-dev/attachments/20150310/d2e9bf1f/attachment-0001.html>


More information about the asterisk-dev mailing list