Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2147285
  • 博文数量: 333
  • 博客积分: 10161
  • 博客等级: 上将
  • 技术积分: 5238
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-19 08:59
文章分类

全部博文(333)

文章存档

2017年(10)

2014年(2)

2013年(57)

2012年(64)

2011年(76)

2010年(84)

2009年(3)

2008年(37)

分类: LINUX

2010-09-19 16:08:30

SIP穿越NAT&FireWall

 
 
SIP从私网到公网会遇到什么样的问题呢?

包的地址转换。

SIP消息里面的SIP地址转换。

SIP消息里面的SDP中的RTP地址转换。  

NAT和Firewall的基本原理

首先,NAT的几种方式:

FullCone当一台私网内的主机向公网发一个包,其本地地址和端口是{A:B},NAT会将其私有地址{A:B}转换成公网地址{X:Y}并绑定。任何包都可以通过地址{X:Y}送到该主机的{A:B}地址上,NAT会将任何发送到{X:Y}的incoming包的地址{X:Y}转换成{A:B}。

Partial/RestrictedCone当一台私网内的主机向公网发一个包,其本地地址和断口是{A:B},NAT会将其私有地址{A:B}转换成公网地址{X:Y}并绑定。任何包都可以通过地址{X:Y}送到该主机的{A:B}地址上,但是,NAT只为第一个发往{X:Y}的包绑定成{A:B}|{X:Y}<->{C:D},其中{C:D}是那个包的源地址和端口。也就是说,只有来自{C:D}的包才能于主机{A:B}通信。

Partial和RestrictedCone的区别是Partial只绑定incomingpacket的IP地址,而RestrictedCone会绑定incomingpacket的IP地址和端口。也就是上面描述的那种情况。

SymmetricCone:当一台私网内的主机向公网某台主机发送一个包,{A:B}à{C:D}。NAT会将其地址{A:B}转换成{X:Y},并为其绑定成{A:B}|{X:Y}<->{C:D}。NAT只接受来自{C:D}的incomingpacket,将它转给{A:B}。也就是说,如果私网内的主机要向外面发送一个包,它必须要知道对方的公网IP和端口。但如果对方也是处于一个私网内,它就很难获知对方的公网IP和端口。

由此可见,SymmetricCone条件最严格,Partial/RestrictedCone次之,FullCone条件最不严格。

下面再看看Firewall的基本策略:

l        Firewall会判断所有的包是来自内部(Inside)还是外部(Outside)。

l        一般,允许所有来自inside的包发出去。

l        一般,允许来自Outside的包发进来,但这个连接必须是由Inside发起的。

l        一般,禁止所有连接由Outside发起的包发进来。

l        一般,firewall会允许几个信任的outside主机,他们可以发起建立连接,并发包进来。
 

 所有NAT和Firewall都是对于TCP/IP层以下进行处理和过滤的,而SIP应用的地址是在应用层。所以必须采用其他的途径来解决这一问题。

针对不同的NAT类型,可以有不同的解决方案。

l        UPnP

l        ExternalQuery

l        STUN

l        ALG

其中前3种都是由SIPClient(包括UA和Proxy)通过某种手段或协议在INVITE之前获取自己的公网地址和端口。需要SIPClient提供额外支持,并且也不适应所有的NAT方式。

ALG(ApplicationLayerGateway)适应所有NAT方式,并不需要SIPClient做任何额外的支持。它对Application层的SIP信令进行处理和修改,从而做到透明转换地址。

下面针对一个案例详细描述ALG的解决方案。

SIPALG解决方案


ALG修改SIP消息里面的SIP地址和端口和SDP消息里面的RTP地址和端口,其中RTP地址和端口要向RTPProxy请求获得,RTPProxy分配自己的一个空闲的地址和端口,并和这个Call保持映射关系。并为分配给呼叫双方的地址和端口进行绑定,这样,呼叫双方的RTP连接地址都是RTPProxy,由RTPProxy经过中转,发至真正的目的地。

假设,有两个SIPClient要进行通信,Ada和Bob,他们分别位于自己的NatServer后面:

其中两台NATServer都是SymmetricCone方式。

其信令流程如下:

1.        Ada发起信令,InviteBob。

IPPacketIPAddress:

From:192.168.1.10:5060

To:128.97.41.56:5060(SIPALG)

SIPMsgIPAddress:

From:192.168.1.10:5060

To:128.97.41.56:5060

SDPBodyIPAddressforRTP:

192.168.1.10:10024

2.        经过NATServer,NAT将其私有地址转换成公网地址,并绑定,由于是采用SymmetricCone方式,所以还绑定目的的IP地址。

{192.168.1.10:5060}|{128.96.41.1:5678}<->{128.97.41.56:5060}

IPPacketIPAddress:

From:128.96.41.1:5678

To:128.97.41.56:5060(SIPALG)

SIPMsgIPAddress:

From:192.168.1.10:5060

To:128.97.41.56:5060

SDPBodyIPAddressforRTP:

192.168.1.10:10024

3.        SIPALG接受到该INVITE,发现其包的IP地址和SIPIP地址不同,就判断其是经过NAT,于是就将其相关的SIPIP地址修改。

并检查它的Body中是否是包含SDP信息,如果是,且有RTP地址,SIPALG就会去向RTPProxy请求一个公网RTP地址来代替原有的RTP地址。

IPPacketIPAddress:

From:128.97.41.56:5060

To:128.96.63.25:5566

SIPMsgIPAddress:

From:128.96.41.1:5678

To:128.96.63.25:5566(下一跳的地址)

SDPBodyIPAddressforRTP:

128.97.44.5:3000

4.        因为Bob不断的向SIPALG发送注册包,所以,它的NATServer始终为它保留着这么个绑定,{10.0.0.12:5060}|{128.96.63.25:5566}<->{128.97.41.56:5060}。所以,由SIPALG发出的INVITE,Bob能收到。

Bob返回200OK,包含SDP信息。

IPPacketIPAddress:

From:10.0.0.12:5060

To:128.97.41.56:5060

SIPMsgIPAddress:

From:10.0.0.12:5060

To:128.97.41.56:5060(下一跳的地址)

SDPBodyIPAddressforRTP:

10.0.0.12:10002

5.        NATServer将其包的IP地址修改。发往SIPALG。

6.        SIPALG接受到该200OK,发现其包的IP地址和SIPIP地址不同,就判断其是经过NAT,于是就将其相关的SIPIP地址修改。

并检查它的Body中是否是包含SDP信息,如果是,且有RTP地址,SIPALG就会去向RTPProxy请求一个公网RTP地址来代替原有的RTP地址。

IPPacketIPAddress:

From:128.96.63.25:5566

To:128.96.41.1:5678

SIPMsgIPAddress:

From:128.96.63.25:5566

To:128.96.41.1:5678(下一跳的地址)

SDPBodyIPAddressforRTP:

128.97.44.5:3002

7.        此时,RTPProxy为这个Session保持着这么个连接绑定

{128.97.44.5:3000|128.97.44.5:3002}

8.        Ada收到200OK,它认为对方的RTP地址是128.97.44.5:3002。将与其建立连接。

而Bob认为对方的RTP地址是128.97.44.5:3000。将与其建立连接。

9.        当RTPProxy的3002端口收到包,它可以从包地址获得Ada的RTP公网IP。

当RTPProxy的3000端口收到包,它可以从包地址获得Bob的RTP公网IP。

从而,RTPProxy会将3002端口收到的包转发到Bob的RTP公网IP。

同样,RTPProxy会将3000端口收到的包转发到Ada的RTP公网IP。

这样,一个通话的连接就成功建立。
SIPALG的部署

因为无论如何,都需要所有RTP包经过RTPProxy,所以所有的MS都要有修改SDP的能力,而只有SIPALG需要有修改SIP消息的能力。让用户配置自己的Proxy是什么,避免公网的SIPClient也经过SIPALG,造成没必要的消耗。

补充

如果SIPALG发现INVITE包的地址和SIP地址是一致的话,它将不对这个包进行修改,它认为这个包是来自公网,或者SIPClient具备了穿越NAT的能力。但它会修改其SDP的IP地址。

ISSUE:

1.      如果SDP描述的是单工工作的话,RTP连接无法建立,因为RTPproxy始终无法知道沉默方的RTP公网IP。

2.      每次建立RTP连接,某一方的RTP包可能会丢掉若干个,直到RTPproxy获知另一方的RTP公网IP。

3.      是否应该强制任何RTP包都要经过RTPProxy,无论它们都是来自公网,可以直接连接。我想是的,因为主叫方是不知道被叫方的网络环境的。

4.      如果多个RTPProxy进行均衡,如何保证为主叫方分配IP的Proxy和为被叫方分配IP的Proxy是一致的呢?(它们必须是同一台Proxy)

可以增加一个header,比如RTPproxy,这个header只有SIPALG认识。

5.      如果SIP消息加密,就无法修改其SIP的IP地址。
阅读(2946) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~