当提到 IKE 和 IPsec 安全关联 (SA) 时,安全参数索引 (SPI) 可能有不同的含义:
- 对于IKE,两个 64 位 SPI 唯一标识一个 IKE SA。对于IKEv2,
IKE_SA_INIT请求将仅在 IKE 标头中设置本地唯一的发起方 SPI,响应方 SPI 为零。响应者将在其响应中将其设置为同样本地唯一的值。这两个 SPI 只会在 IKE SA 重新加密时发生变化。
IKE 标头中现在称为发起方/响应方 SPI 的两个字段以前在RFC 2408 (ISAKMP) 中称为发起方/响应方 Cookie。这可能会造成混淆,因为 IKEv2 使用 COOKIE 通知负载来阻止拒绝服务攻击。
- 对于IPsec,32 位 SPI 半唯一标识 IPsec SA。由于这些 SA 是单向的,ESP/AH 标头仅包含目标入站 SA 的 SPI(与始终包含两个 SPI 的 IKE 标头不同)。由于 SPI 在本地是唯一的,因此目标地址通常足以唯一标识 SA。但它可能会出现问题,例如,如果同一 NAT 后面的两个客户端在连接到同一 VPN 网关时分配相同的本地 SPI。SPI 和目标地址的组合在 NAT 的公共端是相同的,这就是UDP 封装的原因是必须的。UDP 端口允许 NAT 将入站数据包定向到正确的客户端。同样,网关必须采取措施区分两个 SA,以便在向每个客户端发送流量时使用正确的 SA。
这是否意味着,一方设置的 SPI 是用于传入 SA 的 SPI,而不是传出的?
是的,每个对等点都将其入站 SA 的 SPI 发送给另一个对等点。
另外,我的笔记说发起者使用该SAD_ADD方法,而响应者使用SAD_GETSPIand SAD_UPDATE。
使用例如CREATE_CHILD_SAIKEv2 中的交换建立 IPsec SA 的过程可以大致如下所示:
Initiator Responder
SAD_GETSPI (inbound SA) -----------> {select algorithms and derive keys}
SAD_ADD (outbound SA)
SAD_GETSPI (inbound SA)
{derive keys} <----------- SAD_UPDATE (inbound SA)
SAD_UPDATE (inbound SA)
SAD_ADD (outbound SA)
- 发起者将其入站 SA 的 SPI 连同密码算法的提议以及如果使用完美前向保密,其 Diffie-Hellman 因子一起发送给响应者。
- 响应者选择合适的算法并派生密钥(可选地使用 DH)并继续安装 SA。
- 然后它将其入站 SPI 与所选算法(以及可选的 DH 因子)一起返回给发起者,发起者现在能够在其一侧安装 SA。
此外,两个对等点交换流量选择器,这些选择器指定了已建立的 SA 将覆盖的网络流量。
SAD_UPDATE: "请更新 SPI x,将 SPI 设置为 y。"
不是SAD_UPDATE这样。它实际上根本没有改变 SPI,而是 SA 的所有(或部分)其他方面,这些主要是加密/完整性算法和密钥(但也可能包括其他东西,如封装或反重放窗口大小)。
您通常想要调用SAD_GETSPI而SAD_UPDATE不是简单地调用SAD_ADD入站 SA(即使在响应者上,所有信息都可用)的原因是 SAD 通常由操作系统的内核管理,而 IKE 守护程序在用户空间中运行。因此,调用SAD_GETSPI将确保 SPI 实际上是本地唯一的。如果例如在系统上同时使用两个 IKE 守护程序(用于 IKEv1 和 IKEv2)甚至手动管理 SA 的工具(如ip xfrm或setkey),则可能无法保证。
但可以想象,在某些系统上可能会有一种简化,允许响应者在SAD_ADD不指定 SPI 的情况下进行调用,然后 SAD 将分配一个,安装 SA,并返回新的 SPI。但这需要键控守护程序对这种特殊情况进行特殊处理(否则它可以简单地调用SAD_ADD出站 SA 和SAD_GETSPI/SAD_UPDATE入站 SA,无论它是作为发起者还是响应者这样做)。
RFC 2367 (PF_KEYv2) 提供了有关这些操作的更多信息。