跳到主要内容

2.23. NAT 穿越

2.23. NAT 穿越​

网络地址转换 (NAT) 网关是一个有争议的话题。本节简要描述它们是什么, 以及它们可能如何作用于 IKE 流量。许多人认为 NAT 是邪恶的, 我们不应该为了让它们更好地工作而设计我们的协议。IKEv2 确实指定了一些不直观的处理规则, 以使 NAT 更有可能工作。

NAT 存在的主要原因是 IPv4 地址的短缺, 尽管还有其他理由。位于 NAT "后面" 的 IP 节点具有不是全局唯一的 IP 地址, 而是从 NAT 后面网络中唯一、但可能被其他 NAT 后面的节点重用的地址空间中分配的。通常, NAT 后面的节点可以与同一 NAT 后面的其他节点以及具有全局唯一地址的节点通信, 但不能与其他 NAT 后面的节点通信。该规则也有例外。当这些节点与真实 Internet 上的节点建立连接时,

NAT 网关将 IP 源地址 "转换" 为将被路由回网关的地址。来自 Internet 到网关的消息, 其目标地址被 "转换" 为将数据包路由到正确终端节点的内部地址。

NAT 被设计为对终端节点 "透明"。NAT 后面的节点上的软件以及 Internet 上的节点都不需要修改即可通过 NAT 通信。实现这种透明性对于某些协议比对于其他协议更困难。在数据包的载荷中包含端点 IP 地址的协议将会失败, 除非 NAT 网关理解该协议并修改内部引用以及头部中的引用。这种知识本质上是不可靠的, 是对网络层的违反, 并且经常导致微妙的问题。

通过 NAT 打开 IPsec 连接会带来特殊问题。如果连接在传输模式下运行, 更改数据包上的 IP 地址将导致校验和失败, 而 NAT 无法纠正校验和, 因为它们是受密码学保护的。即使在隧道模式下, 也存在路由问题, 因为透明地转换 AH 和 ESP 数据包的地址需要 NAT 中的特殊逻辑, 而这种逻辑本质上是启发式且不可靠的。由于这个原因, IKEv2 将使用 IKE 和 ESP 数据包的 UDP 封装。这种编码效率略低, 但 NAT 更容易处理。此外, 防火墙可能被配置为放行 UDP 封装的 IPsec 流量, 而不放行明文、未封装的 ESP/AH, 或反之亦然。

NAT 通常不仅转换 TCP 和 UDP 端口号以及地址, 还使用入站数据包的端口号来决定哪个内部节点应该获得给定的数据包。由于这个原因, 即使 IKE 数据包必须 (MUST) 从 UDP 端口 500 或 4500 发送和接收, 它们必须 (MUST) 被接受来自任何端口, 并且响应必须 (MUST) 被发送到它们来自的端口。这是因为数据包通过 NAT 时端口可能被修改。类似地, IKE 端点的 IP 地址通常不包含在 IKE 载荷中, 因为载荷是受密码学保护的, 并且无法被 NAT 透明地修改。

端口 4500 被保留用于 UDP 封装的 ESP 和 IKE。发现它与其对应方之间存在 NAT (如下所述) 的 IPsec 端点必须 (MUST) 从端口 4500 发送所有后续流量, NAT 不应将其特殊处理 (就像它们可能对端口 500 做的那样)。

发起方可以 (MAY) 将端口 4500 用于 IKE 和 ESP, 无论是否存在 NAT, 甚至在 IKE 开始时。当任一方使用端口 4500 时, 发送 UDP 封装的 ESP 不是必需的, 但理解接收到的 UDP 封装的 ESP 数据包是必需的。UDP 封装必须 (MUST NOT) 在端口 500 上完成。如果支持网络地址转换穿越 (NAT-T) (即, 如果在 IKE_SA_INIT 期间交换了 NAT_DETECTION_*_IP 载荷), 所有设备必须 (MUST) 能够在任何时候接收和处理 UDP 封装的 ESP 以及非 UDP 封装的 ESP 数据包。任一方可以独立于另一方所作的选择, 决定是否对 ESP 使用 UDP 封装。但是, 如果检测到 NAT, 两个设备都必须 (MUST) 对 ESP 使用 UDP 封装。

支持 NAT 穿越 [NATREQ] 的具体要求如下所列。支持 NAT 穿越是可选的。仅在本节中, 列为 MUST 的要求仅适用于支持 NAT 穿越的实现。

o IKE 发起方和响应方都必须 (MUST) 在其 IKE_SA_INIT 数据包中包含类型为 NAT_DETECTION_SOURCE_IP 和 NAT_DETECTION_DESTINATION_IP 的 Notify 载荷。这些载荷可用于检测主机之间是否存在 NAT, 以及哪一端在 NAT 后面。这些载荷在 IKE_SA_INIT 数据包中的位置紧跟在 Ni 和 Nr 载荷之后 (在可选的 CERTREQ 载荷之前)。

o 与 NAT_DETECTION_SOURCE_IP 通知关联的数据是数据包发送所依据的 SPI (按它们在头部中出现的顺序), IP 地址和端口的 SHA-1 摘要。如果发送方不知道将使用多个网络附件中的哪一个来发送数据包, 则一条消息中可能 (MAY) 有多个 NAT_DETECTION_SOURCE_IP 载荷。

o 与 NAT_DETECTION_DESTINATION_IP 通知关联的数据是数据包发送所依据的 SPI (按它们在头部中出现的顺序), IP 地址, 和端口的 SHA-1 摘要。

o 任一 NAT_DETECTION_SOURCE_IP 或 NAT_DETECTION_DESTINATION_IP 通知的接收方可以 (MAY) 将提供的值与 SPI, 源或接收方 IP 地址 (分别), 地址和端口的 SHA-1 哈希进行比较, 如果它们不匹配, 它应 (SHOULD) 启用 NAT 穿越。如果接收到的所有 NAT_DETECTION_SOURCE_IP 哈希与 NAT_DETECTION_SOURCE_IP 哈希都不匹配, 接收方可以 (MAY) 在不支持 NAT 穿越的情况下拒绝连接尝试。在不匹配 NAT_DETECTION_DESTINATION_IP 哈希的情况下, 意味着接收 NAT_DETECTION_DESTINATION_IP 载荷的系统位于 NAT 后面, 并且该系统应 (SHOULD) 开始发送 [UDPENCAPS] 中定义的保活数据包; 或者, 如果不支持 NAT 穿越, 它可以 (MAY) 拒绝连接尝试。

o 如果接收到的 NAT_DETECTION_SOURCE_IP 载荷 (们) 中没有一个与从包含该载荷的数据包的 IP 头部找到的源 IP 和端口的预期值匹配, 这意味着发送这些载荷的系统位于 NAT 后面 (即, 路由上的某个人更改了原始数据包的源地址以匹配 NAT 盒的地址)。在这种情况下, 接收载荷的系统应允许另一系统的 IP 地址的动态更新, 如下所述。

o IKE 发起方必须 (MUST) 检查 NAT_DETECTION_SOURCE_IP 或 NAT_DETECTION_DESTINATION_IP 载荷 (如果存在), 并且如果它们与外部数据包中的地址不匹配, 必须 (MUST) 通过 UDP 端口 4500 对与此 IKE SA 关联的所有未来 IKE 和 ESP 数据包进行隧道传输。

o 要通过 UDP 端口 4500 对 IKE 数据包进行隧道传输, 在 IKE 头部前加四个零八字节, 结果紧跟在 UDP 头部之后。要通过 UDP 端口 4500 对 ESP 数据包进行隧道传输, ESP 头部紧跟在 UDP 头部之后。由于 ESP 头部的前四个八字节包含 SPI, 而 SPI 不能有效为零, 因此始终可以区分 ESP 和 IKE 消息。

o 实现必须 (MUST) 处理接收到的 UDP 封装的 ESP 数据包, 即使未检测到 NAT。

o 传输模式 TCP 和 UDP 数据包校验和修正所需的原始源和目标 IP 地址 (见 [UDPENCAPS]) 从与交换关联的流量选择器获得。在传输模式 NAT 穿越的情况下, 流量选择器必须 (MUST) 恰好包含一个 IP 地址, 该地址随后用作原始 IP 地址。这在第 2.23.1 节中有更详细的介绍。

o 在某些情况下, NAT 盒决定删除仍然存活的映射 (例如, 保活间隔太长, 或 NAT 盒已重新启动)。如果主机收到一个数据包, 其完整性保护验证通过, 但具有与验证数据包中与该 SA 关联的不同的端口, 地址或两者, 这对主机来说是显而易见的。当找到这样的验证数据包时, 不支持 IKEv2 移动性和多宿主 (MOBIKE) [MOBIKE] 等其他恢复方法, 并且不在 NAT 后面的主机, 应 (SHOULD) 将所有数据包 (包括重传数据包) 发送到验证数据包中的 IP 地址和端口, 并应 (SHOULD) 将其存储为该 SA 的新的地址和端口组合 (即, 它们应动态更新地址)。NAT 后面的主机不应 (SHOULD NOT) 进行这种类型的动态地址更新, 如果验证数据包具有不同的端口和/或地址值, 因为这会打开可能的 DoS 攻击 (例如允许攻击者用单个数据包中断连接)。此外, 动态地址更新应仅响应于新数据包而进行; 否则, 攻击者可以用旧的重复数据包来还原地址。因此, 只有在启用了重放保护时, 才能安全地执行动态更新。当 IKEv2 与 MOBIKE 一起使用时, 上述动态更新地址会干扰 MOBIKE 从相同情况恢复的方式。有关更多信息, 请参见 [MOBIKE] 的第 3.8 节。

2.23.1. 传输模式 NAT 穿越​

与 NAT 穿越一起使用的传输模式需要对 IKEv2 中使用的流量选择器进行特殊处理。完整的场景如下:

+------+ +------+ +------+ +------+ |Client| IP1 | NAT | IPN1 IPN2 | NAT | IP2 |Server| |node |<------>| A |<---------->| B |<------->| | +------+ +------+ +------+ +------+

(其他场景是此复杂情况的简化, 因此本讨论使用完整场景。)

在此场景中, 有两个地址转换 NAT: NAT A 和 NAT B。NAT A 是一个动态 NAT, 将客户端的源地址 IP1 映射到 IPN1。NAT B 是一个静态 NAT, 配置为将到达 IPN2 地址的连接映射到网关的地址 IP2, 即 IPN2 目标地址被映射到 IP2。这允许客户端通过连接到 IPN2 来连接到服务器。NAT B 不一定是静态 NAT, 但客户端需要知道如何连接到服务器, 并且只有当它以某种方式知道 NAT B 的外部地址 (即 IPN2 地址) 时才能这样做。如果 NAT B 是静态 NAT, 则其地址可以配置到客户端的配置中。另一种选择是使用其他协议 (如 DNS) 查找它, 但这超出了 IKEv2 的范围。

在此场景中, 客户端和服务器都配置为对源自客户端节点并发送到服务器的流量使用传输模式。

当客户端开始创建用于向服务器发送流量的 IKEv2 SA 和 Child SA 时, 它可能有一个触发数据包, 其源 IP 地址为 IP1, 目标 IP 地址为 IPN2。其对等授权数据库 (PAD) 和 SPD 需要具有匹配这些地址 (或覆盖它们的通配条目) 的配置。

因为这是传输模式, 它使用与流量选择器和 IKE 数据包的外部 IP 地址完全相同的地址。对于传输模式, 它必须 (MUST) 在 TSi 和 TSr 载荷中恰好使用一个 IP 地址。如果它有 (例如) 它想要协商的多个端口范围, 它可以有多个流量选择器, 但所有 TSi 条目必须使用 IP1-IP1 范围作为 IP 地址, 并且所有 TSr 条目必须具有 IPN2-IPN2 范围作为 IP 地址。TSi 和 TSr 的第一个流量选择器应 (SHOULD) 具有非常具体的流量选择器, 包括协议和端口号, 例如来自触发请求的数据包。

NAT A 然后将 IKE 数据包的源地址从 IP1 替换为 IPN1, NAT B 将 IKE 数据包的目标地址从 IPN2 替换为 IP2, 因此当数据包到达服务器时, 它仍将具有客户端发送的完全相同的流量选择器, 但 IKE 数据包的 IP 地址已被 IPN1 和 IP2 替换。

当服务器收到此数据包时, 它通常基于 ID 查找 RFC 4301 [IPSECARCH] 中描述的对等授权数据库 (PAD), 然后基于流量选择器搜索 SPD。因为 IP1 对服务器来说实际上没有任何意义 (它是客户端在 NAT 后面的地址), 如果使用传输模式, 基于它进行查找是无用的。另一方面, 在找到匹配的 SPD 条目之前, 服务器无法知道其策略是否允许传输模式。

在这种情况下, 服务器应首先检查发起方是否请求了传输模式, 然后对流量选择器进行地址替换。它需要首先存储旧的流量选择器 IP 地址, 以便稍后用于增量校验和修正 (TSi 中的 IP 地址可以存储为原始源地址, TSr 中的 IP 地址可以存储为原始目标地址)。此后, 如果另一端被检测为位于 NAT 后面, 服务器将 TSi 载荷中的 IP 地址替换为从收到的 IKE 数据包的源地址获得的 IP 地址 (即, 它将 TSi 中的 IP1 替换为 IPN1)。如果服务器的末端被检测为位于 NAT 后面, 它将 TSr 载荷中的 IP 地址替换为从收到的 IKE 数据包的目标地址获得的 IP 地址 (即, 它将 TSr 中的 IPN2 替换为 IP2)。

在此地址替换之后, 流量选择器和 IKE UDP 源/目标地址看起来相同, 并且服务器基于这些新的流量选择器进行 SPD 查找。如果找到条目并允许传输模式, 则使用该条目。如果找到条目但不允许传输模式, 则服务器可以 (MAY) 撤消地址替换, 并使用原始流量选择器重新进行 SPD 查找。如果第二次查找成功, 服务器将使用另一端发送的真实流量选择器以隧道模式创建 SA。

传输模式中的这种地址替换是必需的, 因为 SPD 是使用本地主机将看到的地址进行查找的。这也将确保用于隧道出口检查和返回数据包的安全关联数据库 (SAD) 条目是使用本地操作系统栈将看到的地址添加的。

最常见的情况是服务器的 SPD 将包含匹配任何地址的通配条目, 但这也允许创建不同的 SPD 条目, 例如针对不同的已知 NAT 的外部地址。

在 SPD 查找之后, 服务器将基于它找到的 SPD 条目进行流量选择器缩小。它将再次使用已经替换的流量选择器, 因此它将发回以 IPN1 和 IP2 作为 IP 地址的流量选择器; 它仍然可以缩小流量选择器使用的协议号或端口范围。为 Child SA 创建的 SAD 条目将具有服务器将看到的地址, 即 IPN1 和 IP2。

当客户端收到服务器对 Child SA 的响应时, 它将进行类似的处理。如果创建了传输模式 SA, 客户端可以将返回的原始流量选择器存储为原始源和目标地址。它将把流量选择器中的 IP 地址替换为来自 IKE 数据包 IP 头部的地址: 它将用 IP1 替换 IPN1, 用 IPN2 替换 IP2。然后, 它将在针对发送的流量选择器验证 SA 时, 以及在安装 SAD 条目时, 使用那些流量选择器。

传输模式下 NAT 穿越的规则总结如下:

对于提议传输模式的客户端:

  • TSi 条目必须 (MUST) 恰好具有一个 IP 地址, 并且该地址必须 (MUST) 与 IKE SA 的源地址匹配。
  • TSr 条目必须 (MUST) 恰好具有一个 IP 地址, 并且该地址必须 (MUST) 与 IKE SA 的目标地址匹配。
  • 第一个 TSi 和 TSr 流量选择器应 (SHOULD) 具有非常具体的流量选择器, 包括协议和端口号, 例如来自触发请求的数据包。
  • 可以 (MAY) 有多个 TSi 和 TSr 条目。
  • 如果选择了 SA 的传输模式 (即, 如果服务器在其响应中包含了 USE_TRANSPORT_MODE 通知):
    • 将原始流量选择器存储为收到的源和目标地址。
    • 如果服务器位于 NAT 后面, 将 TSi 条目中的 IP 地址替换为 IKE SA 的远程地址。
    • 如果客户端位于 NAT 后面, 将 TSi 条目中的 IP 地址替换为 IKE SA 的本地地址。
    • 在将这些流量选择器用于除存储其原始内容之外的任何用途之前进行地址替换。这包括验证流量选择器是否被另一端正确缩小, 创建 SAD 条目等。

对于响应方, 当客户端提议传输模式时:

  • 将收到的原始流量选择器 IP 地址存储为源和目标地址, 以防需要撤消地址替换, 用作 [UDPENCAPS] 指定的 "真实源和目标地址", 以及用于 TCP/UDP 校验和修正。
  • 如果客户端位于 NAT 后面, 将 TSi 条目中的 IP 地址替换为 IKE SA 的远程地址。
  • 如果服务器位于 NAT 后面, 将 TSr 条目中的 IP 地址替换为 IKE SA 的本地地址。
  • 使用 ID 和替换的流量选择器进行 PAD 和 SPD 查找。
  • 如果未找到 SPD 条目, 或者找到的 SPD 条目不允许传输模式, 撤消流量选择器替换。使用 ID 和原始流量选择器再次进行 PAD 和 SPD 查找, 同时也搜索隧道模式 SPD 条目 (即, 回退到隧道模式)。
  • 但是, 如果找到了传输模式 SPD 条目, 基于替换的流量选择器和 SPD 条目进行正常的流量选择缩小。在创建 SAD 条目以及将流量选择器发回给客户端时, 使用生成的流量选择器。