John A. Sullivan III
2009-Aug-27 18:23 UTC
[asterisk-users] Selective canreinvite in multi-tenant environment
Hello, all. In our multi-tenant environment, we would like to be able to use the reinvite media redirection within Asterisk for calls within a tenant but not between tenants. We would like inter-tenant calls to be fully proxied by the Asterisk server. I think the answer is, "we can't," but I thought I'd ask anyway. I'd dearly like to remove the substantial traffic associated with intra-tenant traffic from the Asterisk server and reduce the intra-tenant latency by doing so. However, I am very, very hesitant to allow our VPN connections to tenants to function as a router between tenants allowing one tenant to directly access phones on another tenant (that's not as wild as it sounds because of our use of the ISCS project - iscs.sourceforge.net). Since the tenants are all connecting via VPN, we are using RFC1918 addresses and no NAT is involved thus the canreinvite=nonat option does not help us. If we set canreinvite=nonat, that will allow for intra-tenant direct media but, if one tenant tries to call another via SIP, it will redirect the media at the Asterisk level but the packets will be dropped at the firewall / router level (or sooner as there may be no route to the destination) and the call will connect but with no sound. Any guidance would be greatly appreciated. Thanks - John -- John A. Sullivan III Open Source Development Corporation +1 207-985-7880 jsullivan at opensourcedevel.com http://www.spiritualoutreach.com Making Christianity intelligible to secular society
John A. Sullivan III
2009-Aug-27 21:09 UTC
[asterisk-users] Selective canreinvite in multi-tenant environment
On Thu, 2009-08-27 at 14:23 -0400, John A. Sullivan III wrote:> Hello, all. In our multi-tenant environment, we would like to be able > to use the reinvite media redirection within Asterisk for calls within a > tenant but not between tenants. We would like inter-tenant calls to be > fully proxied by the Asterisk server. I think the answer is, "we > can't," but I thought I'd ask anyway. > > I'd dearly like to remove the substantial traffic associated with > intra-tenant traffic from the Asterisk server and reduce the > intra-tenant latency by doing so. However, I am very, very hesitant to > allow our VPN connections to tenants to function as a router between > tenants allowing one tenant to directly access phones on another tenant > (that's not as wild as it sounds because of our use of the ISCS project > - iscs.sourceforge.net). > > Since the tenants are all connecting via VPN, we are using RFC1918 > addresses and no NAT is involved thus the canreinvite=nonat option does > not help us. If we set canreinvite=nonat, that will allow for > intra-tenant direct media but, if one tenant tries to call another via > SIP, it will redirect the media at the Asterisk level but the packets > will be dropped at the firewall / router level (or sooner as there may > be no route to the destination) and the call will connect but with no > sound. > > Any guidance would be greatly appreciated. Thanks - JohnAh, I found a way - that'll teach me to say there's something one can't do in Asterisk! However, it has turned up some unexpected behavior. First the new problem and then the original solution. The new problem: The documentation says the L() option prevents reinvites. However, this does not appear to be true. When we dial a SIP device with canreinvite=nonat using L(30600000) (8.5 hours), we see the RTP traffic shunted to be directly between the end points. If we use something like t instead, the reinvite is not issued and traffic is handled B2BUA. The original solution which works well except for the above problem: I'll explain this at two levels for the sake of those who do not need all the details. The inter-tenant calls are done via sip URLs which are handled differently from the intra-tenant, i.e., within a tenant one might dial 333 to get Jane whereas, from a different tenant, one would dial sip:jane at mycompany.com. The inbound uri handler simply redirects the dial plan to the dial plan for extension 333. This in turn calls our common dialing macro. We realized we could set a persistent channel variable in the uri handler, e.g., __DOPTS, set it to some dialing option which prevents reinvites, and then goto the extension part of the plan. We've relegated most of the functions handled by these options to the phones, e.g., transfer, hangup, record, so we didn't want to duplicate functionality. For that reason, we elected to use the L() option except it does not seem to work as mentioned above :-( Here are the gory details for those who actually need this functionality rather than those just curious. There are several issues involved. They are mainly provoked by the capabilities or lack thereof of the firewalls. Some of our clients have firewalls which are SIP aware and can handle the RTP port assignment as part of the SIP packet flow. Others are not SIP aware and thus must allow high UDP ports to be open for the RTP traffic. For those with SIP aware firewalls, we do not really need this fix. Allowing inter-tenant traffic is no more dangerous than allowing inbound SIP calls to phones since we can restrict it to the SIP port. Of course, even that is too insecure for many installations. For those without SIP aware firewalls, we have two issues. The first is security - we do not want to open a raft of high UDP ports for RTP traffic which could possible be exploited for other purposes. The second is NAT. If they attempted a direct RTP conversation rather than passing through the NAT aware Asterisk setup, the RTP traffic will not be properly NAT'd. Hmm . . . on second thought, that is probably not true as I do not believe the RTP traffic contains embedded IP address information in the data portion of the packet and the SIP signalling is still being handled by Asterisk. I'll have to play with that one. In any event, we have to worry about both inbound and outbound calls. To prevent inbound calls from being reinvited, we added the dial option to kill reinvites (which we set in a global macro named KREINVITE) to the inbound sip url handler. As one would imagine, to prevent outbound SIP calls from being reinvited, we added the ${KREINVITE} option to the outbound SIP URL handler. The final result looks something like this: KREINVITE=L(30600000) ; used to kill reinvite by inserting as an option in the dial command - timeout after 8.5 hours (30,600,00 ms) [macro-common] ; ARG1 = extension to dial ; ARG2 = extension for voice mail ; ARG3 = context for voice mail ; ARG4 = extension for followme (optional) ; ARG5 = Timeout is seconds until voice mail / followme (optional - defaults to 24) exten => s,1,Set(TM=${IF(${ISNULL(${ARG5})}?24:${ARG5})}) exten => s,n,Dial(${ARG1},${TM},${DOPTS}) exten => s,n,Wait(0.5) exten => s,n,Goto(s-${DIALSTATUS},1) [z10in] ; direct inbound SIP dialing exten => joe,1,Set(__DOPTS=${KREINVITE}) exten => joe,n,Goto(z10pub,613,1) [dial-uri] ; Always include this last because of its broad matches exten => _[a-zA-Z0-9].,1,GotoIf($[${SIPDOMAIN}!=pbx.mycompany.com]?:_.,1) ; non-URIs will automatically append @pbx.mycompany.com ; this logic separates mistyped extensions from valid URI attempts exten => _[a-zA-Z0-9].,n,Macro(uridial,${EXTEN}@${SIPDOMAIN}) exten => _.,1,Answer(0.5) exten => _.,n,Playback(im-sorry) exten => _.,n,Wait(0.0.5) exten => _.,n,Playback(you-dialed-wrong-number) exten => _.,n,Wait(0.4) exten => _.,n,Playback(vm-goodbye) exten => _.,n,Hangup() [macro-uridial] exten => s,1,NoOp(Calling remote SIP peer ${ARG1}) exten => s,n,Dial(SIP/${ARG1},60,${KREINVITE}) exten => s,n,Congestion() Hope this helps someone else. Improvements, suggestions, and constructive criticism welcome. If anyone knows why we are not getting the expected reinvite prevention from the L() option, please let me know. Thanks - John -- John A. Sullivan III Open Source Development Corporation +1 207-985-7880 jsullivan at opensourcedevel.com http://www.spiritualoutreach.com Making Christianity intelligible to secular society
John A. Sullivan III
2009-Sep-01 03:18 UTC
[asterisk-users] Selective canreinvite in multi-tenant environment
On Thu, 2009-08-27 at 14:23 -0400, John A. Sullivan III wrote:> Hello, all. In our multi-tenant environment, we would like to be able > to use the reinvite media redirection within Asterisk for calls within a > tenant but not between tenants. We would like inter-tenant calls to be > fully proxied by the Asterisk server. I think the answer is, "we > can't," but I thought I'd ask anyway. > > I'd dearly like to remove the substantial traffic associated with > intra-tenant traffic from the Asterisk server and reduce the > intra-tenant latency by doing so. However, I am very, very hesitant to > allow our VPN connections to tenants to function as a router between > tenants allowing one tenant to directly access phones on another tenant > (that's not as wild as it sounds because of our use of the ISCS project > - iscs.sourceforge.net). > > Since the tenants are all connecting via VPN, we are using RFC1918 > addresses and no NAT is involved thus the canreinvite=nonat option does > not help us. If we set canreinvite=nonat, that will allow for > intra-tenant direct media but, if one tenant tries to call another via > SIP, it will redirect the media at the Asterisk level but the packets > will be dropped at the firewall / router level (or sooner as there may > be no route to the destination) and the call will connect but with no > sound. > > Any guidance would be greatly appreciated. Thanks - JohnAs mentioned in another post, we were able to solve this by setting a w dial option to all inbound SIP calls from the Internet. Thus, all internal calls could reinvite but external calls could not. However, just when we thought this was working splendidly well, we turned up another roadblock - transfers. We find that once we transfer a call using our Snom phones, the call between the new call partners does not seem bound by the "w" constraint, Asterisk tries to reinvite the call, and the audio breaks because the firewall cannot associate the new RTP stream with a SIP session. How have others gotten around the problem of transfers causing reinvites on calls which should not allow reinvites? Thanks - John -- John A. Sullivan III Open Source Development Corporation +1 207-985-7880 jsullivan at opensourcedevel.com http://www.spiritualoutreach.com Making Christianity intelligible to secular society