NAT和NAT穿透介绍

来源:互联网 发布:virtualbox ubuntu 卡 编辑:程序博客网 时间:2024/05/22 00:10

NAT和NAT穿透介绍

本文描述NAT和它带来的一些问题以及相应的解决方案。

NAT介绍

NAT(Network Address Translation)是一种机制,采用这种机制的设备通过改变一个包内的IP地址和端口,把一个域内的IP地址映射为另一个域的IP地址(通常是把一个私有地址映射为一个公网地址,反之亦然)。NAT设备所做的工作包括:在NAT的公网侧分配一个临时的端口号并通过该端口号把来自内部主机的包发送到Internet上,维持这个映射一段预先定义好的时间,把该端口从Internet上收到的包转发给内部主机。

安装NAT设备主要是为了解决IPv4地址耗尽的问题,这是通过多个主机共享一个公网/Internet地址来实现的。由于它的映射性质(例如:映射只能有内部主机发起的连接创建),当IPv4地址不是问题的时候,我们也喜欢使用NAT设备(例如家里只有一台主机的情况下),这可以保护内部主机免受某些来自外部网络的攻击。

尽管NAT为内部网络提供了一些保护,但我们要明白,NAT和防火墙不是一回事。NAT不是一个防火墙。防火墙是一个安全解决方案,被设计来加强一个组织的安全策略。而NAT是一个连通性解决方案,它允许多台主机共享一个单独的公网IP地址。可以理解的是两个功能有时很难分开,因为许多产品声称在同一个设备中实现了这两个功能,而且简单的把这种设备标识为“NAT Box”。但是我们想要把这种区别弄的很清楚,因为PJNATH是一个NAT穿透协助方案,而不是一个防火墙旁路解决方案。

NAT 穿透问题

对于典型的C/S应用(像web和email),NAT工作得很好,因为总是客户端初始化对话而且客户端一般也没有必要长时间保持这样的连接。然而NAT的安装给P2P通信造成了严重的问题,特别是像VoIP这类应用。下面详细解释这些问题。

对端地址问题(Peer Address Problem)

在VoIP应用中,我们想要媒体(声音、视频)直接在两个客户端流动。因为转播是代价昂贵的(服务提供者带宽成本、转播所引入的额外延迟)。为了建立直接的连接,每一个客户端通过VoIP的信号通道,把它的媒体传输地址告诉另一个客户端,之后另一端就把它的媒体发送到该地址。

问题就在这里。如果客户端软件不是NAT感知的,它将把它的私有地址发送给对方,当然另一个客户端没法把媒体发送到这个地址。

解决这个问题的传统方法是使用STUN。在这种机制中,客户端首先通过咨询STUN服务器了解到它的公网地址/端口,然后发送这个公网地址而不是它的私有地址到另一个客户端。当两端都使用这种机制时,它们就能够发送媒体包到这些地址(各自的公网地址),从而在NAT上创建了一个映射(也叫做开了一个“洞”,因而这种机制的被普遍称为“打洞”),然后两个客户端就可以相互通信了。

但是这种机制并不是在所有情况下都可以工作,下面将做解释。

Hairpinning behavior

Haripin是这样一种行为,NAT设备把来自内部网络中的某台主机(假设为主机A)的数据包转播回到同一网络中的某台主机(假设为主机B),这种情况下NAT检测到包的目的地址实际上是为内部主机(主机B)创建的一个映射地址。这是一个NAT想要的行为,但不幸的是不是所有的NAT设备都支持这种行为。

在没有这样的行为情况下,如果两个处于同一个NAT之后的内部主机交换了它们的公网地址,它们就不能互相通信。

 

对称行为(Symmetric behavior)

NAT的行为并不统一,人们一直以来尝试着根据它们的行为把它们分为不同的类别。根据RFC 3489第5部分所述,NAT设备的传统分类为:Full Cone(完全锥体)、Restricted Cone(受限锥体)、Port Restricted Cone(端口受限锥体)和Symmetric types(对称类型)。一种更新一些的分类方法(RFC 4787有解释),把NAT的行为类型划分两种属性:映射行为属性和过滤行为属性。每一个属性可以是这三种类型之一:Endpoint-Independent,Address-Dependent, or Address and Port-Dependent。按照这种新的分类方法,一个对称NAT实际上是一个地址和端口独立映射的NAT。

在这些类型中,对称类型是最难处理的。因为这种类型的NAT为本地主机与STUN服务器和其它主机的通信分配不同的映射,这就导致一台主机通知另一台的IP地址/端口对于接受者来说是没有意义的,因为实际上该地址不是NAT设备为这两者之间的通信分配的映射(通知另一台主机的地址通常是通过咨询STUN服务器获得的)。结果是,当接收主机试图发送数据包到该地址时,因为NAT设备认为该包的发送者不是一个能发送数据到该地址的“合法”主机,所以NAT就把这些包丢弃了。

对于这个问题,有两种解决方案。

第二种解决方案是使用媒体转播,但是正如上面提到的,转播是昂贵的,无论就服务提供者的带宽成本,还是转播引入的延迟来说。

绑定超时

当NAT设备创建一个绑定(一个公-私地址映射)时,它也为这个绑定分配一个定时器。一旦没有与该绑定相关的活动/流量,这个定时器就会被用来销毁该绑定。由于这个原因,一个想要保持该绑定的NAT感知的应用程序必须定期性的发送外出包(心跳包),一种称为保活的机制,否则它将最终失去这个绑定并且不能再收到Internet发来的数据。

 

NAT穿透方法

Old STUN (RFC 3489)

最初的STUN(Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)))方法由RFC3489(发布于2003年,然而该工作早在2001年就开始了)定义,该方法是一种独立的、基于标准的解决上述NAT 连通性问题的方法。为了穿透NAT,它装备了NAT类型检查算法和NAT打洞方法,该方法被证明可以成功的穿透多种类型的NAT,因此作为一种简单有效的NAT穿透方法,它已经被广泛应用。

但随后这些IETF的聪明人意识到光STUN是不够的。除了STUN解决方案不能处理对称型NAT和端口受限NAT的不足,人们还发现NAT的行为可能随着流量的改变而改变,因而据此推测NAT类型检测的结果并不那么可靠,所以不应该太依赖这个结果。

为了解决这个问题,STUN 不断努力,并提出了不同的策略。现在它不再试图提供一种独立的解决方案,而是部分解决方案和一个框架以在其上创建其它(基于STUN)的协议,比如TURN和ICE。

STUN/STUNbis (RFC 5389)

The Session Traversal Utilities for NAT (STUN)是Old STUN 的升级版。它仍然为客户端提供一种查询它到STUN服务器的公网/映射地址的机制,然而它舍弃了NAT类型检测,现在它被用作在其上创建其它协议的框架(例如TRUN和ICE)。

Old TURN (draft-rosenberg-midcom-turn)

Traversal Using Relay NAT (TURN),2001年11月开始的一个标准尝试,它是为了创建一个完整的解决方案而作为STUN方法的一个补充方法。最初的设想是使用STUN来检测NAT类型,当发现NAT是对称类型时,就用TURN来转播通信。但是如上面描述的,这种方法注定不可靠,现在使用TURN的首选方式是把它同ICE结合在一起使用。

TURN (draft-ietf-behave-turn)

Traversal Using Relays around NAT (TURN)是TURN的最新发展。很多协议细节发生变化,但目标仍然没有变,即为应用提供转播控制。如上所述,首选方式是,TURN应该与ICE一块使用,因为转播是昂贵的,它应该被作为最后的选择。

ICE解决方案 – 尽心尽责的协议

IETF正在标准化一个新的协议(it's in Work Group Last Call/WGLC stage at the time this article was written),即Interactive Connectivity Establishment (ICE, 交互式连通建立方式). ICE是一个客户端穿透NAT解决方法军械库中的终极武器,ICE承诺,如果在两个客户端之间确实存在一条通讯路径,那么它将找出这条路径。如果存在多条路径,那么ICE将找出最好的一条。ICE结合使用了多种协议(例如:STUN和TURN)并且提供多条候选通信路径(如果存在),因此使穿透成功率达到最大,同时它还有择优选择候选路径的能力,即最贵的可选路径(延迟最大)只有在其它路径都失败的情况下才会被使用。ICE协商过程包括几个阶段:

  • 候选者收集,这一阶段,客户端找出可用来通信的所有可能的地址。它可能找出三种类型的候选者:本地网络接口的地址和由它派生的其他所有地址服务器反向候选地址,转播地址。
  • 对候选地址进行排序。中继地址通常具有最低优先级,因为它最昂贵。
  • 把这些地址编码并发送到远程对等端
  •  配对这些候选地址,这一阶段,ICE把每一个本地候选地址同它从远程对等端收到的候选地址进行配对
  • 检测每个配对的连通性
  • 总结结果。因为每一条可能的路径都被检测过,所以如果存在可用的通信路径,ICE就能找到它。

ICE有许多优点:

  • 它是基于标准的
  • 在STUN可以工作的地方它都可以工作(在STUN不能工作的地方,它也可以工作)
  • 不像单独的STUN解决方案,ICE同时提供了主机候选地址,这解决了the hairpinning issue
  • 像转播解决方案一样,它也能应对对称型NAT。但它不像普通的转播方案,在ICE中,考虑到最小化带宽和转播延迟,转播只有在其它途径都失败的情况下才会使用。
  • 它提供了一个通用框架,用于提供和检查候选地址。ICE标准核心仅仅使用STUN和TURN,但实现者可以让ICE支持更多的协议,比如通过TCP或者HTTP来转播UDP,或者uPnP。
  • 它还添加了一些安全防护,特别是可以应对DoS攻击,因为媒体地址只有在被确认之后才能被使用。

不得不说,ICE是一个实现起来很复杂的协议,互操作性是个问题,在我们实现该协议的时候,有关它的实现并不多。幸运的是,PJNATH作为第一个比较成熟的ICE实现,于2007年中发布了。之后我们一直SIP Interoperability Test (SIPit)在定期测试我们的实现。因此,我们也希望这同时也是最稳定的ICE实现。

PJNATH – 有效的NAT穿透方案构建模块

PJSIP NAT Helper (PJNATH)是一个包含基于标准的NAT穿透解决方案实现的库。PJNATH可以作为一个独立的库被应用软件使用,或者你可以使用PJSUA-LIB库,PJSUA-LIB处于更高的层次,它把PJSIP, PJMEDIA, PJNATH集成在一起以使API更容易使用。

PJNATH 有如下功能:

  • STUNbis实现,它提供了可以使用的STUN感知socket和用于实现更高层次的基于STUN协议(TURN, ICE)的框架。
  • NAT类型检测,这对于故障诊断是很有用的。
  • TURN实现。
  •  ICE实现。

将来会实现更多协议。

 

原文地址:http://www.pjsip.org/pjnath/docs/html/group__nat__intro.htm

原创粉丝点击