上一章我们提到 p2p 最大的障碍就是无处不在的 NAPT(网络端口地址转换),NAPT 是一种 NAT(网络地址转换) 技术,这一章节我们就来介绍一下 NAT 技术。
NAT 产生背景
随着 Internet 的发展和网络应用的增多,IPv4 地址枯竭已成为制约网络发展的瓶颈。尽管 IPv6 可以从根本上解决 IPv4 地址空间不足问题,但是在 IPv6 广泛应用之前,一些过渡技术(如 CIDR、私网地址等)是解决这个问题最主要的技术手段。其中,使用私网地址之所以能够节省 IPv4 地址,主要是利用了这样一个事实:一个局域网中在一定时间内只有很少的主机需访问外部网络,而 80% 左右的流量只局限于局域网内部。由于局域网内部的互访可通过私网地址实现,且私网地址在不同局域网内可被重复利用,因此私网地址的使用有效缓解了 IPv4 地址不足的问题。当局域网内的主机要访问外部网络时,只需通过 NAT 技术将其私网地址转换为公网地址即可,这样既可保证网络互通,又节省了公网地址。IANA (互联网数字分配机构) 保留以下三个网段中的地址作为私网地址:10.0.0.0/8、172.16.0.0/12 和192.168.0.0/16。使用私网地址的主机不能直接访问 Internet,而在 Internet 上也不能直接访问使用私网地址的主机。
技术优点
作为一种过渡方案,NAT 通过地址重用的方法来满足 IP 地址的需要,可以在一定程度上缓解 IP 地址空间枯竭的压力。它具备以下优点:
- 对于内部通讯可以利用私网地址,如果需要与外部通讯或访问外部资源,则可通过将私网地址转换成公网地址来实现。
- 通过公网地址与端口的结合,可使多个私网用户共用一个公网地址。
- 通过静态映射,不同的内部服务器可以映射到同一个公网地址。外部用户可通过公网地址和端口访问不同的内部服务器,同时还隐藏了内部服务器的真实IP地址,从而防止外部对内部服务器乃至内部网络的攻击行为。
- 方便网络管理,如通过改变映射表就可实现私网服务器的迁移,内部网络的改变也很容易。
NAT 技术实现
NAT的基本原理是仅在私网主机需要访问 Internet 时才会分配到合法的公网地址,而在内部互联时则使用私网地址。当访问 Internet 的报文经过 NAT 网关时,NAT 网关会用一个合法的公网地址(IP)替换原报文中的源 IP 地址,并对这种转换进行记录;之后,当报文从 Internet 侧返回时,NAT 网关查找原有的记录,将报文的目的地址再替换回原来的私网地址,并送回发出请求的主机。这样,在私网侧或公网侧设备看来,这个过程与普通的网络访问并没有任何的区别。
基本 NAT (Basic NAT)
Basic NAT 方式属于一对一的地址转换,在这种方式下只转换IP地址,而不关心 TCP/UDP 等传输层协议的端口号,一个公网 IP 地址不能同时被多个用户使用。
Basic NAT方式的处理过程:
- NAT设备收到私网侧主机发送的访问公网侧服务器的报文。
- NAT设备从地址池中选取一个空闲的公网 IP 地址,建立与私网侧报文源IP地址间的NAT转换表项(正反向),并依据查找正向 NAT 表项的结果将报文转换后向公网侧发送。
- NAT 设备收到公网侧的回应报文后,根据其目的 IP 地址查找反向 NAT 表项,并依据查表结果将报文转换后向私网侧发送。
注意:由于Basic NAT这种一对一的转换方式并未实现公网地址的复用,不能有效解决IP地址短缺的问题,因此在实际应用中并不常用。
端口 NAT(NAPT)(PAT)
由于Basic NAT方式并未实现地址复用,因此并不能解决公网地址短缺的问题,而NAPT方式则可以解决这个问题。NAPT方式属于多对一的地址转换,它通过使用"IP地址+端口号"的形式进行转换,使多个私网用户可共用一个公网IP地址访问外网,因此是 NAT 实现的主要形式。
NAPT方式的处理过程如下:
- NAT设备收到私网侧主机发送的访问公网侧服务器的报文。
- NAT设备从地址池中选取一对空闲的"公网IP地址+端口号",建立与私网侧报文"源IP地址+源端口号"间的NAPT转换表项(正反向),并依据查找正 向NAPT表项的结果将报文转换后向公网侧发送。
- NAT设备收到公网侧的回应报文后,根据其"目的IP地址+目的端口号"查找反向NAPT表项,并依据查表结果将报文转换后向私网侧发送。
NAT Server方式
出于安全考虑,大部分私网主机通常并不希望被公网用户访问。但在某些实际应用中,需要给公网用户提供一个访问私网服务器的机会。而在Basic NAT或NAPT方式下,由于由公网用户发起的访问无法动态建立NAT表项,因此公网用户无法访问私网主机。NAT Server(NAT内部服务器)方式就可以解决这个问题——通过静态配置"公网IP地址 +端口号"与"私网IP地址+端口号"间的映射关系,NAT设备可以将公网地址"反向"转换成私网地址。
- 在NAT设备上手工配置静态NAT转换表项(正反向)。
- NAT设备收到公网侧主机发送的访问私网侧服务器的报文。
- NAT设备根据公网侧报文的"目的IP地址+目的端口号"查找反向静态NAT表项,并依据查表结果将报文转换后向私网侧发送。
接下来我们来重点讨论第二种实现方式:端口 NAT(NAPT)(PAT),我们绝大多数的终端设备都位于这个这种 NAT 之后。
NAT 设备的分类
这里是根据设备处理需要 NAPT 的数据包的行为(behavior)来分类的。这里行为分为两种:映射行为(mapping behavior),过滤行为(filter behavior)。
映射行为
这里的映射是指:内网ip+端口和公网ip+端口的映射。nat 设备所有的映射规则可以分为三种:端点无关 ,依赖地址 ,依赖地址+端口 。解释一下端点,一个端点就是一个网络地址(IP)+端口的组合(后面我们提到的端口都代指 IP + 端口),端点无关就是即不依赖地址也不依赖端口,这里地址和端口指的都是远端设备的地址和端口,即:目的IP+目的端口。
- 端点无关:只是根据设备后终端发出数据包的的内网IP + 端口 两个元素的不同来决定映射后的公网IP+端口。
- 依赖地址: 根据本地的内网IP+端口在加上远端地址(目的IP) 三个元素的不同来决定映射后的 公网IP+端口
- 依赖地址+端口: 根据内网IP+端口在加上**远端地址(目的IP)+ 远端端口(目的端口)* *四个元素的不同来决定映射后的 公网IP+端口
上面三种中的第一种我们可以简称为:EIM(Endpoint-independent mapping 端结点无关的映射),后面两种统称为:EDM(Endpoint-dependent mapping 端结点相关的映射)
过滤行为
当我们请求数据包发出后我们当然期望有数据包的返回,这个返回的数据包的目的地址+端口就是映射之后的公网IP+端口,那么是不是所有的目的地址+端口是本端公网IP+端口的数据包我们都放行呢?
根据 nat 设备的放行规则(过滤行为):我们可以把 nat 设备分为三类:
- 端点无关:不做过滤,只要 nat 设备后的终端设备向外发出请求,nat 网络建立了 内网ip+端口和公网ip+端口的映射。公网端点收到的数据包都会被转发到相应内网IP+端口。
- 依赖地址: 根据数据包的 IP 过滤,只有该nat设备后的终端设备向该 IP 发送过数据包,nat 设备才会把来着该设备的数据包转发到内网。
- 依赖地址+端口: 根据数据包的 IP + 端口过滤,只有nat设备后的终端设备向该端点发送给数据包,nat 设备才会把来着该端点的数据包转发到内网。
上面三种中的第一种我们可以简称为:EIF(Endpoint-independent Filtering 端结点无关的过滤),后面两种统称为:EDF(Endpoint-independent Filtering 端节点相关的过滤)
为什么要介绍这些分类呢?因为 P2P 应对无处不在的 napt 的方案叫做 nat 穿越,这其中打洞是最优先要考虑的一种穿越技术,而 nat 设备的映射行为+过滤行为就决定了应用程序是否能打洞成功。
另外一种分类方式
为了方便展示什么样类型的 nat 支持打洞,我们再来引入一种更为传统的 nat 设备分类方式:全锥形,限制锥型,端口限制型,对称型
EIM 和 EIF <=> 全锥型 EIM 和 EDF (基于 IP 的过滤) <=> 限制锥型 EIM 和 EDF (基于 IP 和 Port 的过滤) <=> 端口限制型 EDM 和 EDF (基于 IP 和 Port 的过滤) <=> 对称型
本地类型/对端类型 | 全锥型 | 限制锥型 | 端口限制型 | 对称型 |
---|
全锥型 | √ | √ | √ | √ | 限制锥型 | √ | √ | √ | √ | 端口限制型 | √ | √ | √ | — | 对称型 | √ | √ | — | × |
- √ 表示可以打通
- × 表示不可以打通
- — 表示有打通的方法,但是不能确保 100% 打通
至于为什么有的能打通,有的打不通,有的还不能确保 100% 打通,这个原因是很复杂的,在后面介绍 ICE 时我们再来详细介绍其原理。
|