NAT网络地址转换技术文集

来源:互联网 发布:淘宝分期付款额度500 编辑:程序博客网 时间:2024/04/28 15:25

NAT网络地址转换技术文集

NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IPInternet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。如图

 

 

 

 

 

 

 


     简单的说,NAT就是在局域网内部网络中使用内部地址,而当内部节点要与外部网络进行通讯时,就在网关(可以理解为出口,打个比方就像院子的门一样)处,将内部地址替换成公用地址,从而在外部公网(internet)上正常使用,NAT可以使多台计算机共享Internet连接,这一功能很好地解决了公共IP地址紧缺的问题。通过这种方法,您可以只申请一个合法IP地址,就把整个局域网中的计算机接入Internet中。这时,NAT屏蔽了内部网络,所有内部网计算机对于公共网络来说是不可见的,而内部网计算机用户通常不会意识到NAT的存在。如图2所示。这里提到的内部地址,是指在内部网络中分配给节点的私有IP地址,这个地址只能在内部网络中使用,不能被路由(一种网络技术,可以实现不同路径转发)。虽然内部地址可以随机挑选,但是通常使用的是下面的地址:10.0.0.0~10.255.255.255172.16.0.0~172.16.255.255192.168.0.0~192.168.255.255NAT将这些无法在互联网上使用的保留IP地址翻译成可以在互联网上使用的合法IP地址。而全局地址,是指合法的IP地址,它是由NIC(网络信息中心)或者ISP(网络服务提供商)分配的地址,对外代表一个或多个内部局部地址,是全球统一的可寻址的地址。

    NAT功能通常被集成到路由器、防火墙、ISDN路由器或者单独的NAT设备中。比如Cisco路由器中已经加入这一功能,网络管理员只需在路由器的IOS中设置NAT功能,就可以实现对内部网络的屏蔽。再比如防火墙将WEB Server的内部地址192.168.1.1映射为外部地址202.96.23.11,外部访问202.96.23.11地址实际上就是访问访问192.168.1.1。另外资金有限的小型企业来说,现在通过软件也可以实现这一功能。Windows 98 SEWindows 2000 都包含了这一功能。

    NAT技术类型

    NAT有三种类型:静态NAT(Static NAT)、动态地址NAT(Pooled NAT)、网络地址端口转换NAPTPortLevel NAT)。

    其中静态NAT设置起来最为简单和最容易实现的一种,内部网络中的每个主机都被永久映射成外部网络中的某个合法的地址。而动态地址NAT则是在外部网络中定义了一系列的合法地址,采用动态分配的方法映射到内部网络。NAPT则是把内部地址映射到外部网络的一个IP地址的不同端口上。根据不同的需要,三种NAT方案各有利弊。

    动态地址NAT只是转换IP地址,它为每一个内部的IP地址分配一个临时的外部IP地址,主要应用于拨号,对于频繁的远程联接也可以采用动态NAT。当远程用户联接上之后,动态地址NAT就会分配给他一个IP地址,用户断开时,这个IP地址就会被释放而留待以后使用。

    网络地址端口转换NAPTNetwork Address Port Translation)是人们比较熟悉的一种转换方式。NAPT普遍应用于接入设备中,它可以将中小型的网络隐藏在一个合法的IP地址后面。NAPT与动态地址NAT不同,它将内部连接映射到外部网络中的一个单独的IP地址上,同时在该地址上加上一个由NAT设备选定的TCP端口号。

    Internet中使用NAPT时,所有不同的信息流看起来好像来源于同一个IP地址。这个优点在小型办公室内非常实用,通过从ISP处申请的一个IP地址,将多个连接通过NAPT接入Internet。实际上,许多SOHO远程访问设备支持基于PPP的动态IP地址。这样,ISP甚至不需要支持NAPT,就可以做到多个内部IP地址共用一个外部IP地址上Internet,虽然这样会导致信道的一定拥塞,但考虑到节省的ISP上网费用和易管理的特点,用NAPT还是很值得的。

NAT的完全分析及其UDP穿透的完全解决方案

 

:基本术语

防火墙

防火墙限制了私网与公网的通信,它主要是将(防火墙)认为未经授权的的包丢弃,防火墙只是检验包的数据,并不修改数据包中的IP地址和TCP/UDP端口信息。

网络地址转换(NAT

当有数据包通过时,网络地址转换器不仅检查包的信息,还要将包头中的IP地址和端口信息进行修改。以使得处于NAT之后的机器共享几个仅有的公网IP地址(通常是一个)。网络地址转换器主要有两种类型.

P2P应用程序

P2P应用程序是指,在已有的一个公共服务器的基础上,并分别利用自己的私有地址或者公有地址(或者两者兼备)来建立一个端到端的会话通信。

P2P防火墙

P2P防火墙是一个提供了防火墙的功能的P2P代理,但是不进行地址转换.

P2P-NAT

P2P-NAT 是一个 P2P代理,提供了NAT的功能,也提供了防火墙的功能,一个最简的P2P代理必须具有锥形NATUdp通信支持的功能,并允许应用程序利用Udp打洞技术建立强健的P2P连接。

回环转换

NAT的私网内部机器想通过公共地址来访问同一台局域网内的机器的时,NAT设备等价于做了两次NAT的事情,在包到达目标机器之前,先将私有地址转换为公网地址,然后再将公网地址转换回私有地址。我们把具有上叙转换功能的NAT设备叫做回环转换设备。

 

:NAT分类

可以分为基础NAT网络地址和端口转换(NAPT)两大类

():基础NAT

基础NAT 将私网主机的私有IP地址转换成公网IP地址,但并不将TCP/UDP端口信息进行转换。基础NAT一般用在当NAT拥有很多公网IP地址的时候,它将公网IP地址与内部主机进行绑定,使得外部可以用公网IP地址访问内部主机。(实际上是只将IP转换,192.168.0.23 <-> 210.42.106.35,这与直接设置IP地址为公网IP还是有一定区别的,特别是对于企业来说,外部的信息都要经过统一防火墙才能到达内部,但是内部主机又可以使用公网IP

():网络地址和端口转换 NAPT

这是最普遍的情况,网络地址/端口转换器检查、修改包的IP地址和TCP/UDP端口信息,这样,更多的内部主机就可以同时使用一个公网IP地址。

请参考[RFC1631][RFC2993][RFC2663]这三个文档了解更多的NAT分类和术语信息。另外,关于NAPT的分类和术语,[RFC2663]做了更多的定义。当一个内部网主机通过NAT打开一个外出TCPUDP会话时,NAPT分配给这个会话一个公网IP和端口,用来接收外网的响应的数据包,并经过转换通知内部网的主机。这样做的效果是,NAPT [私有IP:私有端口] [公网IP:公网端口]之间建立了一个端口绑定。

端口绑定指定了NAPT将在这个会话的生存期内进行地址转换任务。这中间存在一个这样的问题,如果P2P应用程序从内部网络的一个[私有IP地址:端口]对同时发出多条会话给不同的外网主机,那么NAT会怎样处理呢?这又可以分为锥形NAT (CONE NAT)对称NAT (SYMMTRIC NAT)两大类来考虑:

A.锥形NAT

(为什么叫做锥形呢?请看以下图形,终端和外部服务器,都通过NAT分派的这个绑定地址对来传送信息,就象一个漏斗一样,筛选并传递信息)

                               

  当建立了一个 [私有IP:端口]-[公网IP:端口] 端口绑定之后,对于来自同一个[私有IP:端口]会话,锥形NAT服务器允许发起会话的应用程序 重复使用这个端口绑定,一直到这个会话结束才解除(端口绑定)。

  例如,假设 Client AIP地址信息如上图所示)通过一个锥形NAT 同时发起两个外出的连接,它使用同一个内部端口(10.0.0.1:1234)给公网的两台不同的服务器,S1S2。锥形NAT 只分配一个公网IP和端口(155.99.25.11:62000)给这个两个会话,通过地址转换可以确保 Client使用端口的同一性(即这个Client只使用这个端口)。而基础NATs和防火墙却不能修改经过的数据包端口号,它们可以看作是锥形NAT的精简版本。

进一步分析可以将CONE NAT受限制锥形NAT (RESTRICT CONE) 端口受限锥形NAT (PORT RESTRICT CONE) 三大类,以下是详细论述: 分为全双工锥形NAT (FULL CONE) ,

1.全双工锥形NAT

当内部主机发出一个外出的连接会话,就会创建了一个公网/私网 地址,一旦这个地址对被创建,全双工锥形NAT会接收随后任何外部端口传入这个公共端口地址的通信。因此,全双工锥形NAT有时候又被称为"混杂"NAT

2.受限制锥形NAT

受限制的锥形NAT会对传入的数据包进行筛选,当内部主机发出外出的会话时,NAT会记录这个外部主机的IP地址信息,所以,也只有这些有记录的外部IP地址,能够将信息传入到NAT内部,受限制的锥形NAT 有效的给防火墙提炼了筛选包的原则——即限定只给那些已知的外部地址传入信息到NAT内部。

3.端口受限锥形NAT

端口受限制的锥形NAT,与受限制的锥形NAT不同的是:它同时记录了外部主机的IP地址和端口信息,端口受限制的锥形NAT给内部节点提供了同一级别的保护,在维持端口同一性过程中,将会丢弃对称NAT传回的信息。

B.对称NAT

对称NAT,与Cone NAT是大不相同的,并不对会话进行端口绑定,而是分配一个全新的公网端口 给每一个新的会话。

还是上面那个例子:如果 Client A (10.0.0.1:1234)同时发起两个 "外出" 会话,分别发往S1S2。对称Nat会分配公共地址155.99.25.11:62000Session1,然后分配另一个不同的公共地址155.99.25.11:62001Session2。对称Nat能够区别两个不同的会话并进行地址转换,因为在 Session1 Session2中的外部地址是不同的,正是因为这样,Client端的应用程序就迷失在这个地址转换边界线了,因为这个应用程序每发出一个会话都会使用一个新的端口,无法保障只使用同一个端口了。

TCPUDP通信中,(到底是使用同一个端口,还是分配不同的端口给同一个应用程序),锥形NAT和对称NAT各有各的理由。当然锥形NAT在根据如何公平地将NAT接受的连接直达一个已创建的地址对上有更多的分类。这个分类一般应用在Udp通信(而不是Tcp通信上),因为NATs和防火墙阻止了试图无条件传入的TCP连接,除非明确设置NAT不这样做。

:NATsession的处理

以下分析NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session.主要有一下几个策略:

A. 源地址(内网IP地址)不同,忽略其它因素, NAPT上肯定对应不同的Session

B. 源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session

C. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)相同,目的端口不同,则在NAPT上肯定对应同一个Session

D. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)不同,忽略目的端口,则在NAPT上是如何处理Session的呢?

A,B,C三种情况的都是比较简单的,可以很容易的实现.D的情况就比较复杂了.所以D情况才是我们要重点关心和讨论的问题。

:完全解决方案

以下针对四种SESSION与四种NAT的完全解决方案,为了方便将使用以下缩写形式:

C代表 CONE NAT

S代表SYMMETRIC NAT,

FC代表 FULL CONE NAT,

RC代表 RESTRICT CONE NAT,

PC 代表 PORT RESTRICT CONE NAT.

首先依据CLIENT (客户)端在NAT 的个数不同可以分为两大类:

TYPE ONE :一个在NAT + 一个在公网中.

这种情况下可以分为两大类:

A. S VS 公网:此种情况下,由于公网的地址在一个SESSION内是不变的,所以可以打洞是可以成功的.

B. C VS 公网: 与上面类似,这种情口下打洞是可以成功的.

TYPE TWO:两个客户都在NAT后面.

这种情况下也可以细分为两大类:

A. 其中一个NAT S(SYMMETRIC NAT) ,:S VS C或者是S VS S .

下面论证这种情口下按照常规打洞是行不通的,在常规打洞中,所有的客户首先登陆到一个服务器上去.服务器记录下每个客户的[公网IP:端口],然后在打洞过程中就使用这个记录的值,然而对于SNAT来说,它并不绑定[私网IP:端口][公网IP:端口]的映射.所以在不同的SESSION,NAT将会重新分配一对[公网IP:端口].这样一来对S型的NAT来说打洞的[公网IP:端口]与登记在服务器上的[公网IP:端口]是不同的.而且也没有办法将打洞的[公网IP:端口]通知到另一个位于NAT下的客户端, 所以打洞是不会成功的.然而如果另一个客户端是在公网,打洞是可以的.前面已经论证了这种情况.

这种情况下的解决方案是只能通过端口预测来进行打洞,具体解决方法如下:例如(以两个都是S型的为例) NAT A 分配了它自己的UDP端口62000用来保持 客户端A 与服务器S的通信会话 NAT B 也分配了31000端口用来保持客户端B服务器S 的通信会话通过与 服务器S的对话客户端A 客户端B都相互知道了对方所映射的真实IP和端口

  客户端A发送一条UDP消息到138.76.29.7:31001(请注意到端口号的增加)同时客户端B发送一条UDP消息到155.99.25.11:62001如果NAT A NAT B继续分配端口给新的会话,并且从A-SB-S的会话时间消耗得并不多的话,那么一条处于客户端A和客户端B之间的双向会话通道就建立了。

  客户端A发出的消息送达B导致了NAT A打开了一个新的会话,并且我们希望NAT A将会指派62001端口给这个新的会话,因为62001是继62000NAT会自动指派给 从服务器S到客户端A之间的新会话的端口号;类似的,客户端B发出的消息送达A导致了 NAT B打开了一个新的会话,并且我们希望 NAT B将会指派31001这个端口给新的会话;如果两个客户端都正确的猜测到了对方新会话被指派的端口号,那么这个 客户端A-客户端B的双向连接就被打通了。其结果如下图所示:

明显的,有许多因素会导致这个方法失败:如果这个预言的新端口(6200131001 恰好已经被一个不相关的会话所使用,那么NAT就会跳过这个端口号,这个连接就会宣告失败;如果两个NAT有时或者总是不按照顺序来生成新的端口号,那么这个方法也是行不通的

如果隐藏在NATA后的一个不同的客户端X(或者在NAT B后)打开了一个新的外出”UDP 连接,并且无论这个连接的目的如何;只要这个动作发生在客户端A 建立了与服务器S的连接之后客户端A 客户端B 建立连接之前;那么这个无关的客户端X 就会趁人不备地” 到这个我们渴望分配的端口。所以,这个方法变得如此脆弱而且不堪一击,只要任何一个NAT方包含以上碰到的问题,这个方法都不会奏效。

在处于 cone NAT 系列的网络环境中这个方法还是实用的;如果有一方为 cone NAT 而另外一方为 symmetric NAT,那么应用程序就应该预先发现另外一方的 NAT 是什么类型,再做出正确的行为来处理通信,这样就增大了算法的复杂度,并且降低了在真实网络环境中的普适性。

    最后,如果P2P的一方处在两级或者两级以上的NAT下面,并且这些NATS 接近这个客户端是SYMMETRIC NAT的话,端口号预言是无效的!

因此,并不推荐使用这个方法来写新的P2P应用程序,这也是历史的经验和教训!

B. 两个都是CONE NAT.

这种情况下可以分为六大类型:

A: FC + FC

B: FC + RC

C: FC + PC

D: PC + RC

E: PC + PC

F: RC + RC

虽然有这么多种情况,但是由于CONE NAT 的特性,所以还是很好办的,因为对于CONE NAT 来说,在同一个SESSION中它会绑定一对[私网IP:端口][公网IP:端口]的映射,所以它们打洞用的[公网IP:端口]与登记在服务器上的[公网IP:端口]是一致的,所以打洞是可以行的通的.

综上所述,就已经完全的概括了所有类型的NAT之间的可能的通信情况了.并且都提供了可行的解决方案.

:对前一阶段的总结

1.前一阶段使用的打洞方法是有缺陷的,它只适应于两个都是FULL CONE NAT的类型的CLIENT(客户端).以下论证它不适应于两个都是CONE NAT的类型中的

B: FC + RC

C: FC + PC

D: PC + RC

E: PC + PC

F: RC + RC

这五种情况.

因为对于受限的NAT它登记了外出包的[IP地址&端口],它仅仅接受这些已登记地址发过来的包,所以它们报告服务器的端口只能接受来自服务器的包.不能接受来自另一客户端的包.所以前一阶段的打洞方法是不可行的.

: 存在的问题

按照理论.NAT将在一定时间后关闭UDP的一个映射,所以为了保持与服务器能够一直通信,服务器必须要发送UDP心跳包,来保持映射不被关闭.这就需要一个合适的时间值.

一种能比较准确地猜测NAT的影射端口的方法

昨晚忽然想到一种方法能比较准确地猜测NAT的影射端口。我指的是那种目标端口敏感的NAT,这种NAT以前是很难穿透的。
   
这种方法使用了三个新socket(也即新的本地端口)来探测 。新建三个socket,每个socket与以前没用过的端口 绑定。然后按时间顺序,第一个socketstun服务器发送 数据包,第二个socket给目标服务器发送数据包 ,也即执行打孔动作,第三个socket再次给stun服务器发送 数据。三个动作均会在服务器上新开一个影射端口 。三个动作时间间隔很短,大约100ms即可。这样,我们有理由相信,第二个socket 分配的映射端口很可能在第一个影射端口和第二个影射端口之间。也即port2>port1同时 port2<port3。可能性最大的是:
port2 = (port1+port3)/2
   
如果服务器发现port3<port1,或者port1por t3之间差距过大,那么很可能是NAT上的端口号已经开始重新分 配,那么应当让客户端重复一下这个流程。重复多几次 ,猜测成功的几率会大很多。
   
一个例外情况是所谓端口保持NAT,也即NAT分配新端口时 ,尽量使新端口号与内网端口号保持一致。但这种情况很容易识别 ,服务器简单比较客户端的内网端口和映射端口即可 。如果发现是这类NAT,那么上面的公式就要修改了:
port2 =
第二个socket的内网端口号
  
当然,端口猜测方法无论如何也是猜测而已,内网之间的用户仍然不可能有100%的连结率。但是猜测端口的方法可 以提高跨NAT连接率,从而降低数据中转服务器的负担。

NAT冲突解决

内网计算机IP172.29.26.30:;59999NAT路由器IP地址为202.102.154.3:60000,外部视频服务器IP地址为60.212.212.23:59999

服务器开设两个线程:监听线程和数据发送线程

监听线程用于登记客户端地址,包括IP地址和端口号,然后调用AddDestination(),加入到发送线程的回话目的端链表。其监听端口设为80000;          

数据发送线程用于发送rtp数据和rtcp数据包。Rtp回话创建于60000端口,在rtpsock邦定端口60000rtcp邦定端口60001,由昨天得知sendsock必须邦定端口,修改rtp库,使其邦定端口59999

内网计算机程序,也就是客户端程序rtp回话创建于端口60000,取出其rtpsock(该端口邦定60000端口,负责接收rtp数据包)。向服务器80000端口发送请求,这代表服务器80000端口发送数据到内网计算机60000端口的通路打开,服务器取得客户端地址,写入目标地址链表。由于客户端是要接收到服务器59999端口发来的数据,于是rtpsock发送数据到服务器的59999端口,此时服务器59999端口发送数据到客户端60000端口的数据打通。这样便可以正确的传送和接收rtp数据包。

但是这时候接收不到rtcp数据包,原因是因为服务器59999端口发送到客户端60001端口的通路没有打通。利用同样的方式既可。

 

 

 

 
原创粉丝点击