SNMP协议小结
简单网络管理协议(SNMP:Simple Network Management Protocol)是由互联网工程任务组(IETF:Internet Engineering Task Force )定义的一套网络管理协议。该协议基于简单网关监视协议(SGMP:Simple Gateway Monitor Protocol),是网络中管理设备和被管设备之间的通信规则,它定义了一系列消息、方法和语法,用于实现管理设备对悲观设备的访问和管理。利用SNMP,一个管理工作站可以远程管理所有支持这种协议的网络设备,包括监视网络状态、修改网络设备配置、接收网络事件警告等。虽然SNMP开始时面向基于IP的网络管理,但作为一个工业标准也被成功用于电话网络管理。
SNMP基本原理
SNMP采用了Client/Server模型的特殊形式:代理/管理站模型。对网络的管理与维护是通过管理工作站与SNMP代理间的交互工作完成的。每个SNMP从代理负责回答SNMP管理工作站(主代理)关于MIB定义信息的各种查询。
SNMP网络元素分为NMS和Agent两种:
NMS(Network Management Station网络管理站)是运行SNMP客户端程序的工作站,能够提供非常友好的人机交互界面,方便网络管理员完成绝大多数的网络管理工作。NMS既可以指一台专门用来进行网络管理的服务器,也可以指某个设备中执行管理功能的一个应用程序。NMS可以向Agent发出请求,查询或修改一个或多个具体的参数值。同时,NMS可以接收Agent主动发送的Trap信息,以获知被管理设备当前的状态。
Agent是驻留在设备上的一个进程,负责接收、处理来自NMS的请求报文。Agent接收到NMS的请求信息后,完成查询或修改操作,并把操作结果发送给NMS,完成响应。同时,当设备发生故障或者其他事件的时候,Agent会主动发送Trap信息给NMS,通知设备当前的状态变化。
NMS是 SNMP网络的管理者,Agent是 SNMP网络的被管理者。NMS和 Agent之间通过 SNMP协议来交互管理信息。
使用SNMP的典型配置。整个系统必须有一个管理站(management station),它实际上是网控中心。在管理站内运行管理进程。在每个被管对象中一定要有代理进程。管理进程和代理进程利用SNMP报文进行通信,而SNMP报文又使用UDP来传送。
SNMP的协议版本
目前,设备的 SNMP Agent支持 SNMP v3版本,兼容 SNMP v1版本和SNMP v2c版本。
SNMP v1采用团体名 (Community Name)认证。 团体名用来定义SNMP NMS和SNMP Agent的关系。如果 SNMP 报文携带的团体名没有得到设备的认可,该报文将被丢弃。团体名起到了类似于密码的作用,用来限制 SNMP NMS对SNMP Agent的访问。
SNMP v2c也采用团体名认证。它在兼容 SNMP v1的同时又扩充了 SNMP v1的功能:它提供了更多的操作类型(GetBulk和InformRequest);它支持更多的数据类型(Counter64等);它提供了更丰富的错误代码,能够更细致地区分错误。
SNMP v3提供了基于用户的安全模型(USM,User-Based Security Model)的认证机制。用户可以设置认证和加密功能,认证用于验证报文发送方的合法性,避免非法用户的访问;加密则是对 NMS和 Agent之间的传输报文进行加密,以免被窃听。通过有无认证和有无加密等功能组合,可以为 SNMP NMS和SNMP Agent之间的通信提供更高的安全性。
NMS和 Agent的 SNMP版本匹配,是它们之间成功互访的前提条件。Agent可以同时配置多个版本,与不同的 NMS交互采用不同的版本。
管理信息结构SMI
SMI是SNMP的一部分,指定了在SNMP的MIB中用于定义管理目标的规则。SMI 是一种语言,是为了确保网络管理数据的语法和语义明确和无二义性而定义的语言。它是定义被管理网络实体中特定数据的语言。它定义了数据类型、对象模型,以及写入和修改管理信息的规则。SNMP中,数据类型并不多。这里我们就讨论这些数据类型,而不关心这些数据类型在实际中是如何编码的。
INTEGER
整型。一个变量虽然定义为整型,但也有多种形式。有些整型变量没有范围限制,有些
整型变量定义为特定的数值(例如,I P的转发标志就只有允许转发时的 1或者不允许转发时的2这两种),有些整型变量定义为一个特定的范围(例如,UDP和TCP的端口号就从0到65535)。
OCTER STRING
0或多个8 bit字节,每个字节值在0~255之间。对于这种数据类型和一种数据类型的BER编码,字符串的字节个数要超过字符串本身的长度。这些字符串不是以NULL结尾的字符串。
DisplayString
0或多个8 bit字节,但是每个字节必须是A S C I I码。在M I B - I I中,所有该类型的变量不能超过255个字符(0个字符是可以的)。
OBJECT IDENTIFIER
对象标识符,缩写OID。对象标识是一种数据类型,它指明一种“授权”命名的对象。“授权”的意思就是这些标识不是随便分配的,它是由一些权威机构进行管理和分配的。对象标识是一个整数序列,以点(“.”)分隔。这些整数构成一个树型结构,对象标识从树的顶部开始,顶部没有标识,以root表示(这和Unix中文件系统的树遍历方向非常类似)。下图显示了在SNMP中用到的这种树型结构。所有的MIB变量都从1.3.6.1.2.1这个标识开始。
树上的每个结点同时还有一个文字名。例如标识1.3.6.1.2.1就和iso.org.dod.internet.memt.mib对应。这主要是为了人们阅读方便。在实际应用中,也就是说在管理进程和代理进程进行数据报交互时,MIB变量名是以对象标识来标识的,当然都是以1.3.6.1.2.1开头的。上图中,我们除了给出了mib对象标识外,还给出了 iso.org.dod.internent.private.enterprises(1.3.6.1.4.1)这个标识。这是给厂家自定义而预留的。在Assigned Number RFC中列出了在该结点下大约400个标识。
IpAddress
4字节长度的OCTER STRING,以网络序表示的I P地址。每个字节代表I P地址的一个字段。
PhysAddress
OCTER STRING类型,代表物理地址(例如以太网物理地址为 6个字节长度)。
Counter
非负的整数,可从0递增到4 294 976 295。达到最大值后归0。
Gauge
非负的整数,取值范围为从0到4 294 976 295(或增或减)。达到最大值后锁定,直到复位。例如,MIB中的tcpCurrEstab就是这种类型的变量的一个例子,它代表目前在ESTABLISHED或COLES_WAIT状态的T C P连接数。
TimeTicks
时间计数器, 以0 . 0 1秒为单位递增,但是不同的变量可以有不同的递增幅度。所以在定义这种类型的变量的时候,必须指定递增幅度。例如, M I B中的s y s U p T i m e变量就是这种类型的变量,代表代理进程从启动开始的时间长度,以多少个百分之一秒的数目来表示。
SEQUENCE
这一数据类型与C程序设计语言中的“structure”类似。一个SEQUENCE包括0个或多个元素,每一个元素又是另一个ASN.1数据类型。例如,M I B中的UdpEntry就是这种类型的变量。它代表在代理进程侧目前“激活”的UDP数量(“激活”表示目前被应用程序所用)。在这个变量中包含两个元素:
1)IpAddress类型中的udpLocalAddress,表示I P地址。
2)INTEGER类型中的udpLocalPort,从0到6 5 5 3 5,表示端口号。
SEQUENCE OF
这是一个向量的定义,其所有元素具有相同的类型。如果每一个元素都具有简单的数据类型,例如是整数类型,那么我们就得到一个简单的向量(一个一维向量) 。但是我们将看到,SNMP在使用这个数据类型时,其向量中的每一个元素是一个SEQUENCE(结构)。因而可以将它看成为一个二维数组或表。
管理信息库MIB
任何一个被管理的资源都表示成一个对象,称为被管理的对象。MIB是被管理对象的集合。它定义了对象之间的层次关系以及对象的一系列属性,比如对象的名字、访问权限和数据类型等。每个Agent都有自己的MIB。NMS根据权限可以对MIB中的对象进行读/写操作。NMS、Agent和MIB之间的关系如图所示
MIB是以树形结构进行存储的,树的节点表示被管理对象,它可以用从根开始的一条路径唯一地识别(OID)。SNMP协议消息通过遍历MIB树形目录中的节点来访问网络中的设备。
SNMP报文
SNMP 5种协议数据单元
SNMP规定了5种协议数据单元PDU(也就是SNMP报文),用来在管理进程和代理之间的交换。SNMPv1/SNMPv2c实现机制基本一致,SNMPv2c丰富了错误码,新增了GetBulk操作。下面以在SNMPv1版本环境执行Get、GetNext和Set操作为例来描述SNMPv1/ SNMPv2c的实现机制。
get-request操作:从代理进程处提取一个或多个参数值。
NMS想要获取被管理设备MIB节点sysName的值(sysName对象在允许访问视图
内),使用public为可读团体名,过程如下:
(1) NMS 给 Agent 发送 Get 请求,请求报文主要字段将被设置为:Version 字段的值为 1,Community 字段的值为 public,PDU 里 Variable bindings 中Name1字段的值为 sysName.0。
(2) Agent 给 NMS 发送 Get 响应,说明是否获取成功。如果成功,则 Response PDU 里 Variable bindings 中 Value1 字段的值为设备的名字(比如Agent010-H3C);如果获取失败,则在 Error status 字段填上出错的原因,在 Error index填上出错的位置信息。
get-next-request操作:从代理进程处提取紧跟当前参数值的下一个参数值。
NMS想要获取被管理设备MIB节点sysName的下一个节点sysLocation的值(sysName和sysLocation对象都在允许访问视图内),使用public为可读团体名,过程如下:
(1) NMS 给 Agent 发送 GetNext 请求,请求报文主要字段将被设置为:Version字段的值为 1,Community字段的值为 public,PDU里 Variable bindings中Name1字段的值为 sysName.0。
(2) Agent 给 NMS 发送 GetNext 响应。如果成功,则 Response PDU 里Variable bindings 中 Name1 字段值为 sysName.0 的下一个节点sysLocation.0, Value1 字段的值为(比如 Beijing China);如果获取失败,则在 Error status 字段填上出错的原因,在 Error index 填上出错的位置信息。
set-request操作:设置代理进程的一个或多个参数值
NMS想要设置被管理设备MIB节点SysName的值为Device01,使用private为可写团体名,过程如下:
(1) NMS 给 Agent 发送 Set 请求,请求报文主要字段将被设置为:Version 字段的值为 1,Community 字段的值为 private,PDU 里 Variable bindings 中Name1字段的值为 sysName.0,Value1字段的值填为 Device01。
(2) Agent 给 NMS 发送 Set 响应,说明是否设置成功。如果成功,则 Response PDU 里 Variable bindings 中 Value1 字段的值填为设备的新名字(比如Device01);如果设置失败,则在 Error status 字段填上出错的原因,在Error index填上出错的位置信息。
get-response操作:返回的一个或多个参数值。这个操作是由代理进程发出的,它是前面三种操作的响应操作。
trap操作:代理进程主动发出的报文,通知管理进程有某些事情发生。
当设备发生某些异常需要通知NMS时,Agent会主动发出Trap报文。例如:设备某端口网线被拔出,Agent发送linkDown的Trap消息给NMS。Version字段的值为1,Community字段的值为public,PDU中enterprise字段为sysObjectID.0的取值(比如enterprise.25506),Generic trap字段值为linkDown,Variable bindings字段携带接口相关信息。
前面的3种操作是由管理进程向代理进程发出的,后面的2个操作是代理进程发给管理进程的,为了简化起见,前面3个操作今后叫做get、get-next和set操作。图4描述了SNMP的这5种报文操作。请注意,在代理进程端是用熟知端口161接收get或set报文,而在管理进程端是用熟知端口162来接收trap报文。
下图是封装成UDP数据报的5种操作的SNMP报文格式。
(1)公共SNMP首部
共三个字段:
l 版本
写入版本字段的是版本号减1,对于SNMP(即SNMPV1)则应写入0。
l 共同体(community)
共同体就是一个字符串,作为管理进程和代理进程之间的明文口令,常用的是6个字符“public”。
l PDU类型
根据PDU的类型,填入0~4中的一个数字,其对应关系如表2所示意图。
表2 PDU类型
PDU类型 | 名称 |
0 | get-request |
1 | get-next-request |
2 | get-response |
3 | set-request |
4 | trap |
(2)get/set首部
l 请求标识符(request ID)
这是由管理进程设置的一个整数值。代理进程在发送get-response报文时也要返回此请求标识符。管理进程可同时向许多代理发出get报文,这些报文都使用UDP传送,先发送的有可能后到达。设置了请求标识符可使管理进程能够识别返回的响应报文对于哪一个请求报文。
l 差错状态(error status)
由代理进程回答时填入0~5中的一个数字,见表3的描述。
表3 差错状态描述
差错状态 | 名字 | 说明 |
0 | noError | 一切正常 |
1 | tooBig | 代理无法将回答装入到一个SNMP报文之中 |
2 | noSuchName | 操作指明了一个不存在的变量 |
3 | badValue | 一个set操作指明了一个无效值或无效语法 |
4 | readOnly | 管理进程试图修改一个只读变量 |
5 | genErr | 某些其他的差错 |
l 差错索引(error index)
当出现noSuchName、badValue或readOnly的差错时,由代理进程在回答时设置的一个整数,它指明有差错的变量在变量列表中的偏移。
(3)trap首部
l 企业(enterprise)
填入trap报文的网络设备的对象标识符。此对象标识符肯定是在图3的对象命名树上的enterprise结点{1.3.6.1.4.1}下面的一棵子树上。
l trap类型
此字段正式的名称是generic-trap,共分为表4中的7种。
表4 trap类型描述
trap类型 | 名字 | 说明 |
0 | coldStart | 代理进行了初始化 |
1 | warmStart | 代理进行了重新初始化 |
2 | linkDown | 一个接口从工作状态变为故障状态 |
3 | linkUp | 一个接口从故障状态变为工作状态 |
4 | authenticationFailure | 从SNMP管理进程接收到具有一个无效共同体的报文 |
5 | egpNeighborLoss | 一个EGP相邻路由器变为故障状态 |
6 | enterpriseSpecific | 代理自定义的事件,需要用后面的“特定代码”来指明 |
当使用上述类型2、3、5时,在报文后面变量部分的第一个变量应标识响应的接口。
l 特定代码(specific-code)
指明代理自定义的时间(若trap类型为6),否则为0。
l 时间戳(timestamp)
指明自代理进程初始化到trap报告的事件发生所经历的时间,单位为10ms。例如时间戳为1908表明在代理初始化后1908ms发生了该时间。
(4)变量绑定(variable-bindings)
指明一个或多个变量的名和对应的值。在get或get-next报文中,变量的值应忽略。
SNMPv2c报文
比较SNMPv1而言,SNMPv2c新增了GetBulk操作报文。GetBulk操作所对应的基本操作类型是GetNext操作,通过对Non repeaters和Max repetitions参数的设定,高效率地从Agent获取大量管理对象数据。
SNMPv2c 修改了 Trap 报文格式。 SNMPv2c Trap PUD 采用 SNMPv1 Get/GetNext/Set PDU的格式,并将sysUpTime和snmpTrapOID作为Variable bindings中的变量来构造报文。