本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、为什么需要NAT
ipv4地址是用4个字节(32位)标识一个地址,总的ipv4地址数量约为42亿。
在智能设备日趋普及,万物互联的今天,ipv4地址是稀缺且珍贵的。
网络地址转换(Network Address Translation, NAT)很好的缓解了ipv4地址不足的问题。
举个例子,一个家庭开通了宽带网络, 家里的手机、平板、电脑等设备都可以通过路由器连接网络, 那每个联网设备联网都被分配一个单独的公网ip吗?并不是这样。我们会发现每个设备被分配了一个类似"192.168.*.*"的局域网ip,但他们的出口ip其实只有一个。
这大大降低了对公网ip地址数量的消耗, 并且局域网内的设备通过路由器都能正常访问互联网上的服务, 这就是NAT的功劳。
二、NAT原理解析
那NAT是如何实现的呢?局域网内的设备都共用一个公网ip(ipA)访问互联网,那外来包的目的地址(ipA)也是相同的, 路由器是使用什么策略将外来的包转发给局域网内的各个设备呢?为什么没有造成混乱呢?
具体的实现细节可以参考RFC2663、RFC3022,本文简单介绍一下NAT的实现原理。
解析NAT原理之前先介绍一下路由器的WAN口和LAN口, 我们看路由器上的网口, 上面分别有WAN、LAN的标识。
WAN代表的是广域网络, 一般WAN口只有一个, 也就是连接出口网线的网口。
LAN代表的是本地局域网络, LAN口可能有多个, 也就是连接需要上网的设备的网口。
NAT的实现依赖在路由器的内部维护一张NAT转换表, 转换表的内容长这个样子:
| WAN | LAN |
|---|---|
| 广域网ipA:6000 | 192.168.0.2:7065 |
| 广域网ipA:6066 | 192.168.0.3:7235 |
| 广域网ipA:7700 | 192.168.0.4:6653 |
维护了这样一张NAT转换表, 路由器就可以按需转发数据包避免混乱了。
我们看NAT转换表中的第一条记录, 一台局域网内的手机的局域网地址是192.168.0.2, 这台手机想访问广域网地址B上的一个web服务, 向广域网地址B的80端口(广域网ipB:80)发起连接。
这台手机设备发起连接时在自身设备上分配了一个端口号7065, 那么对于这台设备来说, 该连接的本地地址就是192.168.0.2:7065。
发起连接的请求经过路由器时, 路由器要给这个连接分配一个广域网端口号, 在这个例子中分配的是6000, 那么在NAT转换表中就有了 广域网ipA,6000 -> 192.168.0.2,7065这条记录。
当广域网的服务返回数据包时, 路由器通过查询NAT转换表中的记录, 就能确定该将数据包转发给哪台设备哪个端口。
下面用一张图展示该过程:
三、NAT是完美的吗?
虽然NAT的实现比较简洁、带来的好处也很多, 但也受到一些质疑。
原因在于, 最初端口号的设计是被用于单个设备上区分不同的进程的。但在NAT中端口号被用作区分不同设备, 这样打破了最初的设计理念。
虽然如此, NAT还是被普遍接受和广泛应用在各种场景。
四、总结
NAT很好的解决了广域网上ipv4地址数量不足的问题。
NAT的实现依赖路由器内部维护的NAT转换表。
NAT的设计影响了一些规范, 但掩盖不了它带来的好处, NAT得到了广泛的应用。