概述
SNMPv3 - 用户安全模型
这是描述SNMP协议第三版安全特征的两篇文章中的第一篇. SNMPv3 RFCs描述了一个新的框架用于定义SNMP第一, 第二和第三版规范之间的关系. 这个框架以模块的方式划分并且绝大部分依赖以前的工作 (例如 SNMPv1, SNMPv2c, SNMPv2u, 和 SNMPv2*).
在这个框架内的两个核心模块是基于用户的安全模型 (USM) 和基于视图的访问控制模型 (VACM). USM 负责 SNMP 包的认证/加密/解密, VACM 负责管理MIB数据的访问. 本文概述了 USM, 下个月我们会看一下 VACM.
USM 的规范定义在 RFC 2574. 以前版本的SNMP有一个众所周知的弱点是缺乏一个坚固的, 一致的安全方案. 在设计 USM 的时候, 这些典型的安全威胁必须被解决:
USM 能保护SNMPv3包不受以上威胁, 它利用多用户中每一个用户提供私钥来认证和保证私密性. 指定使用的认证协议是 HMAC-MD5 和 HMAC-SHA. 指定的私密性协议是 CBC-DES. RFC 指出安全协议在该RFC被制定的时候被认为安全性对于USM是可接受的. 然而, 未来如果有需要模型允许指定新的认证和私密性协议.
概念
SNMPv3 介绍了许多新的概念. 大部分概念被框架中的多个模块用到. 这里是一些USM用到的概念:
SNMPv3 包格式
authentication
| msgSecurityModel
| /
| msgAuthoritativeEngineBo
ots |
SNMP第三版的包结构为了适应像USM之类的安全模型做了改变.
USM 安全参数
USM 使用 msgSecurityParameters 存放五个值. 这些值被用于认证模块来确保数据完整性和数据源认证, 被用于时序模块来保护消息延迟或重传, 以及被用于私密性模块来保护消息不被泄露.
代理发现
正如上面提到的, USM 要求授权引擎的 snmpEngineID, snmpEngineBoots, 和 snmpEngineTime 被放置在 msgSecurityParameters 中. 这要求未认证引擎 (例如. 管理器) 在GET, NEXT, 或 SET操作完成以前为认证引擎 (例如 代理) 准备这些值.
有一个发现过程来达到这个目的. 这里会遇到有两个发现事务. 第一个是发现代理的 snmpEngineID. 第二个是发现 snmpEngineBoots 和 snmpEngineTime. 管理器仅仅在安全级别为authNoPriv或authPriv时需要第二个事务. 这是因为 msgAuthoritativeEngineBo
ots 和 msgAuthoritativeEngineTi
me 被时序模块使用而该模块只是认证过程的一部分.
第一个发现事务被发送SNMPv3包的管理器初始化, 这个包的msgAuthoritativeEngineID
包含一个伪造的值. 当代理接收到一个跟它拥有的 msgAuthoritativeEngineID
不同的包, 这个包会被丢弃并且一个发现包被返回给管理器. 返回的发现包包含正确的 snmpEngineID, 管理器必须使用这个 snmpEngineID.
第二个发现机制要求一个认证过的包被发送给代理. 这意味着认证标志被设置在 msgFlags, 并且 msgAuthenticationParamet
ers 包含计算过的该包的消息摘要. 用于认证该包的私钥来自 msgUserName 指定的用户. 当 msgAuthoritativeEngineBo
ots 和 msgAuthoritativeEngineTi
me 包含伪造的值时这是一个发现包. 当代理接收到这样的包, 首先做认证. 一旦认证完成, msgAuthoritativeEngineBo
ots 和 msgAuthoritativeEngineTi
me 值被检查. 由于值是伪造的, 该包被丢弃并且第二个发现包被返回给管理器. 返回的发现包是认证过的, 使用相同的用户, 包含正确的 snmpEngineBoots 和 snmpEngineTime 值, 管理器必须使用它们.
及时性
一旦管理器得知了代理的 snmpEngineBoots 和 snmpEngineTime, 管理器必须在本地维护这些值应该是多少. 这要求管理器每一秒都增加 snmpEngineTime 这样这个值会非常接近代理维护的主值. 如果 snmpEngineTime 溢出了, 那么 snmpEngineBoots 必须增加. 管理器必须为每一个它想要与之通讯的代理在本地维护这些值.
代理进行及时性检查被认为是认证过程的一部分并且在接收到的包被认证过之后立刻进行. 如果 msgAuthoritativeEngineBo
ots 跟代理的当前 snmpEngineBoots 值不同, 该包被丢弃并且一个发现包被发送回管理器. 如果检查通过, 那么 msgAuthoritativeEngineTi
me 被用于跟代理的 snmpEngineTime 值做检查. 如果两个值的差异多于150秒, 这个包被丢弃并且一个发现包被发送回管理器. 如果两个检查都通过, 那么该包被认为被及时接收到并且继续处理.
+/- 150 秒这个用于比较 snmpEngineTime 的值是RFC默认指定. 这个值可以根据你的网络的速度和大小进行合适的修改.
认证
USM 指定使用消息摘要5 (MD5) 和安全哈希算法1 (SHA-1) 算法来认证 SNMPv3 包. 这些算法用于为可变长度的消息创建唯一固定大小的消息摘要, 也称为消息签名或指纹. MD5 创建 128 位的摘要 (16 字节) 而 SHA-1 创建 160 位的摘要 (20 字节). MD5 和 SHA-1 都不能直接用于消息认证代码因为他们不使用私钥作为输入来导出计算过的消息摘要. 这就是为什么使用消息认证密钥哈希
(HMAC) 算法跟 MD5 和 SHA-1 组合使用来计算消息摘要. HMAC 算法定义了一个过程会在数据中加入私钥然后计算 MD5 或 SHA-1 消息摘要. 这保证了要为同样的数据计算等同消息摘要必须共享一个公共的私钥. 这里是发送和接收认证过的 SNMPv3 包要采取的步骤:
发送认证的 SNMPv3 包:
接收认证的 SNMPv3 包:
私密性
USM 指定使用 Cipher Block Chaining mode to the Data Encryption Standard (CBC-DES) 算法来加密和解密 SNMPv3 包. 加密的范围仅仅覆盖包含scopedPDU, 其中包含 PDU 和用于VACM的上下文数据. DES 算法接受三个输入. 这些输入是要被加密的数据, 一个 56 位的私钥, 和一个 56 位的随机产生的 salt 用于确保两个不同的初始化向量被用于用相同私钥加密的两个输入的不同数据. 通讯中使用加密的双方必须共享同一个私钥和 salt 用于推导初始化向量. 私钥存储在用户表, salt 随着包的 msgPrivacyParameters 传递. 这里是发送和接收加密包的步骤.
发送加密的 SNMPv3 包:
接收加密的 SNMPv3 包:
用户表
每一个代理维护一个用户表用于存储所有能够通过SNMP访问系统的用户. 表中的每一个用户项包含下列信息, 所有这些都可以通过对USM MIB的SNMP操作来修改:
用户表有一个相关联的叫做usmUserSpinLock的自旋锁. 自旋锁是一个建议性锁用于允许几个 SNMP 管理器协同尝试修改一个 MIB 表. 概念很简单. 任何是有有一个代理要对用户表做修改, 管理器必须通过GET命令获取 usmUserSpinLock 的值. 管理器发送SET命令给代理, 其中包含设置 usmUserSpinLock PDU以及用户表中要被修改的变量. SET命令中 usmUserSpinLock 的值必须是之前通过GET命令取得的. 一旦代理接收到包含SET命令的消息, usmUserSpinLock 立刻被处理. 如果当前 usmUserSpinLock 的值跟SET命令中的指定的值不一样, SET 操作失败并返回错误. 如果两个值相同, SET命令的PDU指定的用户表的变量被设置. 当代理处理完整个PDU, usmUserSpinLock 的值加1. 正如你所见, 如果 usmUserSpinLock 的值跟设置的时候不同, 那么用户表从初次获得 usmUserSpinLock 的值以后被修改过.
本地密钥
本地私钥的概念是允许在许多不同的代理对一个用户使用相同的密码. 强迫每个代理为存在的用户记住不同的密码是非常不灵活的. 本地密钥通过一个哈希函数(例如 MD5 或 SHA-1)根据一个私有的密码和用户存在的代理的 snmpEngineID 来计算. 结果是每个代理的密钥都完全不同, 尽管它们使用了相同的密码.
改变密钥
USM 引入了 KeyChange 类型来描述使用私钥的习惯. KeyChange 定义提供了一个安全的方法来通过网络发送本地密钥这样允许用户改变他们的密钥. 当用户要改变他们的密钥时会碰到以下步骤:
管理器:
代理: (接收到 KeyChange SET 操作以后)
创建/克隆 用户
在代理的用户表创建一个新的用户是可能的. 这通过克隆一个存在的用户来实现. 所有的数据从被克隆的用户拷贝到新创建用户的项中. 一旦新的项被创建, 建议立刻改变密钥. 注意你只能通过克隆另一个已存在的用户来创建新的用户. 这要求该代理的用户表必须被初始化为包含你的环境中需要的最小的用户集合.
Using your SNMPv3 manager of choice, 这里有个例子关于如何从已存在的名叫foo的用户创建一个新用户并改变密钥. 注意被创建的新用户的实际名字没有显示在这里, 因为这个名字由被设置的变量的OID索引指定. 用户表通过用户名来查找.
首先获得自旋锁的值然后创建用户. 为了确保新用户项不能被立刻使用, 设置它的状态为 createAndWait.
下一步, 改变私密性密钥. 注意你必须知道foo的私钥用于计算 KeyChange. privKeyChange 值通过被克隆的用户的私钥计算并且新的私钥用于新的用户. 确认使用自旋锁. 同时, usmUserPublic 变量可以被写下作为该包用户密钥的过程的一部分, 随后可以读取这个值来确定密钥改变是否完成.
如果新用户不再使用加密, 那么你可以设置 privProtocol 为 usmNoPrivProtocol 并且不再修改私密性密钥.
现在改变认证私钥. 注意你必须知道foo的认证私钥用于计算 KeyChange. authKeyChange 值通过被克隆的用户的认证密钥和用于新用户的密钥计算. 再一次确认使用自旋锁.
如果新用户不再使用认证, 那么你可以设置 authProtocol 为 usmNoAuthProtocol 并且不再改变认证密钥.
最后, 通过设置状态激活这个用户.
结论
这个USM的概述应该使你理解SNMPv3包的认证和加密/解密涉及哪些东西. 另外, 你可以开始考虑当你部署支持SNMPv3的路由器, 交换机和服务器时如何配置你的环境中的代理. 下个月我将会看一下VACM以及展示它如何用于管理到MIB数据的访问.
参考
转自:
http://blog.sina.com.cn/s/blog_63ec20a10101icnj.html
最后
以上就是土豪高山为你收集整理的SNMPv3 - 用户安全模型的全部内容,希望文章能够帮你解决SNMPv3 - 用户安全模型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复