SIP NAT ALG
VoIP(Voice on IP),从字面上看就是语音跑在IP网络上。具体来说就是将电话业务与web浏览,email等其它数据应用一样,承载在IP网络(例如互联网)上,将其语音数据以IP包的形式传输。
与主流的web应用相比,VoIP具有以下特点
媒体(内容数据)的传输是双向对称,实时的,基于单独的实时传输协议
呼叫建立过程基于单独的信令协议,独立于语音数据传输
这使得VoIP有自己独特的协议栈:明确区分了独立的信令协议与媒体传输协议。
VoIP协议栈
信令协议
信令协议本身不负责VoIP语音通信本身,只负责VoIP通话关系的建立,具体包括通话双方媒体编码的协商,RTP地址的交换等。
由于VoIP通话双方是对等的,因此不同于HTTP这样的client-server协议,VoIP信令协议必须是对等的协议。
SIP是目前主流的VoIP信令协议,它是由属于互联网领域的标准化组织IETF(RFC3261)规范化,并被电信领域的标准化组织3GPP采纳,作为IMS的核心协议。
SIP既可以基于UDP,也可以基于TCP。
H.323是过时的VoIP信令协议,它是由国际电信联盟的标准化机构ITU-T规范化的,目前基本已经被SIP取代。
媒体编码与传输
发送方传输语音之前首先需要进行编码,以方便基于IP网传输。接收方收到语音后首先需要进行解码,之后才能播放。
RTP(Real Time Transport Protocol):实时传输协议,媒体数据的实时传输。
RTP基于UDP,其最主要的任务就是对语音数据(包)进行实时传输。通常一个VoIP通话会包含两个相对独立的单向RTP流。
QOS保障协议
VoIP中主要采用资源预留协议以及进行服务质量监控的实时传输控制协议来避免网络拥塞,保障通话质量。
RSVP最初是IETF为QoS的综合服务模型定义的一个信令协议, 用于在流(Flow)所经过的路径上为该流进行资源预留,从而满足该流的QoS要求。资源预留的过程从应用程序流的源节点发送Path消息开始,该消息会沿着流所经过的路径传到流的目的节点,沿途建立路径状态;目的节点收到这个Path消息后,会向源节点回送一个Resv消息,并沿途建立预留状态,若源节点成功接收到预期的Resv消息,则认为在整条路径上资源预留成功。
NAT简介
在理想的互联网世界中,所有设备都能够直接通信(IPv6便是为了这个目的,它具备几乎无限的寻址空间)。然而,到今天为止,IPv4仍然广泛应用工作良好,这主要是借助于NAT技术。NAT使得连接在私网上的客户端设备(例如PC,智能手机等)可以通畅的访问互联网公网上的服务。实际上,今天大多数客户端设备都位于 NAT之后,没有自己的公网IP地址。
NAT(网络地址转换)的工作原理是让私网中的客户端设备共享公网IP地址,来可以访问公网上的服务。
具体如下图所示:
NAT实现原理示意
说明
客户端通过NAT设备向公网IP发送数据包;收到客户端的数据包后,NAT设备为其分配公网地址(IP-端口),将数据包的源地址替换为公网地址,再发送出去;
同时NAT上保留内网地址-外网地址的绑定关系(session Table)
服务器向收到的数据包的源地址上发送数据包,NAT会收到数据包,并根据之前保留的绑定关系转发到客户端
显然,NAT对于单纯的内网客户端-外网服务器场景工作良好。实际上,NAT主要就是面向HTTP这种客户端-服务器模式设计的,对HTTP之类的客户端服务器协议友好。
SIP穿越NAT的问题
NAT对于SIP不是很友好,这是由于
SIP是个对等协议,通信双方都既是客户端(UAC)又是服务器(UAS)
SIP协议本身的某些参数(如Via,Contact)会携带传输层地址信息(IP,端口),而NAT只作用于传输层协议,不会修改SIP协议中的相关参数。这造成经过NAT转换后,传输层协议本身的地址信息与SIP协议层中携带的传输层地址信息不一致
收不到SIP请求
一般情况下,外部无法通过NAT主动访问处于内网的主机。因此,如果没有预先建立的连接,处于内网的SIP客户端无法收到来自外部的SIP请求。
收不到SIP响应
通常内网客户端可以通过NAT主动访问外网的服务,因此处于内网的SIP客户端可以主动向外发送SIP请求。
但却可能收不到SIP响应。
按着RFC3261的定义,SIP响应消息的目的IP地址是根据SIP请求消息的源IP确定,但目的端口是根据SIP请求消息的顶层 'Via' 头域中的端口值确定的。
当SIP客户端处于NAT之后时,其发送的SIP请求消息的 'Via' 头中的端口值是客户端上的端口,而非NAT上打开的针孔的端口。
这导致如下图所示,SIP响应被发到NAT上,但目的端口是5060,而非NAT上打开的端口10923,于是SIP 响应消息被 NAT丢弃。
失败的SIP响应
收不到媒体
在 SIP offer/answer 交换中,会话中的每个SIP客户端都要在SDP中填写自己接收媒体的IP地址和端口组合。但当SIP客户端处于内网中时,它给出的媒体接收地址是一个私网IP地址和端口组合,而这个地址端口组合无法从NAT外访问时,SIP客户端就收不到媒体。如下图所示。
失败的媒体
解决方案技术说明
如前所述,SIP的NAT穿越可以分为两个独立的问题:信令穿越,媒体穿越。
SIP信令穿越
对称响应
对称响应可以解决收不到SIP响应的问题。根据前面的说明,收不到SIP响应是因为SIP响应被发送到了SIP 'Via' 头域中的IP地址和端口,而非NAT上打开的“针孔”对应的IP地址和端口。
“对称响应”使SIP响应可以被发往NAT上打开的“针孔”,从而正确转发到客户端。如下图所示,客户端A发出的SIP请求在NAT上打开了一个“针孔”,之后这个SIP请求的响应将通过这个”针孔”发回客户端A。
对称响应
“对称响应”首先需要Proxy支持。
遵循对称响应规范[RFC3581]的SIP Proxy将向收到的SIP请求消息的传输层源地址与端口发送SIP响应(而非SIP请求的 'Via' 头域中的IP地址与端口)。
具体来说,
收到SIP请求后,Proxy需要将传输层源地址填入Via头域,源IP设为”received”参数值,源端口设为'rport' 参数值,然后向被叫侧转发;
当Proxy从被叫侧收到SIP响应后(根据SIP规范Via会被原样带回),根据其中Via头域的”received”参数值与'rport' 参数值向主叫侧发送SIP响应。
“对称响应”对SIP客户端也有要求,简单来说就是从同一端口接收和发送SIP消息。大多数现代SIP电话默认使用这种通信方法。
SIP保活
SIP保活可以解决收不到SIP请求的问题。
处于NAT里面的SIP终端可以通过SIP注册进行SIP保活。一旦 SIP终端开机,它将尝试向外部的SIP服务器发送注册消息,SIP注册本身是为了向SIP服务器登记终端的当前地址,以支持呼入寻址。当SIP终端在NAT后时,SIP注册同时可以创建了NAT绑定,实现SIP保活。
NAT 设备上创建的NAT绑定通常会在一段时间不活动后关闭(通常为 60 – 900 秒,具体取决于设备)。这将使 外部的SIP请求无法发进来。为了保持 NAT 绑定打开,可以将SIP注册的刷新周期设置的更短一些,例如每 40 秒发送一次 SIP注册消息,实现SIP保活。
媒体穿越 Media Traversal
媒体NAT穿越问题没有那么简单,需要若干穿越方法的组合。
对称RTP/RTCP
媒体穿越的主要问题是内部IP-端口组合无法从NAT的公网侧访问。“对称 RTP/RTCP”[RFC4961]技术可以用于克服这个问题,它要求 SIP终端从同一IP address/port 组合发送/接收RTP/RTCP traffic 。
SIP互联互通之NAT穿越
目前,根据对NAT支持的不同,处理机制的不同,业内把解决NAT的方法一般有分为以下几种:
这些方案都有其各自的特点。不同企业类型的要求不同,部署成本,安全因素,维护成本等因素的影响,所以它们对解决方案的要求也可能有所不同。
今天,我们会介绍更多市场中主流的一些NAT穿越解决方案UPnP、 ALG、ICE和Media Proxy。
在NAT解决方案中,我们不仅仅需要解决SIP信令的问题,还要解决RTP的问题。现在我们举两个简单的例子说明NAT防火墙对SIP相关业务的影响。在以下的RTP 示例中,SIP信令都没有问题,内网用户呼叫到外网也没有问题,但是内网用户可能听不到内网用户的语音,出去的RTP语音可以成功到达目的地终端,但是外网终端则不能进入到内网中。虽然SIP的SDP中已经添加了对RTP语音的描述,但是如果防火墙会过滤这些端口,或者根本没有开启这些端口的话,那么语音流则会被过滤掉。这就是我们通常所说的单通现象。
在下面的这个RTP示例中,如果是从防火墙外部用户发起呼叫的话,防火墙会直接过滤了SIP请求,SIP消息会被拒绝。
从以上简单的示例中,读者可以看到,很多时候我们面对的现实情况是:
RTP端口是动态变化的,这是一个难题。
防火墙不知道RTP端口变化。
让防火墙开启更多端口在很多场景中是非常不现实的。
针对以上的问题,为了解决这些问题,我们依次介绍几个常见的解决方案。
UPnP
在网络中使用UPnP的设置方式。UPnP是一种非常简单的协议,它可以运行在SIP终端设备中,终端设备开启这个功能以后,它可以直接查询公网地址和端口,然后让SIP INVITE重新写入新的地址,在SDP中使用公网地址。UPnP的好处是目前大部分的厂家都支持此协议,终端用户或者一般家庭用户可以通过简单设置就可以实现简单的NAT穿透。
当内网的主机启动UPnP程序的时候,就会在NAT上产生“映射端口”与UPnP程序的端口一一映射,而且不会被回收。从外部来的消息,只要是发送到“映射端口”的,直接就会送至内网的UPnP程序。像我们平常用到的迅雷,这种方式也不用打洞,但缺点就是需要应用程序、操作系统以及NAT支持UPnP。
ALG
ALG全称是Application Layer Gateway。RFC2633对ALG有粗略的定义。ALG可以对SIP相关数据进行转译(包括呼入请求,响应;呼出请求响应),隐藏内网必要消息,它收集SIP消息中的信息,主要对SIP 头的Via,Contact,Route和Record-Route进行处理。它和Media Proxy不同。它具有以下几个方面的特点:
ALG可以在DMZ中进行设置,由防火墙实现对其控制。
和Media Proxy类似,所有SIP消息和RTP消息可以通过ALG转发到目的地地址。
如果需要,ALG可以配合NAT修改SIP消息的一些值域。
ALG可以以软件的形式嵌入到防火墙。
以下示例演示了一个简单的注册流程,通过ALG以后,ALG修改地址,继续对注册服务器进行注册。注册服务器返回地址以后,ALG再次修改为内网地址。
因为SIP的技术越来越普及,有一些防火墙增加了对SIP的部分支持功能。让我们首先看一个如果是外网的用户呼叫内网用户时的流程,外网用户呼叫内网时,在内网SIP终端返回给外网用户时,防火墙设置了一个策略,内网接收到端口是3232,防火墙则重新映射了一个端口8000,并且修改了SDP信息,然后在SDP中携带了新的RTP接收端口8000,发送给外网用户,通知外网用户,内网终端的RTP接收端口是8000。
外网终端通过这个指定的端口发送RTP语音流。防火墙知道通过这个端口的映射,然后根据映射规则,映射到内网的3232端口。到这里,RTP语音流正式开通。双方通话结束后,防火墙自动删除这个端口映射策略。
如果是内网用户呼叫外网用户,防火墙的映射机制基本上是相同的。不同的是,内网用户对外网用户发起呼叫时,内网终端通知防火墙此终端准备接收RTP的具体端口,防火墙然后根据这个端口映射一个新端口,并且修改SDP的RTP端口,最后发送给外网的终端。外网终端则根据这个端口发送RTP语音,防火墙接收到这个端口的RTP流返回到原来的终端端口。如果通话结束,最后,防火墙删除映射端口匹配设置。
通过以上示例我们可以看到,事实上,ALG仅对Via, Conatct 这些值域进行了修改,实现一个转译,支持了SDP payload。但是ALG目前不支持对多IP地址广播,加密的SDP,SIP TLS和IP V6等其他功能。所以,严格意义来说,ALG仍然很难满足SIP多种业务的需求。
ICE
ICE(交互式连接建立),用于探测双方的连通性。STUN的目的是为了进行P2P通信,通过提供反射地址(Server Reflexive Address)这种能力来使双方可以进行P2P通信,但是依赖NAT类型的不同,这种方式是有失败的概率的:比如双方都为对称型NAT或者一方为对称型,另一方为端口限制型。
因为有失败的可能性,所以单纯的依赖STUN协议提供的反射地址的话,需要事先探测出双方的NAT类型,假如发现是对称型的NAT,那么就不打洞了,而是直接中转。目前网络类型纷繁复杂,STUN协议在5389的时候去掉了NAT类型的判断的能力,因为越来越多的实践发现,在多层NAT下,类型的探测不总是有效的。而使用ICE的时候,不需要事先探测NAT类型。
STUN还有一个作用是为ICE提供支持(对Binding的扩展)。
TURN协议的目的是为了保证通信双方百分之百能进行通信,就是在只知道反射地址而打洞失败的情况下的一种补充方案:使用中继,使用中继方式百分之百能使得双方进行通信,只不过已经不是P2P的了,而且伴随而来的是转发效率的问题。不过这不要紧,因为该协议的目的就是保证双方肯定能通信,损失效率来保证了连同性。
ICE协议的目的就是综合以上两种方案,通过通信双方互相发探测包,找出一种最合理,最廉价的可行路径。ICE首先探测内网地址,再探测STUN提供的反射地址,最后探测TURN协议的中继地址,反正最终目的就是探出一条路,内网地址不行用反射地址,反射地址不行,最后不得已情况下那就用中继地址。
一般来说,目前的TURN服务器通常也实现了STUN协议,所以可以称之为TURN服务器或者是STUN 服务器。
如果说一个服务器是STUN服务器,那么该服务器可能是纯的STUN(RFC 5389)服务器,也可能是一个TURN(RFC 5766)服务器,也可能是两者都实现了的服务器。本文以下图中所说的STUN服务器,均为实现了STUN和TURN的服务器。
Media Proxy
Media Proxy的目的是通过一个Proxy的二次转发机制,重新让双方终端通过Media Proxy进行通信。UA2就可以对UA1发起呼叫请求,需要Media Proxy处理一些proxy所承担的工作:
Media Proxy需要重写SDP中的RTP/AVP值域,重新把RTP语音流指向媒体服务器需要的端口地址。
当对发起呼叫方SIP终端发送消息时,Media Proxy同时需要发送重写的RTP/AVP值域,保证RTP端口能够发送到正确的RTP端口。
在防火墙的端口策略设置中,所使用的端口需要一直仅对Media proxy开放。这样就可以限定部分端口开放给Media Proxy,无需完全开放所有RTP端口。
结尾
综上,我们讨论了几个主要的NAT解决方案,UPnP、ALG、ICE和Media Proxy。通过我们的讨论,我们可以发现,事实上,这些解决方案都有非常强的针对性,同时也具有非常多的局限性。用户需要做更多的调研,找到适合自己需求的解决方案。在本次的讨论中,我们仅讨论了SIP和RTP的互联互通,基本上都是实现了SIP对NAT的简单功能实现,这些技术解决方案事实上并没有真正解决SIP在公网的业务兼容性问题,安全管理问题,公司网络和运营商网络之间的问题。
========= End