公有IP地址:也叫全局地址,是指合法的IP地址,它是由NIC(网络信息中心)或者ISP(网络服务提供商)分配的地址,对外代表一个或多个内部局部地址,是全球统一的可寻 址的地址。
私有IP地址:也叫内部地址,属于非注册地址,专门为组织机构内部使用。因特网分配编号委员会(IANA)保留了3块IP地址做为私有IP地址:
10.0.0.0 ——— 10.255.255.255
172.16.0.0——— 172.16.255.255
192.168.0.0———192.168.255.255
地址池:地址池是有一些外部地址(全球唯一的IP地址)组合而成,我们称这样的一个地址集合为地址池。在内部网络的数据包通过地址转换到达外部网络时,将会在地址池中选择某个IP地址作为数据包的源IP地址,这样可以有效的利用用户的外部地址,提高访问外部网络的能力。
NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术,如下图所示。因此我们可以认为,NAT在一定程度上,能够有效的解决公网地址不足的问题。
简单地说,NAT就是在局域网内部网络中使用内部地址,而当内部节点要与外部网络进行通讯时,就在网关(可以理解为出口,打个比方就像院子的门一样)处,将内部地址替换成公用地址,从而在外部公网(internet)上正常使用,NAT可以使多台计算机共享Internet连接,这一功能很好地解决了公共 IP地址紧缺的问题。通过这种方法,可以只申请一个合法IP地址,就把整个局域网中的计算机接入Internet中。这时,NAT屏蔽了内部网络,所有内部网计算机对于公共网络来说是不可见的,而内部网计算机用户通常不会意识到NAT的存在。如下图所示。这里提到的内部地址,是指在内部网络中分配给节点的私有IP地址,这个地址只能在内部网络中使用,不能被路由转发。
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 SE、Windows 2000 都包含了这一功能。
NAT有三种类型:静态NAT(Static NAT)、动态地址NAT(Pooled NAT)、网络地址端口转换NAPT(Port-Level NAT)。
通过手动设置,使 Internet 客户进行的通信能够映射到某个特定的私有网络地址和端口。如果想让连接在 Internet 上的计算机能够使用某个私有网络上的服务器(如网站服务器)以及应用程序(如游戏),那么静态映射是必需的。静态映射不会从 NAT 转换表中删除。
如果在 NAT 转换表中存在某个映射,那么 NAT 只是单向地从 Internet 向私有网络传送数据。这样,NAT 就为连接到私有网络部分的计算机提供了某种程度的保护。但是,如果考虑到 Internet 的安全性,NAT 就要配合全功能的防火墙一起使用。
对于以上网络拓扑图,当内网主机 10.1.1.1如果要与外网的主机201.0.0.11通信时,主机(IP:10.1.1.1)的数据包经过路由器时,路由器通过查找NAT table 将IP数据包的源IP地址(10.1.1.1)改成与之对应的全局IP地址(201.0.0.1),而目标IP地址201.0.0.11保持不变,这样,数据包就能到达201.0.0.11。而当主机HostB(IP:201.0.0.11) 响应的数据包到达与内网相连接的路由器时,路由器同样查找NAT table,将IP数据包的目的IP 地址改成10.1.1.1,这样内网主机就能接收到外网主机发过来的数据包。在静态NAT方式中,内部的IP地址与公有IP地址是一种一一对应的映射关系,所以,采用这种方式的前提是,机构能够申请到足够多的全局IP地址。
动态地址NAT只是转换IP地址,它为每一个内部的IP地址分配一个临时的外部IP地址,主要应用于拨号,对于频繁的远程联接也可以采用动态NAT。当远程用户联接上之后,动态地址NAT就会分配给他一个IP地址,用户断开时,这个IP地址就会被释放而留待以后使用。
动态NAT方式适合于 当机构申请到的全局IP地址较少,而内部网络主机较多的情况。内网主机IP与全局IP地址是多对一的关系。当数据包进出内网时,具有NAT功能的设备对IP数据包的处理与静态NAT的一样,只是NAT table表中的记录是动态的,若内网主机在一定时间内没有和外部网络通信,有关它的IP地址映射关系将会被删除,并且会把该全局IP地址分配给新的IP数据包使用,形成新的NAT table映射记录。
网络地址端口转换NAPT(Network Address Port Translation)则是把内部地址映射到外部网络的一个IP地址的不同端口上。它可以将中小型的网络隐藏在一个合法的IP地址后面。NAPT与 动态地址NAT不同,它将内部连接映射到外部网络中的一个单独的IP地址上,同时在该地址上加上一个由NAT设备选定的端口号。
NAPT是使用最普遍的一种转换方式,它又包含两种转换方式:SNAT和DNAT。
(1)源NAT(Source NAT,SNAT):修改数据包的源地址。源NAT改变第一个数据包的来源地址,它永远会在数据包发送到网络之前完成,数据包伪装就是一具SNAT的例子。
(2)目的NAT(Destination NAT,DNAT):修改数据包的目的地址。Destination NAT刚好与SNAT相反,它是改变第一个数据包的目的地地址,如平衡负载、端口转发和透明代理就是属于DNAT。
源NAT举例:对于以上网络拓扑图,内网的主机数量比较多,但是该组织只有一个合法的IP地址,当内网主机(10.1.1.3)往外发送数据包时,则需要修改数据包的IP地址和TCP/UDP端口号,例如将
源IP:10.1.1.3
源port:1493
改成
源IP:201.0.0.1
源port:1492(注意:源端口号可以与原来的一样也可以不一样)
当外网主机(201.0.0.11)响应内网主机(10.1.1.3)时,应将:
目的IP:201.0.0.1
目的port:1492
改成
目的IP:10.1.1.3
目的port:1493
这样,通过修改IP地址和端口的方法就可以使内网中所有的主机都能访问外网,此类NAT适用于组织或机构内只有一个合法的IP地址的情况,也是动态NAT的一种特例。
目的NAT举例:这种方式适用于内网的某些服务器需要为外网提供某些服务的情况。
例如以上拓扑结构,内网服务器群(ip地址分别为:10.1.1.1,10.1.1.2,10.1.1.3等)需要为外网提供WEB 服务,当外网主机HostB访问内网时,所发送的数据包的目的IP地址为10.1.1.127,端口号为:80,当该数据包到达内网连接的路由器时,路由器查找NAT table,路由器通过修改目的IP地址和端口号,将外网的数据包平均发送到不同的主机上(10.1.1.1,10.1.1.2,10.1.1.3等),这样就实现了负载均衡。
1.3 NAT实现方式
1.3.1 全锥NAT(Full Cone NAT)
一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。任意外部主机都能通过给eAddr:port2发包到达iAddr:port1。
1.3.2 限制性锥NAT(Address-Restricted Cone NAT)
一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。任意外部主机(hostAddr:any)都能通过给eAddr:port2发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:any。 "any"也就是说端口不受限制。
1.3.3 端口限制性锥NAT(Port Restricted Cone NAT)
端口限制性锥NAT与限制性锥NAT类似,只是多了端口号的限制。
一旦一个内部地址(iAddr:port1)映射到外部地址(eAddr:port2),所有发自iAddr:port1的包都经由eAddr:port2向外发送。一个外部主机(hostAddr:port3)能够发包到达iAddr:port1的前提是:iAddr:port1之前发送过包到hostAddr:port3.
1.3.4 对称NAT(Symmetric NAT)
NAT的基本工作原理是,当私有网主机和公共网主机通信的IP包经过NAT网关时,将IP包中的源IP或目的IP在私有IP和NAT的公共IP之间进行转换。
如下图所示,NAT网关有2个网络端口,其中公共网络端口的IP地址是统一分配的公共 IP,为202.20.65.5;私有网络端口的IP地址是保留地址为192.168.1.1。私有网中的主机192.168.1.2向公共网中的主机202.20.65.4发送了1个IP包(Dst=202.20.65.4,Src=192.168.1.2)。
当IP包经过NAT网关时,NAT Gateway会将IP包的源IP转换为NAT Gateway的公共IP并转发到公共网,此时IP包(Dst=202.20.65.4,Src=202.20.65.5)中已经不含任何私有网IP的信息。由于IP包的源IP已经被转换成NAT Gateway的公共IP,Web Server发出的响应IP包(Dst= 202.20.65.5,Src=202.20.65.4)将被发送到NAT Gateway。
这时,NAT Gateway会将IP包的目的IP转换成私有网中主机的IP,然后将IP包(Des=192.168.1.2,Src=202.20.65.4)转发到私有网。对于通信双方而言,这种地址的转换过程是完全透明的。转换示意图如下。
如果内网主机发出的请求包未经过NAT,那么当Web Server收到请求包,回复的响应包中的目的地址就是私有网络IP地址,在Internet上无法正确送达,导致连接失败。
在上述过程中,NAT Gateway在收到响应包后,就需要判断将数据包转发给谁。此时如果子网内仅有少量客户机,可以用静态NAT手工指定;但如果内网有多台客户机,并且各自访问不同网站,这时候就需要连接跟踪(connection track)。如下图所示:
在NAT Gateway收到客户机发来的请求包后,做源地址转换,并且将该连接记录保存下来,当NAT Gateway收到服务器来的响应包后,查找Track Table,确定转发目标,做目的地址转换,转发给客户机。
以上述客户机访问服务器为例,当仅有一台客户机访问服务器时,NAT Gateway只须更改数据包的源IP或目的IP即可正常通讯。但是如果Client A和Client B同时访问Web Server,那么当NAT Gateway收到响应包的时候,就无法判断将数据包转发给哪台客户机,如下图所示。
此时,NAT Gateway会在Connection Track中加入端口信息加以区分。如果两客户机访问同一服务器的源端口不同,那么在Track Table里加入端口信息即可区分,如果源端口正好相同,那么在实行SNAT和DNAT的同时对源端口也要做相应的转换,如下图所示。
NAT主要可以实现以下几个功能:数据包伪装、平衡负载、端口转发和透明代理。
数据伪装: 可以将内网数据包中的地址信息更改成统一的对外地址信息,不让内网主机直接暴露在因特网上,保证内网主机的安全。同时,该功能也常用来实现共享上网。例如,内网主机访问外网时,为了隐藏内网拓扑结构,使用全局地址替换私有地址。
端口转发: 当内网主机对外提供服务时,由于使用的是内部私有IP地址,外网无法直接访问。因此,需要在网关上进行端口转发,将特定服务的数据包转发给内网主机。例如公司小王在自己的服务器上架设了一个Web网站,他的IP地址为192.168.0.5,使用默认端口80,现在他想让局域网外的用户也能直接访问他的Web站点。利用NAT即可很轻松的解决这个问题,服务器的IP地址为210.59.120.89,那么为小王分配一个端口,例如81,即所有访问210.59.120.89:81的请求都自动转向192.168.0.5:80,而且这个过程对用户来说是透明的。
负载平衡:目的地址转换NAT可以重定向一些服务器的连接到其他随机选定的服务器。例如1.2.3所讲的目的NAT的例子。
失效终结:目的地址转换NAT可以用来提供高可靠性的服务。如果一个系统有一台通过路由器访问的关键服务器,一旦路由器检测到该服务器当机,它可以使用目的地址转换NAT透明的把连接转移到一个备份服务器上,提高系统的可靠性。
透明代理:例如自己架设的服务器空间不足,需要将某些链接指向存在另外一台服务器的空间;或者某台计算机上没有安装IIS服务,但是却想让网友访问该台计算机上的内容,这个时候利用IIS的Web站点重定向即可轻松的帮助我们搞定。
NAT在最开始的时候是非常完美的,但随着网络的发展,各种新的应用层出不穷,此时NAT也暴露出了缺点。NAT的缺陷主要表现在以下几方面:
(1) 不能处理嵌入式IP地址或端口
NAT设备不能翻译那些嵌入到应用数据部分的IP地址或端口信息,它只能翻译那种正常位于IP首部中的地址信息和位于TCP/UDP首部中的端口信息。如下图,由于对方会使用接收到的数据包中应用数据部分嵌入的地址和端口进行通信(比如FTP协议),这样就可能产生连接故障,如果通信双方都是使用的公网IP,这不会造成什么问题,但如果那个嵌入式地址和端口是内网的,显然连接就不可能成功,原因就如开篇所说的一样。MSN Messenger的部分功能就使用了这种方式来传递IP和端口信息,这样就导致了NAT设备后的客户端网络应用程序出现连接故障。
一些NAT服务为了适应更多的场景,提供了对多种协议的适配,比如支持FTP、SCTP、IMCP、DNS等等,这种技术称为ALG(Application Level Gateway),即在应用层对IP和端口做一定的抽取工作,并生成NAT映射表记录。但这些也大大增加了NAT的复杂度,特别是自定义协议的情况下,要考虑较复杂的机制来穿透NAT。
(2) 不能从公网访问内部网络服务
由于内网是私有IP,所以不能直接从公网访问内部网络服务,比如WEB服务,对于这个问题,我们可以采用建立静态映射的方法来解决。比如有一条静态映射,是把218.70.201.185:80与192.168.0.88:80映射起的,当公网用户要访问内部WEB服务器时,它就首先连接到218.70.201.185:80,然后NAT设备把请求传给192.168.0.88:80,192.168.0.88把响应返回NAT设备,再由NAT设备传给公网访问用户。
(3) 有一些应用程序虽然是用A端口发送数据的,但却要用B端口进行接收,不过NAT设备翻译时却不知道这一点,它仍然建立一条针对A端口的映射,结果对方响应的数据要传给B端口时,NAT设备却找不到相关映射条目而会丢弃数据包。
(4) 一些P2P应用在NAT后无法进行
对于那些没有中间服务器的纯P2P应用(如电视会议,娱乐等)来说,如果大家都位于NAT设备之后,双方是无法建立连接的。因为没有中间服务器的中转,NAT设备后的P2P程序在NAT设备上是不会有映射条目的,也就是说对方是不能向你发起一个连接的。现在已经有一种叫做P2P NAT穿越的技术来解决这个问题。
(5) NAT设备对数据包进行编辑和修改操作,降低了发送数据的效率;而且由于增加了技术的复杂性,排错也变得困难了。
通常情况下,当进程使用UDP 和外部主机通信时,NAT 会建立一个Session ,这个Session 能够保留多久并没有标准,或许几秒,几分钟,几个小时。假设ClientA-1 在应用程序中看到了ClientB-1 在线,并且想和ClientB-1 通信,一种办法是Server 作为中间人,负责转发ClientA-1 和ClientB-1 之间的消息,但是这样服务器太累,会吃不消。另一种方法就是让ClientA-1 何ClientB-1 建立端到端的连接,然后他们自己通信。这也就是P2P 连接。根据不同类型的NAT ,下面分别讲解。
(1 )全锥NAT ,穿透全锥型NAT 很容易,根本称不上穿透,因为全锥型NAT 将内部主机的映射到确定的地址,不会阻止从外部发送的连接请求,所以可以不用任何辅助手段就可以建立连接。5.3 使用TCP 穿透NAT
使用TCP 协议穿透NAT 的方式和使用UDP 协议穿透NAT 的方式几乎一样,没有什么本质上的区别,只是将无连接的UDP 变成了面向连接的TCP 。值得注意是:
1. ClientB-1 在向ClientA-1 打孔时,发送的SYN 数据包,而且同样会被NAT-A 丢弃。同时,ClientB-1 需要在原来的socket 上监听,由于重用socket ,所以需要将socket 属性设置为SO_REUSEADDR 。
2. ClientA-1 向ClientB-1 发送连接请求。同样,由于ClientB-1 到ClientA-1 方向的孔已经打好,所以连接会成功,经过3 次握手后,ClientA-1 到ClientB-1 之间的连接就建立起来了。
5.4 穿透对称NAT
上面讨论的都是怎样穿透锥(Cone )NAT ,对称NAT 和锥NAT 很不一样。对于 对称NAT ,当一个私网内主机和外部多个不同主机通信时,对称NAT 并不会像锥(Cone ,全锥,限制性锥,端口限制性锥)NAT 那样分配同一个端口。而是会新建立一个Session ,重新分配一个端口。参考上面穿透限制性锥NAT 的过程,在步骤3时:ClientB-1 (221.10.145.84: ?)向ClientA-1 打孔的时候,对称NAT 将给ClientB-1 重新分配一个端口号,而这个端口号对于Server 、ClientB-1 、ClientA-1 来说都是未知的。同样, ClientA-1 根本不会收到这个消息,同时在步骤4 ,ClientB-1 发送给Server 的通知消息中,ClientB-1 的socket 依旧是(221.10.145.84:6000 )。而且,在步骤6 时:ClientA-1 向它所知道但错误的ClientB-1 发送数据包时,NAT-1 也会重新给ClientA-1 分配端口号。所以,穿透对称NAT 的机会很小。下面是两种有可能穿透对称NAT 的策略。
5.4.1 同时开放TCP ( Simultaneous TCP open )策略
如果一个 对称 NAT 接收到一个来自 本地 私有网 络 外面的 TCP SYN 包, 这 个包想 发 起一个 “ 引入” 的TCP 连 接,一般来 说 , NAT 会拒 绝这 个 连 接 请 求并扔掉 这 个 SYN 包,或者回送一个TCP RST(connection reset ,重建 连 接)包 给请 求方。但是,有一 种 情况 却会接受这个“引入”连接。
RFC 规定:对于对称NAT , 当 这 个接收到的 SYN 包中的源IP 地址 : 端口、目 标 IP 地址 : 端口都与NAT 登 记 的一个已 经 激活的 TCP 会 话 中的地址信息相符 时 , NAT 将会放行 这 个 SYN 包。 需要 特 别 指出 的是:怎样才是一个已经激活的TCP 连接?除了真正已经建立完成的TCP 连接外,RFC 规范指出: 如果 NAT恰好看到一个 刚刚发 送出去的一个 SYN 包和 随之 接收到的SYN 包中的地址 :端口 信息相符合的 话 ,那 么NAT 将会 认为这 个 TCP 连 接已 经 被激活,并将允 许这 个方向的 SYN 包 进 入 NAT 内部。 同时开放TCP 策略就是利用这个时机来建立连接的。
如果 Client A -1 和 Client B -1 能 够 彼此正确的 预 知 对 方的 NAT 将会 给 下一个 TCP 连 接分配的公网TCP 端口,并且两个客 户 端能 够 同 时 地 发 起一 个面向对方的 “ 外出 ” 的 TCP 连 接 请求 ,并在 对 方的SYN 包到达之前,自己 刚发 送出去的 SYN 包都能 顺 利的穿 过 自己的 NAT 的 话 ,一条端 对 端的 TCP 连 接就 能 成功地建立了 。
5.4.2 端口猜测策略
同时开放TCP 策略非常依赖于猜测对方的下一个端口,而且强烈依赖于发送连接请求的时机,而且还有网络的不确定性,所以能够建立的机会很小,即使Server 充当同步时钟的角色。下面是一种通过UDP 穿透的方法,由于UDP 不需要建立连接,所以也就不需要考虑“同时开放”的问题。
为了介绍ClientB-1 的诡计,先介绍一下STUN 协议。STUN (Simple Traversal of UDP Through NATs )协议是一个轻量级协议,用来探测被NAT 映射后的地址:端口。STUN 采用C/S 结构,需要探测自己被NAT 转换后的地址:端口的Client 向Server 发送请求,Server 返回Client 转换后的地址:端口。
参考上面UDP穿透NAT 的步骤2 ,当ClientB-1 收到Server 发送给它的消息后,ClientB-1 即打开3 个socket 。socket-0 向STUN Server 发送请求,收到回复后,假设得知它被转换后的地址:端口( 221.10.145.84:600 5 ),socket-1 向ClientA-1 发送一个UDP 包,socket-2 再次向另一个STUN Server 发送请求,假设得到它被转换后的地址:端口( 221.10.145.84:60 20 )。通常,对称NAT 分配端口有两种策略,一种是按顺序增加,一种是随机分配。如果这里对称NAT 使用顺序增加策略,那么,ClientB-1 将两次收到的地址:端口发送给Server 后,Server 就可以通知ClientA-1 在这个端口范围内猜测刚才ClientB-1 发送给它的socket-1 中被NAT 映射后的地址:端口,ClientA-1 很有可能在孔有效期内成功猜测到端口号,从而和ClientB-1 成功通信。
5.5 问题总结
从上面两种穿透对称NAT 的方法来看,都建立在了严格的假设条件下。但是现实中多数的NAT 都是锥NAT ,因为资源毕竟很重要,反观对称NAT ,由于太不节约端口号所以相对来说成本较高。所以,不管是穿透锥NAT,还是对称NAT ,现实中都是可以办到的。除非对称NAT 真的使用随机算法来分配可用的端口。
NAT技术无可否认是在ipv4地址资源的短缺时候起到了缓解作用;在减少用户申请ISP服务的花费和提供比较完善的负载平衡功能等方面带来了不少好处。但是在ipv4地址在以后几年将会枯竭,NAT技术不能改变ip地址空间不足的本质。然而在安全机制上也潜在着威胁,在配置和管理上也是一个挑战。如果要从根本上解决ip地址资源的问题,ipv6才是最根本之路。在ipv4转换到ipv6的过程中,NAT技术确实是一个不错的选择,相对其他的方案优势也非常明显。