XFRM

同步补丁工作基于 Krisztian <hidden@balabit.hu> 和其他人的初始补丁,以及 Jamal <hadi@cyberus.ca> 的额外补丁。

同步的最终目标是能够插入属性并生成事件,以便安全地将 SA 从一台机器移动到另一台机器以实现高可用性 (HA) 目的。其思想是同步 SA,以便接管机器在访问 SA 时能够尽可能准确地处理 SA。

我们已经能够生成 SA 的添加/删除/更新事件。这些补丁增加了同步能力,并提供了准确的生命周期字节计数(以确保 SA 的正确衰减)和重放计数器,以避免重放攻击,并在故障转移时将损失降到最低。这样,备份可以像活动成员一样保持最新状态。

由于上述项会随着 SA 接收的每个数据包而变化,因此可能会生成大量事件。为此,我们还添加了一种类似 Nagle 的算法来限制事件。例如,我们将设置阈值,表示“当重放序列阈值达到或 10 秒过去时通知我”。这些阈值可以通过 sysctl 在系统范围内设置,也可以根据每个 SA 进行更新。

需要同步的已识别项目包括: - 生命周期字节计数器 请注意:如果假设故障转移机器是提前已知的,则生命周期时间限制不重要,因为时间倒计时的衰减并非由数据包到达驱动。 - 入站和出站的重放序列

1) 消息结构

nlmsghdr:aevent_id:可选-TLVs。

netlink 消息类型为

XFRM_MSG_NEWAE 和 XFRM_MSG_GETAE。

XFRM_MSG_GETAE 不包含 TLV。

XFRM_MSG_NEWAE 将至少包含两个 TLV(如下文进一步讨论)。

aevent_id 结构如下所示

struct xfrm_aevent_id {
          struct xfrm_usersa_id           sa_id;
          xfrm_address_t                  saddr;
          __u32                           flags;
          __u32                           reqid;
};

唯一的 SA 由 xfrm_usersa_id、reqid 和 saddr 的组合标识。

标志用于指示不同的事项。可能的标志包括

XFRM_AE_RTHR=1, /* replay threshold*/
XFRM_AE_RVAL=2, /* replay value */
XFRM_AE_LVAL=4, /* lifetime value */
XFRM_AE_ETHR=8, /* expiry timer threshold */
XFRM_AE_CR=16, /* Event cause is replay update */
XFRM_AE_CE=32, /* Event cause is timer expiry */
XFRM_AE_CU=64, /* Event cause is policy update */

这些标志的使用方式取决于消息的方向(内核<->用户)以及原因(配置、查询或事件)。这将在下面的不同消息中描述。

在 netlink 中将适当地设置 pid 以识别方向(发送到内核时为 0,从内核到用户空间时为 pid = 创建事件的进程 ID)

程序需要订阅多播组 XFRMNLGRP_AEVENTS 才能收到这些事件的通知。

2) TLV 反映不同的参数:

  1. 字节值 (XFRMA_LTIME_VAL)

此 TLV 包含自上次事件以来字节生命周期的运行/当前计数器。

b) 重放值 (XFRMA_REPLAY_VAL)

此 TLV 包含自上次事件以来重放序列的运行/当前计数器。

c) 重放阈值 (XFRMA_REPLAY_THRESH)

此 TLV 包含内核用于在重放序列超出时触发事件的阈值。

  1. 到期计时器 (XFRMA_ETIMER_THRESH)

这是一个以毫秒为单位的计时器值,用作 Nagle 值以限制事件的速率。

3) 参数的默认配置:

默认情况下,这些事件应关闭,除非至少有一个侦听器注册侦听多播组 XFRMNLGRP_AEVENTS。

安装 SA 的程序需要指定这两个阈值,但是为了不更改 racoon 等现有应用程序,我们还为这些不同参数提供了默认阈值,以防它们未被指定。

这两个 sysctl/proc 条目是

a) /proc/sys/net/core/sysctl_xfrm_aevent_etime 用于以 100 毫秒为增量单位提供 XFRMA_ETIMER_THRESH 的默认值。默认值为 10(1 秒)

b) /proc/sys/net/core/sysctl_xfrm_aevent_rseqth 用于以增量数据包计数提供 XFRMA_REPLAY_THRESH 参数的默认值。默认值为两个数据包。

4) 消息类型

  1. 由用户-->内核发出的 XFRM_MSG_GETAE。XFRM_MSG_GETAE 不携带任何 TLV。

响应是 XFRM_MSG_NEWAE,其格式基于 XFRM_MSG_GETAE 查询的内容。

响应将始终包含 XFRMA_LTIME_VAL 和 XFRMA_REPLAY_VAL TLV。 * 如果设置了 XFRM_AE_RTHR 标志,则也会检索 XFRMA_REPLAY_THRESH * 如果设置了 XFRM_AE_ETHR 标志,则也会检索 XFRMA_ETIMER_THRESH

  1. XFRM_MSG_NEWAE 由用户空间发出以配置,或由内核发出以宣布事件或响应 XFRM_MSG_GETAE。

  1. 用户 --> 内核以配置特定的 SA。

可以通过传递相应的 TLV 来更新任何值或阈值参数。

响应会返回给用户空间的发送者,以指示成功或失败。

如果成功,还会向任何侦听器发出带有 XFRM_MSG_NEWAE 的事件,如 iii) 中所述。

  1. 内核->用户方向,作为对 XFRM_MSG_GETAE 的响应

响应将始终包含 XFRMA_LTIME_VAL 和 XFRMA_REPLAY_VAL TLV。

如果 XFRM_MSG_GETAE 消息中明确请求,则将包含阈值 TLV。

  1. 内核->用户以事件形式报告,如果有人使用 XFRM_MSG_NEWAE(如上文 #i 所述)为 SA 设置了任何值或阈值。在这种情况下,会设置 XFRM_AE_CU 标志,通知用户此更改是更新的结果。消息将始终包含 XFRMA_LTIME_VAL 和 XFRMA_REPLAY_VAL TLV。

  2. 内核->用户以事件形式报告,当重放阈值或超时被超过时。

在这种情况下,会设置 XFRM_AE_CR(重放超出)或 XFRM_AE_CE(超时发生),以告知用户发生了什么。请注意,这两个标志是互斥的。消息将始终包含 XFRMA_LTIME_VAL 和 XFRMA_REPLAY_VAL TLV。

阈值设置的例外

如果 SA 受到突发流量的冲击,导致计时器阈值在未看到数据包的情况下到期,那么会观察到以下异常行为:计时器到期后的第一个数据包到达将触发超时事件;也就是说,我们不等待超时期限或达到数据包阈值。这样做是为了简单性和效率。

-JHS