SNMP学习总结(1)——基本概念

这篇博客简要介绍了snmp协议的基本概念

1 SNMP简单概述

1.1 什么是SNMP?

  SNMP是英文”Simple Network Management Protocol”的缩写,中文意思是“简单的网络管理协议”。它属于TCP/IP五层协议中的应用层协议,用于网络管理的协议。SNMP主要用于网络设备的管理。由于SNMP协议简单可靠 ,受到了众多厂商的欢迎,成为了目前最为广泛的网管协议。
  SNMP协议主要由两大部分组成:SNMP管理站SNMP代理。SNMP管理站是一个中心节点,负责收集维护各个SNMP元素的信息,并对这些信息进行处理,最后反馈给网络管理员;而SNMP代理是运行在各个被管理的网络节点之上,负责统计该节点的各项信息,并且负责与SNMP管理站交互,接收并执行管理站的命令,上传各种本地的网络信息。
  SNMP管理站和SNMP代理之间是松散耦合。他们之间的通信是通过UDP协议完成的。一般情况下,SNMP管理站通过UDP协议向SNMP代理发送各种命令,当SNMP代理收到命令后,返回SNMP管理站需要的参数。但是当SNMP代理检测到网络元素异常的时候,也可以主动向SNMP管理站发送消息,通告当前异常状况。
  SNMP的基本思想:为不同种类的设备、不同厂家生产的设备、不同型号的设备,定义为一个统一的接口和协议,使得管理员可以是使用统一的外观面对这些需要管理的网络设备进行管理。通过网络,管理员可以管理位于不同物理空间的设备,从而大大提高网络管理的效率,简化网络管理员的工作。
  SNMP的工作方式:管理员需要向设备获取数据,所以SNMP提供了【读】操作;管理员需要向设备执行设置操作,所以SNMP提供了【写】操作;设备需要在重要状况改变的时候,向管理员通报事件的发生,所以SNMP提供了【Trap】操作。

1.2 SNMP和UDP

SNMP采用UDP协议在管理端和agent之间传输信息。 SNMP采用UDP161端口接收和发送请求,162端口接收trap,执行SNMP的设备缺省都必须采用这些端口。SNMP消息全部通过UDP端口161接收,只有Trap信息采用UDP端口162。

1.3 Snmp版本

SNMP目前共有v1,v2,v3这三个版本:

  • SNMP v1是SNMP协议的最初版本,不过依然是众多厂家实现SNMP基本方式。
  • SNMP v2通常被指是基于community的SNMP V2。Community实质上就是密码。
  • SNMP v3 是最新版本的SNMP。它对网络管理最大的贡献在于其安全性。增加了对认证和密文传输的支持。

2 SNMP工作原理

  在具体的实现上,SNMP为管理员提供了一个网管平台(NMS),又称为管理站,负责网管命令的发出、数据存储及数据分析。被监管的设备上运行一个SNMP代理(Agent),代理实现设备与管理站的SNMP通信。
  snmp工作原理
  管理站和代理端使用MIB进行接口统一,MIB定义了设备中的被管理对象。管理站和代理都实现相应的MIB对象,使得双方可以识别对方的数据,实现通信。管理站向代理请求MIB中定义的数据,代理端识别后,将管理设备提供的相关状态或参数等数据转换成MIB定义的格式,最后将该信息返回给管理站,完成一次管理操作。   

3 SNMP报文

3.1 报文类型

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

  • Get-Request 、Get-Next-Request与Get-Response
    SNMP 管理站用Get-Request消息从拥有SNMP代理的网络设备中检索信息,而SNMP代理则用Get-Response消息响应。Get-Next- Request用于和Get-Request组合起来查询特定的表对象中的列元素。
  • Set-Request SNMP管理站用Set-Request 可以对网络设备进行远程配置(包括设备名、设备属性、删除设备或使某一个设备属性有效/无效等)。
  • Trap SNMP代理使用Trap向SNMP管理站发送非请求消息,一般用于描述某一事件的发生,如接口UP/DOWN,IP地址更改等。

上面五种消息中Get-Request、Get-Next-Request和Set-Request是由管理站发送到代理侧的161端口的;后面两种Get-Response和Trap 是由代理进程发给管理进程的,其中Trap消息被发送到管理进程的162端口,所有数据都是走UDP封装。SNMP工作流程如图2:
SNMP工作流程

3.2 报文格式

SNMP代理和管理站通过SNMP协议中的标准消息进行通信,每个消息都是一个单独的数据报。SNMP使用UDP(用户数据报协议)作为第四层协议(传输协议),进行无连接操作。SNMP消息报文包含两个部分:SNMP报头和协议数据单元PDU。
SNMP报文格式

以下部分是报文格式的具体分析,有需要可以继续学习。

  在实际网络传输环境下,SNMP报文的长度取决于其所采用的编码方式。SNMP统一采用BER(Basic Encoding Rule)的编码规则,同时在正式SNMP规范中使用的是ASN.1语法,Abastract Syntax Notation v1,即抽象语法描述语言。这两个概念在后面实践环节再做进一步介绍,这里只要稍微了解一下即可,不妨碍我们对协议本身的分析。这里我们简单解释一下BER编码规则:
  BER作为ANS.1的基本编码规则,描述具体的ANS.1对象如何编码为比特流在网络上进行传输。BER编码规则由三部分组成:
  BER编码方式
SNMP中定义了几种基本的数据类型,其中v1和v2版有些改动,具体参见相应的RFC文档。这里我们只介绍几种最常见的类型:

  • INTEGER:一个整数
  • OCTER STRING: 0或多个8bit字节,每个字节在0~255之间取值
  • DisplayString:0或多个8bit字节,每个字节必须是ASCII码。在MIB-II中,所有该类型变量不能超过255个字符(0个字符可以)
  • NULL:代表相关的变量没有值
  • IpAddress:4字节长的OCTER STRING,以网络字节序表示IP地址
  • PhyAddress:6字节长的OCTER STRING,代表物理地址
  • Counter:非负整数,可以从0递增到232-1()。达到最大值后归0
  • TimeTicks:时间计数器,以0.01秒为单位递增,不同的变量可以有不同的递增幅度。所以在定义这种类型的变量时需要制定递增幅度
  • SEQUENCE:与C语言中的结构体类似
  • SEQUENCE OF:一个向量,参见后面ANS.1语法详细介绍章节

SNMP报文在传输层是封装在UDP报文中的,而UDP又是基于IP网络的,因此,我们可以得到完整的报文描述结构,如下图所示:
SNMP协议报文格式
PDU类型其实包含两个字节,第一个字节表示真实的PDU的类型;第二个字节表示后面报文所占的字节总数。针对SNMPv1,这个字段取值如下:
| PDU类型 | 名 称 |
| :——–: | :—–: |
| 0 | get-request |
| 1 | get-next-request |
| 2 | get-response |
| 3 | set-request |
| 4 | trap |
  也就是说,trap的类型是4。但是在数据报文中,该字段一般表示为ax,其中x取[0,4],即a0~a3表示相应的get、set等操作,a4表示trap报文。这里除了类型字段意外,其他字段均采用BER编码方式:
采用BER编码的字段
  
实战演练之报文格式分析
  Trap报文格式和上述图5所展示的结构有些差别,这里我们只分析SNMPv1和SNMPv2的Trap报文格式。trap报文前面的部分都一样,区别在PDU协议数据单元部分。

SNMPv1 Trap报文
SNMPv1的Trap报文格式如下所示:
SNMPv1的Trap报文格式
注意:除了PDU类型和PDU长度字段外,后面的每个字段都是BER编码方式。
trap类型”可以取以下值,其中0~6是已定义的特定trap,7及其以后的类型由供应商自定义。
表2 trap类型、名称及描述信息
| trap类型 | 名称 | 描述信息 |
| :——–: | :—–: | :—-: |
| 0 | coldStart | 代理进程对自己初始化 |
| 1 | warmStart | 代理进程对自己重新初始化 |
| 2 | linkDown | 一个接口已从工作状态变为故障状态(报文中的第一个变量标识此接口) |
| 3 | linkUp | 一个接口已从故障状态变为工作状态(报文中的第一个变量标识此接口) |
| 4 | authenticationFailure | 从SNMP管理进程收到无效共同体的报文 |
| 5 | egpNeighborLoss | 一个EGP邻站已变为故障状态(报文中的第一个变量包含邻站IP地址) |
| 6 | enterpriseSpecific | 在这个特定的代码段中查找trap信息 |
  通过wireshark抓包工具,捕获一条如下的SNMP报文,接下来对其进行仔细分析。
SNMPv1原始报文内容:

00 23 5a 9e 58 b9 00 4c 41 49 50 55 08 005 45 00 00 48 00 00 40 00 40 11 a5 4e c0 a8 0a 01 c0 a8 0a 05 0c 00 00 a2 00 34 ff e0 30 2a 02 01 00 04 06 70 75 62 6c 69 63 a4 1d 06 0a 2b 06 01 04 01 bf 08 03 02 0a 40 04 c0 a8 0a 01 02 01 00 02 01 00 43 01 0e 30 00

目的MAC:00 23 5a 9e 58 b9
源MAC:00 4c 41 49 50 55
协议类型:08 005 ,为IP数据报
IP头:45 00 00 48 00 00 40 00 40 11 a5 4e c0 a8 0a 01 c0 a8 0a 05
UDP头:0c 00 00 a2 00 34 ff e0
其余部分都为SNMP报文,接下来我们对照前面的报文结构体来逐个分析一下。

  • 30 表示SNMP消息是ASN.1的SEQUENCE类型;
  • 2a 表示该SNMP报文的总长度是42(0x2a)个字节,该字段所表示的报文长度起始于它后面的第一个字节直到报文结束;
  • 02 01 00 表示版本号,可见其确实为BER编码方式。02表示该字段是INTEGER类型;01表示该字段占1个字节;00表示版本号,该值为“版本号-1”;
  • 04 06 70 75 62 6c 69 63 表示团体名,04表示该字段为OCTET STRING类型;06表示该字段占6个字节;70 75 62 6c 69 63 表示团体名的ANSII码的十六进制形式,这里是“public”;
  • a4 1d 其中a4中的“4”表示这是一个trap报文,a4又叫报文的标签标记;1d表示后面还有29(0x1d)个字节的数据;
  • 06 0a 2b 06 01 04 01 bf 08 03 02 0a 企业OID标识。06表示该字段是个对象标识符,OBJECT IDENTIFIER;0a表示该字段占10(0x0a)个字节;关于SNMP的OID的编码方式有些奇特:例如1.3.6.1.2…. 取前两个数字分别记为x和y。编码时40x+y,这里x=1,y=3,因此结果为401+3=43,即表示十六进制的2b。因此,这里的企业OID编码即为1.3.6.1.4.1.8072.3.2.10;
  • 40 04 c0 a8 0a 01 同样40表示该字段为OCTET STRING 类型;04表示IP地址占4个字节;IP地址为192.168.10.1;
  • 02 01 00 其中00表示trap类型为coldStart;
  • 02 01 00 其中00表示我们指定的trap即specific-trap也为coldStart类型;
  • 43 01 0e 43表示为TimeTicks类型;01表示该字段占1个字节;0e即十进制的14表示时间标签为0.14秒,这里时间计数器以0.01秒递增;
  • 30 00 30表示“键-值”值对的编码类型为SEQUENCE;00表示该字段占0个字节,即没有该字段。

SNMPv2 Trap报文
SNMPv2的Trap报文格式如图8所示:
SNMPv2的Trap报文格式
同样的,这里除了trap类型和报文长度是标准网络字节序之外,其余协议字段也均为BER编码方式。可以看到v2版的trap报文正在向统一的报文格式发展,已经非常类似普通的SNMP请求、响应报文了。
SNMPv2原始报文内容:
00 23 5a 9e 58 b9 00 4c 41 49 50 55 08 00 45 00 00 7b 00 00 40 00 40 11 a5 1b c0 a8 0a 01 c0 a8 0a 05 0c 01 00 a2 00 67 04 bb 30 5d 02 01 01 04 06 70 75 62 6c 69 63 a7 50 02 04 17 73 2c fb 02 01 00 02 01 00 30 42 30 0d 06 08 2b 06 01 02 01 01 03 00 43 01 0e 30 17 06 0a 2b 06 01 06 03 01 01 04 01 00 06 09 2b 06 01 06 03 01 01 05 01 30 18 06 0a 2b 06 01 06 03 01 01 04 03 00 06 0a 2b 06 01 04 01 bf 08 03 02 0a

目的MAC:00 23 5a 9e 58 b9
源MAC:00 4c 41 49 50 55
协议类型:08 00,IP报文
IP头:45 00 00 7b 00 00 40 00 40 11 a5 1b c0 a8 0a 01 c0 a8 0a 05
UDP头:0c 01 00 a2 00 67 04 bb
余下部分全为SNMP报文内容,这里我们做一下简单的约定:
xx 标注类型;xx 标注长度;xx 标注真正的数据。
这样一来上面这串原始数据就好分析多了

  • 30 5d 整个SNMP报文的编码方式为30,即SEQUENCE类型,报文长度93(0x5d)字节;
  • 02 01 01 版本号01即v2版本;
  • 04 06 70 75 62 6c 69 63 团体名70 75 62 6c 69 63 即英文的“public”;
  • a7 50 a7表示trap类型为7,即厂商自定义trap;50表示PDU区段占80(0x50)字节;
  • 02 04 17 73 2c fb 请求ID为17 73 2c fb 十进制的393424123;
  • 02 01 00 错误状态0;
  • 02 01 00 错误索引0;
  • 30 42 “变量名-值”对编码类型30 即SEQUENCE类型;“变量名-值”所占总字节0x42,即66字节;
  • 30 0d 06 08 2b 06 01 02 01 01 03 00 43 01 0e 第一个“名-值”对区段编码方式30 即SEQUENCE类型;第一个“名-值”对总长度0x0d,13字节;第一个变量名的编码类型0x06,时间标签;第一个变量名占0x08个字节;第一个变量名2b 06 01 02 01 01 03 00,为1.3.6.1.2.1.1.3.0;第一个变量值为0x0e,即14;
  • 30 17 06 0a 2b 06 01 06 03 01 01 04 01 00 06 09 2b 06 01 06 03 01 01 05 01 第二个“名-值”对;变量名1.3.6.1.6.3.1.1.4.1.0;变量值1.3.6.1.6.3.1.1.5.1;
  • 30 18 06 0a 2b 06 01 06 03 01 01 04 03 00 06 0a 2b 06 01 04 01 bf 08 03 02 0a 第三个“名-值”对;变量名1.3.6.1.6.3.1.1.4.3.0;变量值1.3.6.1.4.1.8072.3.2.10;

今天我们简单对SNMP协议做个入门普及,包括它的原理,应用场景报文格式等。下面的章节,我们将以开源net-snmp为例来向大家阐述多种代理开发流程和原理,以及要注意的问题,其中每种扩展mib的方式都对应不同的开发需求。

坚持原创技术分享,您的支持将鼓励我继续创作!
0%