跳到主要内容

4. 控制消息属性值对

为了在允许互操作的同时最大化可扩展性, L2TP 全文使用一种统一方法来编码消息类型和消息体. 本文档其余部分将这种编码称为 AVP (Attribute-Value Pair, 属性值对).

4.1 AVP 格式

每个 AVP 编码如下:

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|M|H| rsvd | Length | Vendor ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Type | Attribute Value...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
[until Length is reached]... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

前六位是位掩码, 描述 AVP 的一般属性.

本文档定义其中两位, 其余位保留供未来扩展使用. 保留位 MUST 设置为 0. 如果收到的 AVP 中某个保留位设置为 1, 则 MUST 将其视为未识别 AVP.

Mandatory (M) bit: 控制实现收到无法识别的 AVP 时所需的行为. 如果与特定会话相关联的消息中, 未识别 AVP 的 M 位被设置, 则与该消息关联的会话 MUST 终止. 如果与整个隧道相关联的消息中, 未识别 AVP 的 M 位被设置, 则整个隧道 (以及其中所有会话) MUST 终止. 如果 M 位未设置, 未识别 AVP MUST 被忽略. 随后必须继续处理控制消息, 就像该 AVP 不存在一样.

Hidden (H) bit: 标识 AVP 的 Attribute Value 字段中的数据被隐藏. 此能力可用于避免在 AVP 中以明文传递用户密码等敏感数据. 第 4.3 节描述执行 AVP 隐藏的过程.

Length: 编码此 AVP 中包含的八位组数量 (包括 Overall Length 和位掩码字段). Length 可以按 6 加上 Attribute Value 字段的八位组长度计算. 该字段本身为 10 位, 因此单个 AVP 最多允许 1023 个八位组数据. AVP 的最小 Length 为 6. 如果长度为 6, 则 Attribute Value 字段不存在.

Vendor ID: IANA 分配的 "SMI Network Management Private Enterprise Codes" [RFC1700] 值. 值 0 对应 IETF 采纳的属性值, 用于本文档定义的所有 AVP. 任何希望实现自身 L2TP 扩展的厂商都可以使用自己的 Vendor ID 和私有 Attribute 值, 以保证不会与其他厂商的扩展或未来 IETF 扩展冲突. 注意, Vendor ID 分配了 16 位, 因此此功能限制为前 65,535 个企业.

Attribute Type: 一个 2 八位组值, 在给定 Vendor ID 下定义的所有 AVP 中具有唯一解释.

Attribute Value: 这是由 Vendor ID 和 Attribute Type 指示的实际值. 它紧随 Attribute Type 字段之后, 占用 Length 指示的剩余八位组 (即 Length 减去 6 个八位组报头). 如果 Length 为 6, 则该字段不存在.

4.2 Mandatory AVPs

收到设置了 M-bit 的未知 AVP, 对其关联的会话或隧道是灾难性的. 因此, M 位应只为对会话或隧道正确运行绝对关键的 AVP 定义. 此外, 如果 LAC 或 LNS 收到设置了 M-bit 的未知 AVP 并因此关闭会话或隧道, 则发送该 Mandatory AVP 的对等方必须完全承担造成不可互操作情形的责任. 在定义设置 M-bit 的 AVP 之前, 尤其是厂商专用 AVP, 应确保这正是预期后果.

当存在足够好的替代方案时, 应使用该替代方案而不是 M-bit. 例如, 与其简单发送设置 M-bit 的 AVP 来判断特定扩展是否存在, 不如在请求消息中发送 AVP, 并期待回复消息中出现对应 AVP, 以此识别可用性.

对新 AVP (本文档未定义的 AVP) 使用 M-bit 时, MUST 提供关闭相关功能的配置能力, 使该 AVP 要么不发送, 要么发送但不设置 M-bit.

4.3 AVP Attribute Value 的隐藏

每个 AVP 报头中的 H 位提供一种机制, 用于向接收对等方指示 AVP 内容是被隐藏还是以明文存在. 此功能可用于隐藏用户密码或用户 ID 等敏感控制消息数据.

只有在 LAC 和 LNS 之间存在共享秘密时, H 位才 MUST 被设置. 该共享秘密与用于隧道认证的秘密相同 (参见第 5.1.1 节). 如果给定控制消息中的任何 AVP 设置了 H 位, 则消息中还必须存在 Random Vector AVP, 且它 MUST 位于第一个 H 位为 1 的 AVP 之前.

隐藏 AVP 值需要多个步骤. 第一步是取原始 (明文) AVP 的长度和值字段, 并按如下方式编码为 Hidden AVP Subformat:

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length of Original Value | Original Attribute Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... | Padding ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Length of Original Attribute Value: 要隐藏的 Original Attribute Value 的八位组长度. 这是必要的, 因为添加额外 Padding 后会丢失 Attribute Value 的原始长度信息.

Original Attribute Value: 要被隐藏的 Attribute Value.

Padding: 随机附加八位组, 用于掩盖正在隐藏的 Attribute Value 的长度.

为了掩盖被隐藏数据的大小, 生成的子格式 MAY 如上所示进行填充. Padding 不会改变放入 Length of Original Attribute Value 字段的值, 但会改变正在创建的结果 AVP 的长度.

接下来, 对以下内容的串接执行 MD5 哈希:

  • AVP 的 2 八位组 Attribute number
  • 共享秘密
  • 任意长度的随机向量

此哈希中使用的随机向量值在 Random Vector AVP 的值字段中传递. 发送方必须将该 Random Vector AVP 放在消息中任何隐藏 AVP 之前.

随后将 MD5 哈希值与 Hidden AVP Subformat 的前 16 个八位组 (或更少) 片段进行 XOR, 并放入 Hidden AVP 的 Attribute Value 字段.

如果 Subformat 长于 16 个八位组, 则对由共享秘密后接第一次 XOR 结果组成的八位组流计算第二个单向 MD5 哈希. 该哈希与 Subformat 的第二个 16 八位组 (或更少) 片段进行 XOR, 并放入 Hidden AVP 的 Value 字段中对应的八位组.

如有必要, 重复此操作, 使用共享秘密和每个 XOR 结果生成下一个哈希, 以便与值的下一片段进行 XOR.

该隐藏方法改编自 RFC 2138 [RFC2138], 后者取自 Kaufman, Perlman 和 Speciner [KPS] 所著《Network Security》一书的 "Mixing in the Plaintext" 章节. 下面是该方法的详细说明:

将共享秘密记为 S, Random Vector 记为 RV, Attribute Value 记为 AV. 将值字段拆分为 16 八位组块 p1, p2 等, 最后一个块在末尾用随机数据填充到 16 八位组边界. 将密文块记为 c(1), c(2) 等. 同时定义中间值 b1, b2 等.

b1 = MD5(AV + S + RV)   c(1) = p1 xor b1
b2 = MD5(S + c(1)) c(2) = p2 xor b2
. .
. .
. .
bi = MD5(S + c(i-1)) c(i) = pi xor bi

该字符串将包含 c(1)+c(2)+...+c(i), 其中 + 表示串接.

接收时, 随机向量取自待解隐藏 AVP 之前消息中遇到的最后一个 Random Vector AVP. 然后反向执行上述过程以得到原始值.

4.4 AVP 摘要

以下各节列出本文档定义的所有 L2TP AVP.

AVP 名称之后的列表指明使用每个 AVP 的消息类型. 每个 AVP 标题之后给出该 AVP 目的的简短描述, Attribute Value 格式的详细信息 (包括图形), 以及正确使用该 AVP 所需的任何附加信息.

4.4.1 适用于所有控制消息的 AVP

Message Type (All Messages)

Message Type AVP, Attribute Type 0, 标识此处的控制消息, 并定义确定后续 AVP 精确含义的上下文.

此 AVP 的 Attribute Value 字段格式如下:

 0                   1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Message Type 是一个 2 八位组无符号整数.

Message Type AVP MUST 是消息中的第一个 AVP, 紧随控制消息报头 (第 3.1 节定义) 之后. 已定义控制消息类型及其标识符列表见第 3.2 节.

Message Type AVP 中的 Mandatory (M) 位具有特殊含义. 它并不是指示 AVP 本身在不被识别时是否应被忽略, 而是指示控制消息本身是否应被忽略. 因此, 如果 Message Type AVP 中设置了 M-bit 且实现不知道该 Message Type, 则隧道 MUST 被清除. 如果未设置 M-bit, 实现可以忽略未知消息类型. 本文档定义的所有消息类型中, M-bit MUST 设置为 1. 此 AVP 不得被隐藏 (H-bit MUST 为 0). 此 AVP 的 Length 为 8.

Random Vector (All Messages)

Random Vector AVP, Attribute Type 36, 用于支持隐藏任意 AVP 的 Attribute Value.

此 AVP 的 Attribute Value 字段格式如下:

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Random Octet String ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Random Octet String 可以是任意长度, 但推荐随机向量至少为 16 个八位组. 该字符串包含随机向量, 用于计算 MD5 哈希以取回或隐藏某个隐藏 AVP 的 Attribute Value (参见第 4.2 节).

一条消息中可以出现多个 Random Vector AVP; 在这种情况下, 隐藏 AVP 使用最靠近且位于其之前的 Random Vector AVP. 此 AVP MUST 位于第一个设置 H 位的 AVP 之前.

此 AVP 的 M-bit MUST 设置为 1. 此 AVP MUST NOT 被隐藏 (H-bit MUST 为 0). 此 AVP 的 Length 为 6 加上 Random Octet String 的长度.

(续: 后续为其他 AVP 定义...)