《TCP/IP协议族》:SNMP协议一

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yexiangCSDN/article/details/86301263

一、SNMP协议概述

简单网络管理协议(SNMP:Simple Network Management Protocol)是由互联网工程任务组(IETF:Internet Engineering Task Force )定义的一套网络管理协议。该协议基于简单网关监视协议(SGMP:Simple Gateway Monitor Protocol)。利用SNMP,一个管理工作站可以远程管理所有支持这种协议的网络设备,包括监视网络状态、修改网络设备配置、接收网络事件警告等。 虽然SNMP开始是面向基于IP的网络管理,但作为一个工业标准也被成功用于电话网络管理。

二、SNMP协议标准RFC文档下载

关于下载地址:http://tools.ietf.org/rfc/index  这是RFC的一个索引页面,下面涉及到的RFC文档都在这个页面中有下载。

SNMPv1

SNMPv1 is defined by IETF (http://www.ietf.org ) in RFC 1157 plus a few supporting RFCs shown in the reference links. 

Reference
rfc1155.pdf : Structure and Identification of Management Information for TCP/IP based internets
rfc1156.pdf : Management Information Base Network
rfc1157.pdf : A Simple Network Management Protocol

SNMPv2

SNMPv2 is defined by IETF (http://www.ietf.org ) in RFC 1441 originally plus with a group of supporting and updating RFCs showing in the list below.

Reference

rfc1901.pdf : Introduction of community-based  SNMPv2 

rfc1902.pdf : Structure of Management Information for SNMPv2
rfc1903.pdf : Textual Conventions for SNMPv2
rfc1904.pdf : Conformance Statements for SNMPv2 

rfc1905.pdf : Protocol Operations for SNMPv2
rfc1906.pdf : Transport Mappings for SNMPv2
rfc1907.pdf : Management Information Base for SNMPv2

rfc1908.pdf : Coexistence between SNMPv1 and SNMPv2

SNMPv3

SNMPv3 is defined by IETF (http://www.ietf.org ) in RFC 3411 plus a group of supporting RFCs shown in the reference links.

Reference

rfc3410.pdf : Introduction and Applicability Statements for Internet Standard Management Framework
rfc3411.pdf : Architecture for Describing SNMP Frameworks
rfc3412.pdf : Message Processing and Dispatching for the SNMP
rfc3413.pdf : SNMP Applications
rfc3414.pdf : User-based Security Model (USM) for SNMPv3
rfc3415.pdf : View-based Access Control Model for the SNMP
rfc3584.pdf : Coexistence between SNMP v1, v2 and v3

三、SNMP工作原理

 SNMP采用特殊的C/S模式,即代理/管理站模型。对网络的管理与维护是通过管理工作站与SNMP代理间的交互工作完成的。每个SNMP从代理负责回答SNMP管理工作站(主代理)关于MIB定义信息的各种查询。

基于TCP/IP的网络管理包括两部分:网络管理站(manager)和被管理的网络单元(agent)。这些被管设备的共同点就是都运行TCP/IP协议。管理进程和代理进程之间的通信有两种方式,一种是管理进程向代理进程发出请求,询问参数值,另一种方式是代理进程主动向管理进程报告某些重要的事件。

基于TCP/IP的网络管理包含3个组成部分:

1. 一个管理信息库(MIB)管理信息库包含所有代理进程的所有可被查询和修改的参数。
2. 关于MIB的公用结构和表示符号,叫做管理信息结构SMI。例如:SMI定义计数器是一个非负整数,它的计数范围是0-3. 管理进程和代理进程之间的通信协议,叫做简单网络管理协议SNMP。SNMP包括数据交换的格式等,主要采用UDP协议。
 

SNMP的应用场景如图所示:

为什么需要SNMP?

作为运维人员,我们很大一部分的工作就是为了保证我们的网络能够正常、稳定的运行。因此监控,控制,管理各种网络设备成了我们日常的工作。在网络兴起的早期,维护方式就是运维人员蹲在近端对设备进行各种操作,当网络设备越来越多,网络规模越来越大时,管理工作会变得越来越单调乏味,这样的近端维护方式也近乎不可能。因此,远程管理网络的需求日益迫切,SNMP应运而生。使用SNMP,一个运行网管软件的工作站就能对成千上万的网络设备进行监控和信息采集,这些信息可以用来构建网络或者定位网络中的问题。

3.1 管理信息库MIB

管理信息库MIB:任何一个被管理的资源都表示成一个对象,称为被管理的对象。MIB是被管理对象的集合。它定义了被管理对象的一系列属性:对象的名称、对象的访问权限和对象的数据类型等。每个SNMP设备(Agent)都有自己的MIB。MIB也可以看作是NMS(网管系统)和Agent之间的沟通桥梁。它们之间的关系如图1所示。

                        图1 NMS Agent和MIB的关系

MIB文件中的变量使用的名字取自ISO和ITU管理的对象标识符(object identifier)名字空间。它是一种分级树的结构。如图2所示,第一级有三个节点:ccitt、iso、iso-ccitt。低级的对象ID分别由相关组织分配。一个特定对象的标识符可通过由根到该对象的路径获得。一般网络设备取iso节点下的对象内容。如名字空间ip结点下一个名字为ipInReceives的MIB变量被指派数字值3,因而该变量的名字为:

iso.org.dod.internet.mgmt.mib.ip.ipInReceives

相应的数字表示(对象标识符OID,唯一标识一个MIB对象)为: 1.3.6.1.2.1.4.3

                                                          图2 MIB树结构

当网络管理协议在报文中使用MIB变量时,每个变量名后还要加一个后缀,以作为该变量的一个实例。如ipInReceives的实例数字表示为:1.3.6.1.2.1.4.3.0.

需要注意的是,MIB中的管理对象的OID有些需要动态确定,如IP路由表,为了指明地址202.120.86.71的下一站路由(next hop),我们可以引用这样的实例:

iso.org.dod.internet.mgmt.mib.ip. ipRouteTable.ipRouteEntry.ipRouteNextHop.202.120.86.71, 相应的数字表示为:1.3.6.1.2.1.4.21.1.7.202.120.86.71

对于这种动态对象标识的实例,由于无法转换为预先指定的Readkey名称,与飞邻的产品架构冲突(需要动态生成可变Readkey),暂不考虑支持。

3.2 管理信息结构(SMI)

SMI定义了SNMP框架所用信息的组织、组成和标识,它还为描述MIB对象和描述协议怎样交换信息奠定了基础。

SMI定义的数据类型:

◆ 简单类型(simple)

Integer:整型是-2,147,483,648~2,147,483,647的有符号整数

octet string: 字符串是0~65535个字节的有序序列

OBJECT IDENTIFIER: 来自按照ASN.1规则分配的对象标识符集

◆    简单结构类型(simple-constructed)

SEQUENCE 用于列表。这一数据类型与大多数程序设计语言中的“structure”类似。一个SEQUENCE包括0个或更多元素,每一个元素又是另一个ASN.1数据类型

 SEQUENCE OF type 用于表格。这一数据类型与大多数程序设计语言中的“array”类似。其所有元素具有相同的类型. 一个表格包括0个或更多元素,每一个元素又是另一个ASN.1数据类型。

◆    应用类型(application-wide)

IpAddress: 以网络序表示的IP地址。因为它是一个32位的值,所以定义为4个字节;

counter:计数器是一个非负的整数,它递增至最大值,而后回零。在SNMPv1中定义的计数器是32位的,

即范围为 0-4294976295.

Gauge :也是一个非负整数,它可以递增或递减,但达到最大值时保持在最大值,直到复位。

即范围为 0-4294976295.

time ticks:是一个时间单位,表示以0.01秒为单位计算的时间;

3.3 管理信息库mib-2

 在Internet结点下面的第二个结点是mgmt(管理),标号是2。再下面是管理信息库,原先的结点名是mib。1991年定义了新的版本MIB-II,故结点名现改为mib-2,其标识为{1.3.6.1.2.1},或{Internet(1) .2.1}。这种标识为对象标识符。

最初的结点mib将其所管理的信息分为8个类别(上图展示了7个)。现在de mib-2所包含的信息类别已超过40个

应当指出,MIB的定义与具体的网络管理协议无关,这对于厂商和用户都有利。厂商可以在产品(如路由器)中包含SNMP代理软件,并保证在定义新的MIB项目后该软件仍遵守标准。用户可以使用同一网络管理客户软件来管理具有不同版本的MIB的多个路由器。当然,一个没有新的MIB项目的路由器不能提供这些项目的信息。

这里要提一下MIB中的对象{1.3.6.1.4.1},即enterprises(企业),其所属结点数已超过3000。例如IBM为11.3.6.1.4.1.2},Cisco为{1.3.6.1.4.1.9},Novell为{1.3.6.1.4.1.23},Huawei为{1.3.6.1.4.1.2011}。世界上任何一个公司、学校只要用电子邮件发往[email protected]进行申请即可获得一个结点名。这样各厂家就可以定义自己的产品的被管理对象名,使它能用SNMP进行管理。

3.4 OID

OID( 对象标识符),是SNMP代理提供的具有唯一标识的键值MIB(管理信息基)提供数字化OID到可读文本的映射

一个OID是一个唯一的键值对.

一个SNMP管理器(客户)可以向代理查询键值对中的特定信息。从程序员的角度看,这和导入大量的全局变量没有多少区别。SNMP的OID是可读或可写的。尽管向一个SNMP设备写入信息的情况非常少,但它是各种管理应用程序用来控制设备的方法(例如针对交换机的可管理GUI)。SNMP中有一个基本的认证框架,能够让管理员发送公共名来对OID读取或写入的认证。绝大多数的设备使用不安全的公共名 "public" 。

一个OID看起来和一个IPv6的地址很象,并且不同的厂商有不同的前缀等信息。OID都非常长,使得人们难以记住,或者对他非常感冒。因此,人们就设计了一种将数字OID翻译为人们可读的格式。这种翻译映射被保存在一个被称为 “管理信息基础"(Management Infomation Base) 或MIB的、可传递的无格式文本文件里。说白了MIB中存放的就是这些一系列数字字符串,然后客户端根据键找到对应值然后翻译。其实就是为了简化存储过程。

OID的编写规则和习惯:

SNMP OID是用一种按照层次化格式组织的、树状结构中的唯一地址来表示的,它与DNS层次相似。与其他格式的寻址方式类型,OID以两种格式加以应用:全名和先对名(有时称为“相关”)

完全验证格式从root根开始,并且向外移到某个设备的独立的质上。

OID可用人们可读的方式重写为:

所有完全验证OID都有 .iso.org.dod.internet.private 开始,数字表达为: .1.3.6.1.4. 。几乎所有的OID都会跟上企业(.1)和由IANA(互联网编号分配中心分配的)唯一的厂商标号。例如OID 789表示Network Appliance格式的厂商编号( NetApp )。厂商编号后面的是基于厂商实现的功能,并且各不相同。请注意,在iso.前面的 . 与DNS中的后点相似,正确验证的OID是有一个表示根的前缀 `. 开始的。

OID的相对格式,从企业值开始,略过所有的隐含地址。因此,我们可以用相对地址 enterprises.netapp.netappl.raid.diskSUmmary.diskSpaceCount.0 来表示上述的OID,或者用数字格式 .1.789.6.4.8.0 .

写OID的常用格式是用MIB名称和在MIB中定义的唯一键值。例如,我们可以用简写的格式重写上述OID

 NETWORK-APPLIANCE-MIB::diskSpareCount.0

MIB中OID的书写格式规则为::MIB Name::唯一键值.instance.

某些唯一键值,可用多个实例表示,这样所有的OID都以实例值结尾。这就是为什么你得注意到大多数OID都是以一个 .0 结尾的。

3.5  MIB内部结构

MIB的内部结构刚开始时会让人感觉有些奇怪和不好理解,不过它的结构非常好,你可以在不懂的情况下一个一个看进去。MIB的结构来源于IETF RFC1155和2578定义的管理信息结构。如果你想要修改或编写自己的MIB,在动手前理解SMI非常有帮助。

为了更好地理解他们是怎样工作的,我们先来看看MIB的头:
 

-- PowerNet-MIB {iso org(3) dod(6) internet(1) private(4)
-- enterprises(1) apc(318) }
PowerNet-MIB DEFINITIONS ::= BEGIN
 
IMPORTS
enterprises, IpAddress, Gauge, TimeTicks FROM RFC1155-SMI
DisplayString FROM RFC1213-MIB
OBJECT-TYPE FROM RFC-1212
TRAP-TYPE FROM RFC-1215;
 
apc OBJECT IDENTIFIER ::= { enterprises 318 }
products OBJECT IDENTIFIER ::= { apc 1 }
apcmgmt OBJECT IDENTIFIER ::= { apc 2 }
 
Comments can be inserted into a MIB by prepending them with two dashes. In the header the
 declaration BEGIN starts off the MIB. Imports can be used to pull information from other
 MIBs, typically those mandated by the MIB-II standard.

可以用行开头为 -- 的方法在MIB中加入注释。

在头部用 BEGIN`声明来开始MIB的定义。 

`Imports 可用来从其他MIB中提取信息,通常用它来提取MIB-II规范要求的内容。

MIB放置从enterprise值开始的OID地址的结构。

在此,enterprise值是318, 对应 "apc" (相对地址为 .1.318)。 通常之后会定义几个类别。注意在花括号间定义的两个值,其父地址后面跟一个它自己的地址。因此产品标识符有apc标识符表示,其父为enterprise标识符,以此类推。类别和自类别的类型通常跟在MIB头的后面,并且把有用的键值分割为子组。通过分段,各种值分别被列出,这样可用的值更容易浏览。MIB的真正好处在于对象类型的描述。以下是一个整形键值的例子:

upsBasicOutputStatus OBJECT-TYPE
SYNTAX INTEGER {
   unknown(1),
   onLine(2),
   onBattery(3),
   onSmartBoost(4),
   timedSleeping(5),
   softwareBypass(6),
   off(7),
   rebooting(8),
   switchedBypass(9),
   hardwareFailureBypass(10),
   sleepingUntilPowerReturn(11),
   onSmartTrim(12)
}
ACCESS read-only
STATUS mandatory
DESCRIPTION
   "The current state of the UPS. If the UPS is unable
    to determine the state of the UPS this variable is set
    to unknown(1)."
::= { upsBasicOutput 1 }

因此,在这里真正需要注意的是,MIB其实只是提供给我们一张我们想从某个SNMP代理中获得的可用OID的各种值的地图。一个MIB描述了在哪里找某个值、以及返回结果是什么。我们可以不用MIB与设备进行交互,只不过在理获得'Up'的返回值,要比‘1’的返回值要简单的多。通过利用Net-SNMP命令行工具,你可以决定你希望返回结果的输出样式(这种方式下使用“Up"这样的格式更好),或者你用脚本调用工具时(这种方式下使用”1“的格式就更好)。

四、SNMP报文介绍

SNMP中定义了五种消息类型:Get-Request、Get-Response、Get-Next-Request、Set-Request和Trap

1. get-request操作: SNMP 管理站用Get-Request消息从拥有SNMP代理的网络设备中检索信息提取一个或多个参数值。
2. get-next-request操作:Get-Next- Request用于和Get-Request组合起来查询特定的表对象中的列元素从代理进程处提取一个或多个参数的下一个参数值。
3. set-request操作: SNMP管理站用Set-Request 可以对网络设备进行远程配置(包括设备名、设备属性、删除设备或使某一个设备属性有效/无效等)。
4. get-response操作:由代理进程发出的一个或多个参数值。它是3种的响应操作。
5. trap操作:代理进程主动发出的报文,通知管理进程由事情发生。

前面3个操作是由管理进程向代理进程发出的,后两个是代理进程发给管理进程的。
说明:

◆前4种操作是简单的请求-应答方式,由于采用UDP协议,因此一定要有超时和重传机制。
◆管理进程采用UDP的161端口,代理进程使用UDP的162端口,因此一个系统可以同时为管理进程和代理进程。

SNMP工作流程如图

五、SNMP报文格式  

 下图是封装成UDP数据报的5种操作的SNMP报文格式。可见一个SNMP报文共有三个部分组成,即公共SNMP首部、get/set首部、trap首部、变量绑定。

1、公共SNMP首部

版本 : 写入版本字段的是版本号减1,对于SNMP(即SNMPV1)则应写入0。

共同体(community): 共同体就是一个字符串,作为管理进程和代理进程之间的明文口令,常用的是6个字符“public”。

PDU类型 :  根据PDU的类型,填入0~4中的一个数字,其对应关系如下图

2、get/set首部

请求标识符(request ID) : 

这是由管理进程设置的一个整数值。代理进程在发送get-response报文时也要返回此请求标识符。管理进程可同时向许多代理发出get报文,这些报文都使用UDP传送,先发送的有可能后到达。设置了请求标识符可使管理进程能够识别返回的响应报文对于哪一个请求报文

差错状态(error status):

由代理进程回答时填入0~5中的一个数字,见下图描述

差错索引(error index):

当出现noSuchName、badValue或readOnly的差错时,由代理进程在回答时设置的一个整数,它指明有差错的变量在变量列表中的偏移。

3、trap首部

企业(enterprise):

填入trap报文的网络设备的对象标识符。此对象标识符肯定是在图3的对象命名树上的enterprise结点{1.3.6.1.4.1}下面的一棵子树上。

 trap类型:

此字段正式的名称是generic-trap,共分为表4中的7种

 当使用上述类型2、3、5时,在报文后面变量部分的第一个变量应标识响应的接口。

特定代码(specific-code):指明代理自定义的时间(若trap类型为6),否则为0。

时间戳(timestamp) :

指明自代理进程初始化到trap报告的事件发生所经历的时间,单位为10ms。例如时间戳为1908表明在代理初始化后1908ms发生了该时间。

4、变量绑定(variable-bindings):

 指明一个或多个变量的名和对应的值。在get或get-next报文中,变量的值应忽略。

六、SNMP的运行过程

驻留在被管设备上的AGENT代理进程从UDP端口161接受来自网管站的串行化报文,经解码、团体名验证、分析得到管理变量在MIB树中对应的节点,从相应的模块中得到管理变量的值,再形成响应报文,编码发送回网管站。网管站得到响应报文后,再经同样的处理,最终显示结果。

下面根据RFC1157详细介绍Agent接受到报文后采取的动作:

首先解码生成用内部数据结构表示的报文,解码依据ASN.1的基本编码规则,如果在此过程中出现错误导致解码失败则丢弃该报文,不做进一步处理。

第二步:将报文中的版本号取出,如果与本Agent支持的SNMP版本不一致,则丢弃该报文,不做进一步处理。

第三步:将报文中的团体名取出,此团体名由发出请求的网管站填写。如与本设备认可的团体名不符,则丢弃该报文,不做进一步处理,同时产生一个陷阱报文。SNMPv1只提供了较弱的安全措施,在版本3中这一功能将大大加强。

第四步:从通过验证的ASN.1对象中提出协议数据单元PDU,如果失败,丢弃报文,不做进一不处理。否则处理PDU,结果将产生一个报文,该报文的发送目的地址应同收到报文的源地址一致。

根据不同的PDU,SNMP协议实体将做不同的处理:

6.1 GetRequest PDU

第一种情况:如果PDU中的变量名在本地维护的MIB树中不存在,则接受到这个PDU的协议实体将向发出者发送一个GetResponse报文,其中的PDU与源PDU只有一点不同:将ERROR-STATUS置为noSuchName,并在ERROR-INDEX中指出产生该变量在变量LIST中的位置。

第二种情况:如果本地协议实体将产生的响应报文的长度大于本地长度限制,将向该PDU的发出者发送一个GetResponse报文,该PDU除了ERROR-STATUS置为tooBig,ERROR-INDEX置为出错变量在变量LIST中的位置,与源PDU相同。

第三种情况:如果本地协议实体因为其他原因不能产生正确的响应报文,将向该PDU的发出者发送一个GetResponse报文,该PDU除了ERROR-STATUS置为genErr,ERROR-INDEX置为出错变量在变量LIST中的位置,其余与源PDU相同。

第四中情况:如果上面的情况都没有发生,则本地协议实体向该PDU的发出者发送一个GetResponse报文,该PDU中将包含变量名和相应值的对偶表,ERROR-STATUS为noError,ERROR-INDEX为0,request-id域的值应与收到PDU的request-id相同。

6.2 GetNextRequest PDU

GetNextRequest PDU的最重要的功能是表的遍历。

下面通过一个例子解释表遍历的过程:

被管设备维护如下路由表:

Destination NextHop Metric

9.1.2.3 99.0.0.3 3

10.0.0.51 89.1.1.42 5

10.0.0.99 89.1.1.42 5

假设网管站欲取得这张路由表的信息,该表的索引是目的网络地址。

网管站向被管设备发送一个GetNextRequest PDU,其中的受管对象的标识如下

GetNextRequest ( ipRouteDest, ipRouteNextHop, ipRouteMetric1 )

SNMP agent响应如下GetResponse PDU:

GetResponse (( ipRouteDest.9.1.2.3 = "9.1.2.3" ),

( ipRouteNextHop.9.1.2.3 = "99.0.0.3" ),

( ipRouteMetric1.9.1.2.3 = 3 ))

说明: (ipRouteDest.9.1.2.3 =  "9.1.2.3" ) 意思是,代理向管理站回复时,回复了一个对象ID是ipRouteDest.9.1.2.3,value是"9.1.2.3"的对象。这样一来, 管理站下一个GetNextRequest 报文中必然会包含ID是ipRouteDest.9.1.2.3的对象。

代理要做的就是要对ipRouteDest对象做特殊处理,要根据ipRouteDest.9.1.2.3中“9.1.2.3”去查下一条记录。

网管站继续:

GetNextRequest ( ipRouteDest.9.1.2.3,

ipRouteNextHop.9.1.2.3,

ipRouteMetric1.9.1.2.3 )

agent响应:

GetResponse (( ipRouteDest.10.0.0.51 = "10.0.0.51" ),

( ipRouteNextHop.10.0.0.51 = "89.1.1.42" ),

( ipRouteMetric1.10.0.0.51 = 5 ))

值得注意的是agent必须能够确定下一个管理变量名,以保证所有变量能被取到且只被取到一次。

网管站继续:

GetNextRequest ( ipRouteDest.10.0.0.51,

ipRouteNextHop.10.0.0.51,

ipRouteMetric1.10.0.0.51 )

agent 响应:

GetResponse (( ipRouteDest.10.0.0.99 = "10.0.0.99" ),

( ipRouteNextHop.10.0.0.99 = "89.1.1.42" ),

( ipRouteMetric1.10.0.0.99 = 5 ))

网管站继续

GetNextRequest ( ipRouteDest.10.0.0.99,

ipRouteNextHop.10.0.0.99,

ipRouteMetric1.10.0.0.99 )

这是因为路由表中所有的行都被取遍,agent因返回路由表对象的下一字典后继即该管理对象在MIB树中的后序遍历的直接后继。这里应是nettoMediaIndex,管理对象的OBJECT IDENTIFIER。这个响应通知网管站对表的遍历已经完成。

6.3 GetResponse PDU

GetResponse PDU只有当受到getRequest GetNextRequest SetRequest才由协议实体产生,网管站收到这个PDU后,应显示其结果。

6.4 SetRequest PDU

SetRequest PDU除了PDU类型标识以外,和GetRequest相同,当需要对被管变量进行写操作时,网管站侧的协议实体将生成该PDU。

对SetRequest的响应将根据下面情况分别处理:

如果是关于一个只读变量的设置请求,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为noSuchName, error index的值是错误变量在变量list中的位置。

如果被管设备上的协议实体收到的PDU中的变量对偶中的值,类型、长度不符和要求,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为badValue, error index的值是错误变量在变量list中的位置。

如果需要产生的GetReponse报文长度超过了本地限制,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为tooBig, error index的值是错误变量在变量list中的位置。

如果是其他原因导致SET失败,则收到该PDU的协议实体产生一个GetReponse报文,并置error status为genErr, error index的值是错误变量在变量list中的位置。

如果不符合上面任何情况,则agent将把管理变量设置收到的PDU中的相应值,这往往可以改变被管设备的运行状态。同时产生一个GetResponse PDU,其中error status置为noError,error index的值为0。

6.5 Trap PDU

Trap是被管设备遇到紧急情况时主动向网管站发送的消息。网管站收到trap PDU后要将起变量对偶表中的内容显示出来。一些常用的trap类型有冷、热启动,链路状态发生变化等。

猜你喜欢

转载自blog.csdn.net/yexiangCSDN/article/details/86301263
今日推荐