(下面,我将忽略任何DNS查找或第二层操作,因为这与NAT故事无关。)
任何TCP连接都是四个部分的元组:
<source IP> <source port> <destination IP> <destination port>
简而言之:目标IP用于将数据包发送到正确的计算机,目标端口用于将数据包在该计算机上发送到正确的程序/会话。源IP用于了解将答复发送到哪里。源端口也是如此。发送答复后,只需交换源和目标。
让我们从两台没有任何NAT的计算机开始:
- 电脑有IP
1.1.1.1
- 网络服务器具有IP
3.3.3.3
- HTTP的标准端口是
80
当计算机请求网页时,它将首先从随机范围(1024-65535)中选择一个随机未使用的端口号。让我们选择2345
。然后,将发生以下顺序:计算机使用以下方式发送数据包:源IP 1.1.1.1
,源端口2345
,目标IP 3.3.3.3
,目标端口80
。数据包到达Web服务器,它看到了它自己的IP和端口80
,因此知道这是对网页的请求。然后,Web服务器以带有源IP 3.3.3.3
,源端口80,目标IP 1.1.1.1
和目标端口的数据包的形式发送回网页2345
。由于端口号,计算机接收到这些数据包,并且知道请求的网页是2345
。
这些端口组合通常这样写:1.1.1.1:2345
和3.3.3.3:80
。
现在,互联网上的计算机数量远远超过了可用的IPv4地址数量。为了保留地址空间,引入了一组专用地址范围,这些地址范围可自由用于地址共享。这些范围称为RFC1918,如下所示:
- 192.168.0.0-192.168.255.255
- 172.16.0.0-172.31.255.255
- 10.0.0.0-10.255.255.255
这些地址在Internet路由表中不存在,因此,如果您要发送一个目标地址在Internet骨干网中这些范围内的数据包,它们只会被丢弃。这是因为数百万人使用相同的地址。这些地址需要翻译成对互联网有用的东西。这是网络地址转换的来源:
我们有两台计算机:
- A:
192.168.0.1
和B:192.168.0.2
- 他们的网关的公共IP为
1.1.1.1
。
- 我们保持相同的Web服务器。
- 两台计算机都需要来自同一服务器的相同网页。
首先,两台计算机都选择一个随机端口:假设:192.168.0.1:2345
和192.168.0.2:5432
。
计算机A发送带有源192.168.0.1:2345
和目标的数据包3.3.3.3:80
。网关将此数据包转换为源1.1.1.1:2345
目的地,3.3.3.3:80
并记住对该组合的所有答复都将发送至192.168.0.1
。因此,当它收到带有source 3.3.3.3:80
和destination 的答复时1.1.1.1:2345
,它将把它转换为source 3.3.3.3:80
和destination 192.168.0.1:2345
并继续发送数据包。
计算机B发送带有源192.168.0.2:5432
和目标的数据包3.3.3.3:80
。网关将此数据包转换为源1.1.1.1:5432
目的地,3.3.3.3:80
并记住对该组合的所有答复都将发送至192.168.0.2
。因此,当它收到带有source 3.3.3.3:80
和destination 的答复时1.1.1.1:5432
,它将把它转换为source 3.3.3.3:80
和destination 192.168.0.2:5432
并继续发送数据包。
如果两台计算机碰巧选择了相同的源端口号,则网关将简单地选择另一个空闲的随机源端口号,并记住还要转换该端口号。有时将其称为PAT(端口地址转换)。这基本上是NAT的子集。
这一切有几种实现。网关可能只记住“计算机X使用了源端口Y”并将带有端口Y的任何内容转发到计算机X。它可能还记得了计算机X使用了源端口Y和目标Z”并且仅将任何内容从端口Z转发到了端口Y到。或者可以选择它记住整个元组,并且仅将匹配整个源/目标ip和端口的流量发送到计算机X。