跳到主要内容

3.1. Generating an Outgoing SNMP Message (生成出站 SNMP 消息)

3.1. Generating an Outgoing SNMP Message (生成出站 SNMP 消息)

本节描述 SNMP 引擎在代表用户使用特定 securityLevel 生成包含管理操作 (如请求、响应、通知或报告) 的消息时所遵循的过程。

步骤 1: 确定用户信息 (Determine User Information)

1a) 响应或报告消息 (Response or Report Message)

如果传递了任何 securityStateReference (响应或报告消息), 则从 cachedSecurityData 中提取有关用户的信息。现在可以丢弃 cachedSecurityData。

  • securityEngineID 设置为本地 snmpEngineID
  • securityLevel 设置为调用模块指定的值

1b) 请求或通知消息 (Request or Notification Message)

否则, 根据 securityName, 从本地配置数据存储 (LCD, usmUserTable) 中提取有关目标 snmpEngineID (由 securityEngineID 指定) 处的用户的信息。

如果 LCD 中没有该用户的信息, 则向调用模块返回错误指示 (unknownSecurityName)。

步骤 2: 检查隐私支持 (Check Privacy Support)

如果 securityLevel 指定消息要受到保护免受泄露, 但用户不同时支持认证和隐私协议, 则无法发送消息。

向调用模块返回错误指示 (unsupportedSecurityLevel)。

注意: 隐私 (加密) 需要认证。不允许 noAuth + privacy 的组合。

步骤 3: 检查认证支持 (Check Authentication Support)

如果 securityLevel 指定消息要进行认证, 但用户不支持认证协议, 则无法发送消息。

向调用模块返回错误指示 (unsupportedSecurityLevel)。

步骤 4: 加密消息 (如果需要) (Encrypt the Message)

4a) 使用隐私 (authPriv)

如果 securityLevel 指定消息要受到保护免受泄露, 则根据用户的隐私协议加密表示序列化 scopedPDU 的字节序列。

为此, 根据抽象原语调用实现用户隐私协议的隐私模块:

statusInformation =       -- 成功或失败
encryptData(
IN encryptKey -- 用户的本地化 privKey
IN dataToEncrypt -- 序列化的 scopedPDU
OUT encryptedData -- 序列化的 encryptedPDU
OUT privParameters -- 序列化的隐私参数
)

参数 (Parameters):

  • statusInformation: 指示加密过程是否成功

  • encryptKey: 用户的本地化私有 privKey 是可以由加密算法使用的秘密密钥

  • dataToEncrypt: 序列化的 scopedPDU 是要加密的数据

  • encryptedData: encryptedPDU 表示加密的 scopedPDU, 编码为 OCTET STRING

  • privParameters: 隐私参数, 编码为 OCTET STRING

错误处理 (Error Handling):

如果隐私模块返回失败, 则无法发送消息, 并向调用模块返回错误指示 (encryptionError)。

如果隐私模块返回成功, 则:

  • 返回的 privParameters 放入 securityParameters 的 msgPrivacyParameters 字段
  • encryptedPDU 作为正在准备的消息的有效负载

4b) 不使用隐私 (noAuthNoPriv 或 authNoPriv)

如果 securityLevel 指定消息不受保护免受泄露, 则:

  • 将零长度 OCTET STRING 编码到 securityParameters 的 msgPrivacyParameters 字段
  • 明文 scopedPDU 作为正在准备的消息的有效负载

步骤 5: 设置 msgAuthoritativeEngineID

将 securityEngineID 编码为 OCTET STRING 到 securityParameters 的 msgAuthoritativeEngineID 字段。

注意: 对于请求消息, 空的 (零长度) securityEngineID 是可以的, 因为这将导致远程 (权威) SNMP 引擎返回报告 PDU, 该报告 PDU 的 securityParameters 中的 msgAuthoritativeEngineID 中包含正确的 securityEngineID。这是发现机制的一部分。

步骤 6: 设置 snmpEngineBoots 和 snmpEngineTime

6a) 已认证消息 (Authenticated Message)

如果 securityLevel 指定消息要进行认证, 则使用 LCD 中与 securityEngineID 对应的当前 snmpEngineBootssnmpEngineTime 值。

6b) 响应或报告消息 (未认证) (Response or Report Message - unauthenticated)

否则, 如果这是响应或报告消息, 则使用 LCD 中与本地 snmpEngineID 对应的当前 snmpEngineBootssnmpEngineTime 值。

6c) 其他未认证消息 (Other Unauthenticated Messages)

否则 (这是未认证的请求或通知), snmpEngineBootssnmpEngineTime 都设置为零。

步骤 7: 编码时间值 (Encode Time Values)

msgAuthoritativeEngineBootsmsgAuthoritativeEngineTime 的值设置为步骤 6 中确定的值, 并编码为 INTEGER 值到 securityParameters 中。

步骤 8: 设置 msgUserName

msgUserName 字段设置为 securityName, 并编码为 OCTET STRING 到 securityParameters 中。

步骤 9: 认证消息 (如果需要) (Authenticate the Message)

9a) 使用认证 (authNoPriv 或 authPriv)

如果 securityLevel 指定消息要进行认证, 则根据用户的认证协议对消息进行认证。

msgAuthenticationParameters 字段设置为根据认证协议规则序列化的:

authenticationInformation =
authenticationAlgorithm(
IN authKey -- 用户的本地化 authKey
IN wholeMsg -- 未认证的消息
)

过程 (Process):

  1. msgAuthenticationParameters 字段临时填充由认证协议确定的值 (对于 HMAC-MD5-96 和 HMAC-SHA-96 通常为 12 个零字节)

  2. 对整个序列化消息 (wholeMsg) 运行认证算法

  3. 认证算法的输出 (MAC/摘要) 替换 msgAuthenticationParameters 中的临时值

参数 (Parameters):

  • authKey: 用户的本地化私有 authKey 是认证算法使用的秘密密钥

  • wholeMsg: 未认证的消息 (msgAuthenticationParameters 临时设置为零)

  • authenticationInformation: 计算的认证摘要/MAC

将计算的认证摘要放入 msgAuthenticationParameters 字段。

9b) 不使用认证 (noAuthNoPriv)

如果 securityLevel 指定消息不进行认证, 则将零长度 OCTET STRING 编码到 msgAuthenticationParameters 字段。

步骤 10: 完成并返回 (Finalize and Return)

将完成的 wholeMsg 与指示成功的 statusInformation 一起返回给调用模块。

Message Generation Flow Summary (消息生成流程摘要)

1. 查找用户信息 (从缓存或 LCD)
2. 验证安全级别支持
3. 检查认证支持
4. 加密 scopedPDU (如果是 authPriv)
└─> 设置 msgPrivacyParameters
5. 设置 msgAuthoritativeEngineID
6. 确定时间值 (boots/time)
7. 编码时间值
8. 设置 msgUserName
9. 认证消息 (如果是 authNoPriv 或 authPriv)
└─> 计算 MAC/摘要
└─> 设置 msgAuthenticationParameters
10. 返回完整的 wholeMsg

Special Cases (特殊情况)

Discovery Messages (发现消息)

对于发现消息:

  • securityEngineID 为空 (零长度)
  • securityLevel 为 noAuthNoPriv
  • msgAuthoritativeEngineID 为空
  • msgAuthoritativeEngineBoots 和 msgAuthoritativeEngineTime 为零
  • msgUserName 为空
  • msgAuthenticationParameters 为空
  • msgPrivacyParameters 为空

Notification Messages (通知消息)

对于通知消息 (Trap, Inform):

  • 通知发起者 (notification originator) 是权威引擎
  • securityEngineID 是本地 snmpEngineID
  • 使用本地 snmpEngineBoots 和 snmpEngineTime 值

Error Conditions (错误条件)

可能返回以下错误指示:

错误 (Error)条件 (Condition)
unknownSecurityName在 LCD 中未找到用户
unsupportedSecurityLevel用户缺少所需的认证或隐私协议
encryptionError隐私模块未能加密数据

Implementation Notes (实现注意事项)

  1. 缓存的安全数据 (Cached Security Data): 对于响应和报告消息, 从处理原始请求消息期间保存的缓存数据中检索安全信息

  2. 时间同步 (Time Synchronization): 已认证消息使用 LCD 中目标权威引擎的时间值。这些值必须保持同步 (参见第 4 节关于发现)

  3. 密钥使用 (Key Usage): 必须使用特定 securityEngineID 的本地化 authKey 和 privKey

  4. 消息大小 (Message Size): 实现必须确保生成的消息不超过与远程引擎协商的 maxMessageSize