使用 AH 协议的流量不能被伪装。AH 协议包含跨越 IP 地址的加密校验和,伪装网关无法正确地重新生成该校验和。因此,所有伪装的 AH 流量都将被丢弃,因为它们具有无效的校验和。
使用传输模式 ESP 的 IPsec 流量也不能被可靠地伪装。传输模式 ESP 本质上加密了 IP 报头之后的所有内容。例如,由于 TCP 和 UDP 校验和包含源 IP 地址和目标 IP 地址,并且 TCP/UDP 校验和位于加密的载荷内,因此在伪装网关更改 IP 地址后无法重新计算,TCP/UDP 报头将在远程网关的校验和测试中失败,并且数据包将被丢弃。不包含有关源或目标 IP 地址信息的协议可能会成功地使用伪装的传输模式。
除了这些限制之外,当一次只有一个 IPsec 主机被伪装,或者当每个伪装主机与不同的远程主机通信时,IPsec 伪装是安全可靠的。当多个伪装主机与同一远程主机通信时,会出现一些弱点
如果两个或多个伪装主机使用传输模式与同一远程主机通信,并且远程主机的安全策略允许与同一对等方建立多个传输模式会话,则会话可能会发生冲突。发生这种情况是因为伪装网关的 IP 地址将被用于标识会话,并且任何其他标识信息都无法被伪装,因为它位于数据包的加密部分内。
如果远程主机的安全策略不允许与同一对等方建立多个传输模式会话,情况会更糟:最近协商的传输模式会话很可能会完全接管所有来自较旧会话的流量,导致较旧的会话“死亡”。虽然如果远程主机不期望接收流量,来自较旧传输模式 IPsec 会话的已建立会话可能会被快速重置,但至少会有一个信息包被发送到错误的host。此信息可能会被接收者丢弃,但它仍然会被发送。
因此,传输模式冲突可能导致两个会话之间信息泄漏或一个或两个会话终止。 如果有可能通过同一伪装网关尝试与其他传输模式 IPsec 会话到同一远程 IPsec 主机,则不建议通过伪装网关使用传输模式的 IPsec。
使用隧道模式和外部网络寻址(其中伪装的 IPsec 主机被分配来自远程主机网络的 IP 地址)的 IPsec 不会受到这些问题的影响,因为来自远程网络分配的 IP 地址将用于标识会话,而不是使用伪装主机的 IP 地址。
如果两个或多个伪装主机在与同一远程主机建立会话时,恰好在启动 ISAKMP 流量时选择了相同的发起方 cookie,则伪装网关会将所有 ISAKMP 流量路由到第二个主机。对于每个主机,在建立初始 ISAKMP 连接时,发生这种冲突的几率是 1/2^64(即非常小)。
纠正此问题需要将响应方 cookie 包含在用于路由入站 ISAKMP 流量的密钥中。此修改已集成到 2.2.x 内核的 IPsec 伪装中,并且在伪装主机启动 ISAKMP 交换和远程主机响应之间的短暂窗口期内,会丢弃任何会与当前未完成流量冲突的新 ISAKMP 流量来覆盖此窗口期。此修改将很快反向移植到 2.0.x 代码。
两个或多个与同一远程 IPsec 主机通信的伪装 IPsec 主机可能会协商使用相同的 SPI 值用于入站流量。如果发生这种情况,伪装网关会将所有入站流量路由到第一个接收到使用该 SPI 的入站流量的主机。对于每个未完成的 ESP 会话,发生这种情况的可能性约为 1/2^32,并且可能在任何重新密钥协商时发生。
由于 SPI 值指的是具有不同加密密钥的不同 SA,因此第一个主机将无法解密 предназначен для 其他主机的数据,因此不会发生数据泄漏。伪装网关无法检测或阻止此冲突。防止此冲突的唯一方法是让远程 IPsec 主机检查伪装主机提出的 SPI 值,以查看该 SPI 值是否已被来自同一 IP 地址的另一个 SA 使用。这样做不太可能,因为它对已经昂贵的操作(重新密钥协商)施加了更多开销,以使一小部分用户受益于相对罕见的事件。
这将在下一节中详细讨论。
为了避免这些问题,2.2.x 代码默认情况下阻止建立与同一远程主机的多个连接。如果可以接受与同一远程主机的多个连接暴露的弱点,则可以启用“并行会话”。
出于安全原因阻止并行会话可能会很烦人:IPsec 伪装代码无法嗅探会话并查看会话何时终止,因此即使会话在建立后立即终止,伪装表条目仍将在 IPsec 伪装表生存期内保持存在。如果阻止并行会话,则意味着在最近会话的伪装表条目超时并被删除之前,服务器将对其他客户端不可用。这可能长达几个小时。
在 ISAKMP 密钥交换中,ESP SPI 值被通信的部分是加密的,因此 ESP SPI 值必须通过检查实际的 ESP 流量来确定。此外,出站 ESP 流量不包含任何指示入站 SPI 将是什么的信息。这意味着没有完全可靠的方法可以将入站 ESP 流量与出站 ESP 流量关联起来。
IPsec 伪装尝试通过按远程主机对初始 ESP 流量进行序列化来关联入站和出站 ESP 流量。这意味着
有几种方法可能导致无法正确关联流量
/usr/src/linux/net/ipv4/ip_masq.c
(2.2.x 版本中为 ip_masq_ipsec.c
) 并增加 INIT 生存期或允许的 INIT 重试次数来解决此问题,但这会以增加阻塞(和 DoS)窗口为代价。
IPsec 伪装表生存期
内核配置参数略长于重新密钥协商间隔来解决此问题,重新密钥协商间隔是任何给定 SPI 对应该使用的最长时间。这里的问题是,如果您为许多远程服务器进行伪装,您可能不知道所有重新密钥协商间隔,或者某些服务器的重新密钥协商间隔可能设置为不合理的高值,例如几个小时。
最佳解决方案是某种方法来预加载伪装表,其中包含正确关联的出站 SPI/入站 SPI 对或远程主机 + 入站 SPI 到伪装主机的其他映射。这无法通过检查 ISAKMP 密钥交换来完成,因为它是加密的。可能可以使用 RSIP(也称为 Host-NAT)与伪装的 IPsec 主机通信,并请求在 SPI 信息协商完成后通知它。这正在调查中。如果要做些什么来实现这一点,最早也要在 2.3.x 系列中完成,因为 RSIP 是一个相当复杂的客户端/服务器 NAT 协议。
当收到具有新 SPI 的入站 ESP 数据包时,伪装防火墙会尝试猜测未关联的入站流量的目标伪装主机。如果入站 ESP 流量与已建立的会话或待处理的会话初始化不匹配,则数据包将发送到最近与该远程主机重新密钥协商的伪装主机。 “不正确”的伪装主机将丢弃该流量,因为它被不正确地加密,而“正确”的主机将获得其数据。当“正确”的主机响应时,正常的 ESP 初始化序列化过程就会发生。