NAT如何保证每台机器都有唯一的公网IP?
它不是。
你的问题比你想象的要复杂。提取公共地址的范围是1.0.0.0到223.255.255.255,但该范围内有一些块不能用于公共地址。
IANA 维护着IANA IPv4 专用地址注册表,该注册表为每个块解释了块中的地址是否可用作源地址或目标地址、地址是否可转发(可路由)以及地址是否可全局访问。一些地址,例如127.0.0.0/8, 由 IPv4 协议本身保留,并且也指示。其他地址块无法全局访问,因为 ISP 已同意不在公共 Internet 上转发它们。例如,三个Private地址块是任意选择的,ISP同意不在公共互联网上转发,但是可以在一个私有网络内转发,包括一个ISP自己的网络,但不能在ISP网络之间转发,虽然两个ISP(或其他公司)可以同意在两个 ISP 之间转发它们。
全局可达的地址称为公共地址。IANA 拥有这些地址,并将它们分配给 RIR 以在区域内使用。RIR 将这些地址分配给公司,包括 ISP。不幸的是,IANA 用完了要分配给 RIR 的地址,而 RIR 也用完了要分配给其区域内公司的地址。
IPv4 地址短缺的最大缓解措施是使用一种称为 NAPT 的 NAT。它允许没有足够公共 IPv4 地址的公司在单个公共地址后面隐藏其他地址。正如您所指出的,这确实会导致在私有寻址之外发起的流量出现问题。有多种方法可以尝试解决此问题,但这是一个问题。
我的问题是,NAT 究竟是如何执行这种转换的?我看到的一些消息表明,每台机器都会使用路由器的公共 IP,但事实并非如此。
对于 NAPT 来说确实如此。您缺少的是,许多公司都被分配了公共地址块,并且他们将公共地址用于需要从公司外部访问的设备,而其他只需要发起对话的设备将使用私有地址,转换为公共地址。
每台机器是否都有唯一的公共 IP 地址?
不。有些设备根本不连接到公共 Internet,只连接到内部网络,并且不需要公开寻址这些设备。其他设备有时可能需要访问公共 Internet 上的服务,而这些设备可以使用私有寻址和 NAPT(尽管 NAPT 对某些应用程序和协议来说可能是一个大问题)。其他设备需要向公共 Internet 提供服务,这些设备将有一个公共地址,直接分配给该设备的以太,或者许多设备都有一个私有地址,该地址在公共连接的路由器的 NAPT 表中具有永久条目。
如果不是,不在同一网络上的机器如何区分网络上的不同机器?
在大多数情况下,它们是不区分的。最初的 IP 范式是每个设备都有一个唯一的(公共)地址。没有足够的公共 IPv4 地址来接近这一点。使用 IPv4 私有寻址和 NAPT 是一种解决方法,但您需要中间的设备来维护连接状态,从而牺牲了 IP 的端到端连接。对于某些设备,您可以在 NAPT 表中添加一个永久条目,以允许将外部发起的流量发送到内部的特定设备。(内部发起的流量会自动在 NAPT 表中创建一个条目以允许回复。)
NAPT 仅适用于 TCP、UDP 和 ICMP。其他传输协议失败,一些使用 TCP 或 UDP 的应用程序和应用层协议也可能因为 NAPT 而中断。
NAT(包括 NAPT)是一个巨大的主题,并且有多个 RFC 涵盖它。例如,RFC 3022,传统 IP 网络地址转换器(传统 NAT),其中第 2.2 节讨论了 NAPT:
2.2. NAPT概述
比如说,一个组织有一个私有 IP 网络和一个到服务提供商的 WAN 链接。专用网络的末节路由器在 WAN 链接上分配了一个全局有效地址,组织中的其余节点具有仅具有本地意义的 IP 地址。在这种情况下,可以允许专用网络上的节点在 NAPT 的帮助下使用单个注册的 IP 地址同时访问外部网络。NAPT 将允许将类型(本地 IP 地址、本地 TU 端口号)的元组映射到类型(注册的 IP 地址、分配的 TU 端口号)的元组。
此模型适合大多数小型办公室家庭办公室 (SOHO) 组使用单个服务提供商分配的 IP 地址访问外部网络的要求。通过为注册 IP 地址的每个服务 TU 端口静态映射本地节点,可以扩展此模型以允许入站访问。
在下面图 3 的示例中,存根 A 在内部使用 A 类地址块 10.0.0.0/8。服务提供商为末节路由器的 WAN 接口分配了一个 IP 地址 138.76.28.4。
\ | /
+-----------------------+
|Service Provider Router|
+-----------------------+
WAN |
|
Stub A .............|....
|
^{s=138.76.28.4,sport=1024, | v{s=138.76.29.7, sport = 23,
^ d=138.76.29.7,dport=23} | v d=138.76.28.4, dport = 1024}
+------------------+
|Stub Router w/NAPT|
+------------------+
|
| LAN
--------------------------------------------
| ^{s=10.0.0.10,sport=3017, | v{s=138.76.29.7, sport=23,
| ^ d=138.76.29.7,dport=23} | v d=10.0.0.10, dport=3017}
| |
+--+ +--+ +--+
|--| |--| |--|
/____\ /____\ /____\
10.0.0.1 10.0.0.2 ..... 10.0.0.10
Figure 3: Network Address Port Translation (NAPT) Operation
当存根 A 主机 10.0.0.10 向主机 138.76.29.7 发送 telnet 数据包时,它使用全局唯一地址 138.76.29.7 作为目的地,并将数据包发送到其主路由器。存根路由器有一个静态路由,用于子网 138.76.0.0/16,因此数据包被转发到 WAN 链路。但是,在转发数据包之前,NAPT 会将 IP 和 TCP 标头中的源地址 10.0.0.10 和源 TCP 端口 3017 的元组转换为全局唯一的 138.76.28.4 和唯一分配的 TCP 端口(例如 1024)。返回路径上的数据包经过类似的地址和 TCP 端口转换,用于目标 IP 地址和目标 TCP 端口。再次注意,这不需要更改主机或路由器。翻译是完全透明的。
在此设置中,只允许 TCP/UDP 会话并且必须源自本地网络。但是,有些服务(例如 DNS)需要入站访问。可能存在组织希望允许入站会话访问的其他服务。可以在存根路由器上静态配置众所周知的 TU 端口服务 [RFC 1700],以将其定向到专用网络中的特定节点。
除了 TCP/UDP 会话之外,除了 REDIRECT 消息类型之外,ICMP 消息也可能被 NAPT 路由器监视。ICMP 查询类型报文的转换类似于 TCP/UDP 报文,即 ICMP 报文头中的标识符字段将唯一映射到已注册 IP 地址的查询标识符。ICMP 查询消息中的标识符字段由查询发送方设置,并在来自查询响应方的响应消息中原封不动地返回。因此,NAPT路由器将(本地IP地址,本地ICMP查询标识符)的元组映射到(注册的IP地址,分配的ICMP查询标识符)的元组,以唯一标识来自任何本地主机的所有类型的ICMP查询。对 ICMP 错误消息的修改将在后面的部分中讨论,
在 NAPT 设置中,注册的 IP 地址与存根路由器 WAN 接口的 IP 地址相同,路由器必须确保区分源自自身的 TCP、UDP 或 ICMP 查询会话与源自节点上的节点的会话。本地网络。假设所有入站会话(包括 TCP、UDP 和 ICMP 查询会话)都被定向到作为端节点的 NAT 路由器,除非目标服务端口静态映射到本地网络中的不同节点。
除了 TCP、UDP 和 ICMP 查询类型之外的会话根本不允许来自本地节点,由 NAPT 路由器提供服务。