个人认为,理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息,更加便于理解协议。
因此本文将在SNMP协议报文的基础上进行介绍。
SNMPv1版本相关RFC
SNMPv2版本相关RFC
- 关于 Community-based SNMPv2 的基本原理,可参考RFC1901-Introduction to Community-based SNMPv2。
- 关于 SNMPv2-SMI 的基本原理,可参考RFC2578-Structure of Management Information Version 2。
- 关于 SNMPv2-TC 的基本原理,可参考RFC2579-Textual Conventions for SMIv2。
- 关于 SNMPv2-CONF 的基本原理,可参考RFC2580-Conformance Statements for SMIv2。
- 关于SNMP管理框架的基本原理,可参考RFC3411-An Architecture for Describing SNMP Management Frameworks
- 关于 SNMPv2 协议交互的基本原理,可参考RFC3416-Version 2 of the Protocol Operations for SNMP
- 关于 SNMPv2 协议的传输协议,可参考RFC3417-Transport Mappings for the Simple Network Management Protocol (SNMP)。
- 关于SMI Numbers分类及其定义的OID值,可参考IANA发布的Structure of Management Information (SMI) Numbers (MIB Module Registrations)。
- 关于SNMP字段空间定义,可参考IANA发布的Simple Network Management Protocol (SNMP) Number Spaces。
- 关于SNMP v1/v2/v3版本间的共存,可参考RFC3484-Coexistence between Version 1, Version 2, and Version 3 of the Internet-standard Network Management Framework。
- 关于企业私有识别码的相关字段,可参考IANA的Private Enterprise Numbers (PENs)。
常见企业识别码有:CISCO=9, Ericsson=193(…), Microsoft=311(…), Juniper=1411(…), HUAWEI=2011, ZTE=3902, RUIJIE=4881, MAIPU=5651, TP-Link Corporation Limited=11863, H3C=25506。- 关于常用OID值及其定义,可参考Global OID reference database。
- 关于OID技术的现状和发展,可参考中国电子技术标准化研究院发布的《对象标识符(OID)白皮书 (2015)》。
- 关于 ASN.1(Abstract Syntax Notation One) 的相关定义,可参考国际标准化组织的 ISO/IEC 8824。
- 关于 ASN.1(Abstract Syntax Notation One) 的编码规则,可参考国际标准化组织的 ISO/IEC 8825。
- 关于SNMP简易工具及其使用指导,可参考博客Windows系统下的可用SNMP软件-[资源]。
- 关于MIB/SMI的其他介绍,可参考博客【snmp】MIB结构与语法。
…SNMP的不同版本还存在大量相关RFC,感兴趣者可查阅相关资料。
除上述提到的 SNMP 协议外,其他网络管理协议还有 CMOT/CMIP(RFC1189),Netconf(RFC6241) 和 Telemetry(RFC9232) 等。此处着重介绍Community-based SNMPv2c版本。
个人能力有限,如有疑问烦请指导学习。
目录
SNMP
- 目录
- 1.背景介绍
- 1.1.相关术语
- 1.2.ASN.1的Basic Encoding Rules
- 1.2.1.ASN.1的Basic Encoding Rules
- 1.2.2.BER封装示例
- 2.SMI-RFC1155/RFC2578
- 2.1.SMI-RFC1155
- 2.2.SMIv2-RFC2578
- 2.3.MIB结构示例-VRRP
- 2.3.1.MIB树
- 3.SNMP协议原理
- 3.1.SNMP相关概念
- 3.2.SNMPv1-RFC1157
- 3.2.1.SNMPv1的5种PDU
- 3.3.SNMPv2-RFC3416
- 3.3.1.SNMPv2的PDU变化
- 3.4.SNMP交互原理
- 更新
1.背景介绍
1.1.相关术语
MIB:Management Information Base,管理信息库。被管理对象的信息库。MIB 中的对象由 ASN.1(Abstract Syntax Notation One,抽象语法标记1)描述。
OID:Object IDentifier,对象标识符。每类对象都有其命名、语法结构和编码类型。OID 就是管理定义对象的名称。
OID:是一种用于识别某些对象的方法而不管与该对象相关的语义,是遍历全局树的整数序列。
对象类型的语法:定义了对象对应抽象数据结构的。其结构可以为 INTEGER 或 OCTET 字符串,并且通常在定义语法时允许任何满足 ASN.1 结构的对象类型。
对象类型的编码:使用对象类型语法表示该对象类型实例的方式。 与对象的语法和编码概念隐含相关的是对象在网络上传输时的表示方式。
OID树:该树由一个根组成,该根通过边连接到多个标记节点。反过来,每个节点都可以有自己的标记子节点,也可称子树。当遍历树时,可以委派对分配给节点对应含义标签的管理控制。标签是简短的文本描述和整数的配对。
RFC1155 认为根节点不可被标签化,但至少有3个子节点。
ccitt(0):由 International Telegraph and Telephone Consultative Committee 国际电报和电话咨询委员会定义的 Label0。
iso(1):由 International Organization for Standardization 国际标准化组织定义的 Label1。
joint-iso-ccitt(2):由 ISO 和 CCITT 共同管理的 Label2。
自动换行
在 iso(1) 节点下,ISO 指定了一个子树供其他(国际)国家组织 org(3) 使用。在现有的子节点中,有两个已分配给 NIST(U.S. National Institutes of Standards and Technology,美国国家标准与技术研究院)。其中一个子树已由 NIST 转移给 dod(6)(Department of Defense,美国国防部)。
RFC1155 中定义了 IAB(Internet Activities Board,网络活动委员会)负责管理的 Internet 团体串节点 1.3.6.1。并且由 IAB 批准指定了管理对象标识符4个子树:
directory = Internet 1:被保留用于将来的备忘录,以讨论如何在 Internet 中使用 OSI Directory。
mgmt = Internet 2:用于识别 IAB 批准的文档中定义的对象,该子树的管理由 IAB 委托给 IANA(Internet Assigned Numbers Authority,互联网号码分配局)。
experimental = Internet 3:用于在网络实验中标识对象,该子树的管理由 IAB 委托给 IANA(Internet Assigned Numbers Authority,互联网号码分配局)。
private = Internet 4:用于厂商私有等场景下标识对象,该子树的管理由 IAB 委托给 IANA(Internet Assigned Numbers Authority,互联网号码分配局)。 关于企业私有识别码的相关字段,可参考IANA的Private Enterprise Numbers (PENs)。
//常用 OID 树结构。上图仅罗列部分内容,感兴趣者可查阅相关资料。
Managed Objects:管理对象。RFC1155 中定义对象由5部分组成:OBJECT DESCRIPTOR、Syntax、Definition、Access 和 Status。MIB 中未定义引用对象实例的方法,对对象实例的引用是通过特定于协议的机制实现的。例如 SNMP 和 CMOT 协议。
OBJECT DESCRIPTOR:对象类型的文本名称,OID 与其对应。或者说对象的数字表达为 OID,文本表达为OBJECT DESCRIPTOR。
Syntax:定义对象的表达语法结构,是 ASN.1 type ObjectSyntax 的一种。
Definition/Description:对象类型语义的文本描述。
Access:访问权限,可分为只读、读写、只写和不允许访问。
Status:对象状态,可分为必需的、可选的或过时的。
SMI:Structure of Management Information,管理信息结构。用于定义改编的子集,并分配关联的管理值。
RFC2578 中描述的较为详细将 SMIv2 分为了三部分:
Module definitions:用于描述信息模块。
Object definitions:用于描述管理对象。
Notification definitions:用于描述未经请求的管理信息传输。
NMS:Network management stations,网络管理站。是一个执行监视和控制网元的管理应用程序,也即管理对象服务器。
NE:Network elements,网元。通常是主机、网关、终端服务器等被管理对象设备。它们具有管理代理,负责执行 NMS 请求的网络管理功能。
1.2.ASN.1的Basic Encoding Rules
1.2.1.ASN.1的Basic Encoding Rules
Basic Encoding Rules,基本编码规则。BER 是ASN.1的正式标准文档定义于 ISO/IEC 8824 和 ISO/IEC 8825。ISO/IEC 8824/8825 分为多个章节,并历经 version1995, version1998, version2002, version2008, version2015, version2021。目前最新版本章节有 ISO/IEC 8824-1:2021 Information technology Abstract Syntax Notation One (ASN.1) Part 1: Specification of basic notation 和 ISO/IEC 8825-1:2021 Information technology ASN.1 encoding rules Part 1: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)。
与该标准等同的文本标准有:GB/T 16262、GB/T 16263 和 ITU-T X.690 等。
BER提供了一套规则,使得任何按该规则编码的一段数据(八位组流)都能够按照此规则被解析,这种规则使得一段数据自包含自身的结构信息。也即定义了编码发送器如何对数据值进行编码的各种选择。
BER的通用规则:
主体采用形似 TLV 的格式进行编码,也即 {Type, Length, Value} 的格式。
这里描述的是 primitive constructed encoding 首要编码格式,Alternative constructed encoding 额外编码格式会在上述三部分内容后携带 End-of-contents octets 以标识编码结束。感兴趣者可查阅相关资料。
Identifier octets:身份标识字节。用于标识数据类型,共 8-bits。
高位的 2-bits 称为 Class:00 表示 Universal Class;01 表示 Application Class;10 表示 Context-specific Class;11 表示 Private Class。
紧跟者的 1-bit 称为 P/C-bit:用于表示是否为构造类型。
其余 bits 称为 Tag number:用于标记字节数。
因此实际表示类型只有 5-bits,但 111112 用于保留使用作为转义标识。也即当标签类型 >30,此时 Tag number 取 111112。
Length octets:长度字节。用于描述 Contents octets 字段的长度,分为 definite form确定格式 和 indefinite form不确定格式。
definite form确定格式 又可分为 short form短格式 和 long form长格式。Length octets 通常长 1字节,当最高位 bit 为 0 时表示 short form短格式;反之为 1 时表示 long form短格式。
short form短格式 只使用 剩余 7-bit,因此只能表示 [0,127]。long form短格式 使用时意味着 Length octets 超过 1字节。此时原来的长度字节第一高bit位置 1,其余 7 位指明后续用于表示长度的字节数。Length = 201,应编码为 0x81C9。
自动换行
indefinite form不确定格式 仅在 Alternative constructed encoding 额外编码结构中出现,并且此时 Length octets 固定为 1字节。通过 End-of-contents octets 以标识编码结束。
相似的 111111112 的 Length octets 用于保留使用。
Contents octets:内容字节。包含具体的有效内容。
例如对于编码数据 0x5F2D027A68,由于 0x5F 的 tag number 为 111112 意味着还有更多字节表示 Identifier octets。那么实际上 Identifier octets 为 0x5F2D, Length octets 为 0x02,Contents octets 为0x7A68。
1.2.2.BER封装示例
本文《2.1.1.ASN.1的Basic Encoding Rules》介绍了基本的编码格式,这里简单介绍下常用的几种类型数据的封装格式。
这里以上图所示结构进行举例说明。
需要说明的是以下例子仅用于展示说明,实际情况还需针对进行考虑。
boolean:
也即0x0101FF。布尔值只有 False 和 True,当布尔值为 False 时 Contents octets 取 0x00;当布尔值为 True 时Contents octets 取任意非0值。也即分别编码为 0x0101 00 和 0x0101 FF。
integer:
也即0x02XXXX。那么对应 十进制数字128 应编码为0x0202 0100。
bit string:
也即0x03XXXX。由于传输时以字节为最小单位,bit string不一定占据完整字节,因此高位填充后有可能需要将剩余 bit 额外以 0 填充。同时在 Contents octets 字段第一个字节标识补位 bit 的个数。那么对应 bit string = 10101,应编码为0x0302 03A8;对应 bit string = 000111001101,应编码为0x0302 041CD0。
octet string:
也即0x04XXXX。相比于 bit string,octet string 高位填充后直接占据了整个字节。那么对应 octet string = 1010 1100 1110,应编码为0x0402 ACE0。
此外还有一种 IA5String 类型的字节串0x16XXXX,其内容字段采用 ASCII 方式进行编码。
null:
也即0x0500。contents octets不含任何内容。
object identifier:
也即0x06XXXX。对于此类型进行编码时,需将前两个节点记作 X 和 Y 并以 (X*40)+Y 的形式编码在同一个字节中。那么对应 OID = 1.3.6.1.2.1.2,应编码为0x0606 2B0601020102。
sequence:是标签号为 16 号的构造类型,因此 P/C-bit 置位。这是多个 TLV 的组合。
定义一个 sequence 具有格式 sequence {name IA5String, ok BOOLEAN},且有值值{name “smith”, ok TRUE}。则其编码应为
也即 0x300A 1605736D697468 0101FF,这里的 0x736D697468 是 smith 对应的ASCII 值。
set:是标签号为 17 号的构造类型,因此 P/C-bit 置位。这是多个 TLV 的组合。与 sequence 区别在于,set 是无序的。
那么对于上文的结构可表示为
0x310A 1605736D697468 0101FF 或
0x310A 0101FF 1605736D697468。
//这里简单介绍下其他类型的 Identifier octets。感兴趣者可查阅相关资料。
点击此处回到目录
2.SMI-RFC1155/RFC2578
如前文所描述,MIB(Management Information Base)是用来描述被管理对象向管理对象通告信息的文件。而 SMI(Structure of Management Information)则主要定义了 MIB 的组成部分和语法。这里简单介绍下 SMI 的相关定义,并以 MIB 实例进行相关说明。
RFC1155-Structure and Identification of Management Information for TCP/IP-based Internets中定义了第一版SMI,而RFC2578-Structure of Management Information Version 2中定义了第二版SMI。这里参考进行相关说明。
SMI 为 MIB 定义的 Naming Hierarchy/命名结构:
OBJECT IDENTIFIER 也即 OID 通常用于标识对象,在 RFC1155 和 RFC2578 中都定义了相同的表达:
[节点名/子树名] OBJECT IDENTIFIER ::= { 父节点/父树名 分支节点 }
例如:
directory OBJECT IDENTIFIER ::= { internet 1 }
表示 directory 节点是 internet 子节点的 1 节点,directory 节点也即 1.3.6.1.1。
例如此图的 internet 节点的 OID 就可表示为 1.3.6.1。某种程度上 internet 和 1.3.6.1 是同一被管理对象的不同表达。
SMI 为 MIB 定义的 Syntax/语法:
语法用于定义与 OBJECT-TYPE 对象类型对应的结构。
在 RFC1155-SMIv1 中有
Primitive Types 基本类型:主要定义了 4 种。有 INTEGER、OCTET STRING、OBJECT IDENTIFIER 和 NULL。
Defined Types 定义类型:主要定义了 6 种。有 NetworkAddress、IpAddress、Counter、Gauge、TimeTicks 和 Opaque。
在 RFC2578-SMIv2 的 2.2 章节中提到
ASN.1 types ASN基本类型:主要定义了 3 种。有 INTEGER、OCTET STRING 和 OBJECT IDENTIFIER。
Application-defined types 应用类型:主要定义了 8 种。有 Integer32、IpAddress、Counter32、Gauge32、TimeTicks、Opaque、Unsigned32 和 Counter64。
除了这 11 种 base type,RFC2578-SMIv2 还提到了 BITS construct 和 textual convention。
Integer32和Integer:Integer32 取 4字节共 32bit 整数计数。最高位 bit 用于指示±,其余 31bit 用于表示数字。也即 Integer32 可以表示 -2147483648 至 2147483647 的十进制整数。Integer32 和 Integer 类型无法区分,区别在于字符长度。
OCTET STRING:这种类型表示任意二进制或文本数据。通常不宜超过 255 字节。
OBJECT IDENTIFIER:这种类型通常是认为指定的类型名。每种子实例最多可有 128 sub-identifiers。
NetworkAddress和IpAddress:SMIv1 中描述 NetworkAddress 可以用于描述多种协议地址组的场景,SMIv2 中则说明使用 textual convention 替代了这种效果。IpAddress 是一个 32-bit 的是网络地址。
Counter/Counter32和Counter64:Counter/Counter32 是一个没有起始值概念的 32-bit 非负整数,超过极值后从 0 重新开始循环。并且具有该类型的对象通常是只读的访问,也不允许使用 DEFVAL 子句。Counter64 的区别在于是长为 64-bit 的非负整数。
Gauge/Gauge32:这是一个 32-bit 的非负整数。该值可以增加或减小。但不会像 Counter 会循环,Gauge/Gauge32 增加到极值后不会在继续增加而是保持在 4294967295。类似的减小到 0 后可以反向增加但是不能在继续减小。
TimeTicks:32-bit 以 0.01s 为单位的时间,也即大约 497 天。
Opaque:不透明类型仅用于向后兼容,不得用于新定义的对象类型。standard MIB 不得定义为 Opaque。
Unsigned32:表示 0 到 4294967295 之间的整数值信息。
BITS construct:表示命名 bit 的枚举,取值分配非负数、连续值,从零开始。并且如所枚举的命名位才能存在于值中。语法为 BITS construct 的节点有 dot1dDeviceCapabilities (1.3.6.1.2.1.17.6.1.1.1) 和 probeCapabilities (1.3.6.1.2.1.16.19.1)。
Textual convention:文本约定是一个基本类型子类的新定义类型,RFC2579-SNMPv2-TC 中专门对其进行说明。与 SMI 中定义的类型相比,这些新类型具有不同的名称、相似的语法,但语义更精确,用于方便用户阅读 MIB 模块。
其中又定义了 AutonomousType、DateAndTime、MacAddress、PhysAddress、RowPointer、RowStatus、…等不同基本类型的子类型。感兴趣者可查阅 RFC2579-SNMPv2-TC 原文或网络上公开的 SNMPv2-TC.MIB 文件。
需要说明的是:除上述提到的 RFC2578-SMIv2/SNMPv2-SMI 和 RFC2579-SNMPv2-TC 提到的语法类型外,还有其他文件也定义了子类型语法。
例如有:
RFC2580-SNMPv2-CONF 中定义的 MODULE-COMPLIANCE、OBJECT-GROUP 和 NOTIFICATION-GROUP。
RFC2863-IF-MIB 中定义的 InterfaceIndex 和 InterfaceIndexOrZero。
RFC3411-SNMP-FRAMEWORK-MIB 中定义的 SnmpAdminString、SnmpEngineID 和 SnmpSecurityLevel。
RFC4133-ENTITY-MIB 中定义的 PhysicalClass 和 PhysicalIndex。
实际上由于 MIB 文件可以重新定义和引用,所以实际上 MIB 语法没有上限。这里仅简单举例下常用的 MIB 语法,感兴趣者可查阅相应资料。
2.1.SMI-RFC1155
在 RFC1155-SMIv1 中, Structure and Identification of Management Information 被定义为主要由 5 部分组成:OBJECT、Syntax、Definition、Access 和 Status。
1@OBJECT:这通常指对象类型的文本名称(称为 OBJECT DESCRIPTOR)及其相应的 OID。
2@Syntax:对象类型的抽象表达,也即上文提到的语法之一。
3@Definition/Description:对象类型语义的文本描述。实现应确保其对象实例满足此定义。
4@Access:MIB 的可访问权限,为 read-only、read-write、write-only 或 not-accessible 之一。
5@Status:MIB 的当前状态,为 mandatory、optional 或 obsolete 之一。
RFC1155-SMIv1中有Object Instances:
如上图所示,在该 MIB 中是多个对象类型的集合。atEntry 父节点有 3 个子节点 atIndex、atPhysAddress 和 atNetworkAddress,语法分别为 INTEGER、OCTET STRING 和 NetworkAddress,分别用于描述 ”对象类型物理地址的接口号“、“依赖于介质的物理地址” 和 “与物理地址对应的网络地址”,都具有可读可写权限,状态为必需。
如果将多个 atEntry 作为子节点组合起来可形成一个 list 形式的父节点 atTable:
其语法定义为子节点中语法的集合。并且 list 对象还可组合形成更大级别的 list 对象。
为了便于工具进行解读可以使用 OBJECT-TYPE macro 进行表达:
详细内容可查阅相关资料。
并且考虑到网络标准MIB文档的过时,应以 OID 后加 version-number 的方式进行区分。在必要时应至宣告旧对象类型的老化而不删除其名。如果需要改变原有对象的语法,则应改变其名。
2.2.SMIv2-RFC2578
RFC2578–SMIv2/SNMPv2-SMI 中更详细的定义了 SMI,并将其分为 3 部分:Module definitions、Object definitions 和 Notification definitions。
Module definitions:用于描述信息模块。 MODULE-IDENTITY macro 用于提供每个信息模块的联系和修订历史记录,并必须在每个信息模块中出现一次。其中 IMPORT 子句通过指定信息模块的模块名称来引用信息模块。
Object definitions:用于描述管理对象。传达托管对象的语法和语义。
Notification definitions:用于描述未经请求的管理信息传输。
MODULE-IDENTITY macro 通常由 6 部分组成
1@LAST-UPDATED:该字句必须存在且包含目前最后一次更新 MIB 的日期和时间。
2@ORGANIZATION:该字句必须存在且包含对开发此信息模块组织的文本描述。
3@CONTACT-INFO:该字句必须存在且包含可联系此信息模块的技术查询的人员的相关信息。
4@DESCRIPTION:该字句必须存在且包含对模块信息高级别的文本描述。
5@REVISION:该字句可选存在用于描述 MIB 所经修改的变化且包含修订的日期和时间。当存在是应当包含 DESCRIPTION 子字句。
6@MODULE-IDENTITY value:通常是 OID,可以引用包含调用的信息模块。
OBJECT-IDENTITY 和 OBJECT-TYPE macro 通常由 6 部分组成:结构与 RFC1155-SMIv1 较为相近。
RFC2578–SMIv2/SNMPv2-SMI 的第 7 章 Mapping of the OBJECT-TYPE macro 中提到,对于非 list 节点/对象通过在该对象的名称后附加一个子标识符 0 来标识该对象的实例。
这也是我们在之后通过 SNMP 交互过程中发现某些 OID 会额外多 .0 的原因。后文将对其介绍。
1@SYNTAX:该字句必须存在且包含定义对象的抽象数据结构。
该数据结构必须为 base type、BITS construct 和 textual convention 之一。详细内容已在前文进行描述。
2@UNITS:该字句可选存在且表明对象单元的文本定义。
3@MAX-ACCESS:该字句必须存在且表明对象单元的协议识别。取值 not-accessible、accessible-for-notify、read-only、read-write 和 read-create。
4@STATUS:该字句必须存在且表明当前定义是最新的还是已过时的。取值 current/obsolete/deprecated。
current 值表示定义是当前且有效的。
obsolete 值表示该定义已过时,不应实现或可以删除。
deprecated 值表示定义已过时,但允许继续实现以实现新旧兼容。
5@DESCRIPTION:该字句必须存在且包含对对象的文本定义,该定义提供了实现所需的所有语义定义。
6@REFERENCE:该字句可选存在且包含对其他文档的文本交叉引用。
7@INDEX:如果该对象对应于概念行且不存在 AUGMENTS 子句,该子句必须存在,否则必须不存在该子句。用于定义从属于该对象的列式对象的实例标识信息,如何形成实例标识。
8@AUGMENTS:除非对象对应于概念行,否则 AUGMENTS 子句不得存在,它是 INDEX 子句的替代项。 对应于概念行的每个对象都有一个 INDEX 子句或一个 AUGMENTS 子句。
9@DEFVAL:该字句可选存在定义了一个可接受的默认值。在创建对象实例时,代理可以自行决定使用该默认值。 也就是说,该值是对实现者的“提示”。
NOTIFICATION-TYPE macro 往往指代 SNMP trap 结构
与 OBJECT-TYPE macro 类似,通常由 OBJECTS、STATUS、DESCRIPTION 和 REFERENCE 字句组成。
NOTIFICATION-TYPE 型对象如上图所示。
点击此处回到目录
2.3.MIB结构示例-VRRP
此处介绍的 vrrpMIB.mib 文件定义于 RFC2787 中,感兴趣者可查阅相关资料。
如上图展示了 vrrpMIB 节点的 MIB 树结构,其具有 1.3.6.1.2.1.68 的OID。并且由于 vrrpMIB 节点还引用了 IF-MIB.MIB 文件(具有 interface=1.3.6.1.2.1.2 的 OID),所以还会展现同级的 interface 节点。
vrrpMIB 节点解析
此处关于 TEXTUAL-CONVENTION macro 未做介绍,感兴趣可查询 RFC2579-SNMPv2-TC 原文。与 SMI 中定义的类型相比,这些新类型具有不同的名称、相似的语法,但语义更精确,可用于方便用户阅读 MIB 模块。
如上图所示vrrpMIB 是多个对象实例的集合,包含了多个对象。
这是一种特殊的对象类型 SYNTAX语法,可以方便地将虚构的表格结构强加给 MIB 中的有序对象集合。
vrrpMIB的trap信息,可用于 SNMPv2 的 trap-PDU 和 Inform-PDU。
此处仅简单示例下MIB文件的SMI结构,vrrpMIB 还包含了 RFC2580-SNMPv2-CONF 中定义的 MODULE-COMPLIANCE macro、OBJECT-GROUP macro 和 NOTIFICATION-GROUP macro,等内容。感兴趣者可查阅相关资料。
2.3.1.MIB树
通过上述所介绍 SMI(Structure of Management Information)中定义的 MIB 文件结构,推出了一些著名定义 MIB 的RFC:《RFC1156-MIB for Network Management of TCP/IP-based internets》,《RFC1213-MIB for Network Management of TCP/IP-based internets:MIB-II》,《RFC3418-MIB for SNMP》,《RFC4750-OSPF Version 2 MIB》和《RFC4273-Definitions of Managed Objects for BGP-4》。
因此形成了如上图所示的标准MIB树。
点击此处回到目录
3.SNMP协议原理
上世纪末,基于IP的网络结构蓬勃发展,因此对互联网管理的需求日益紧迫。IAB (Internet Activities Board,互联网活动委员会) 在 RFC1052 中提出关于制定互联网网络管理标准的建议报告。IETF (Internet Engineering Task Force,互联网工程任务组) 被指示在网络管理领域创建两个新的工作组。一个小组负责进一步规范和定义 MIB 文件。另一个负责定义和修改 SNMP协议 (Simple Network Management Protocol,简单网络管理协议) 的,以适应网络供应商和运营社区的短期需求,并与 MIB 工作组的输出保持一致。
简单而言,管理对象和被管理对象通过一系列标准 MIB 文件约定管理内容,并且通过调用 SNMP 协议交互管理信息。但需要说明的是 SNMP 协议并不是唯一通过 MIB 交互管理信息的协议,CMOT/CMIP 协议也可通过此方式进行管理内容交互。
3.1.SNMP相关概念
SNMP体系结构模型:
SNMP协议采用类似 Client/Server 的 C/S 架构。被管理对象称为 NE 网元,作为 SNMP Client agent 角色;管理对象称为 NMS 网络管理站,作为 SNMP Server 角色。
SNMP体系结构模型的目标在于
- 降低管理代理软件的开发成本,简化降低管理工具的形式和复杂程度,并易于网络管理工具开发人员理解和使用。
- 提供足够的可扩展性的管理协议,以适应网络操作和管理的其他可能意想不到的方面。
- 提供独立于特定主机或特定网关的管理协议。
SNMP概念关系:
SNMP application entities:SNMP应用实体。NMS 和 NE 中使用 SNMP 相互通信的实体。
protocol entities:协议实体。支持 SNMP application entities 的进程。
SNMP community:SNMP 团体串。SNMP agent 中与 SNMP application entities 对应匹配的一串字符。
SNMP application entities 通过 protocol entities 产生 SNMP 消息,并归属于对应的 SNMP community。对应的消息称为 authentic SNMP message 真实SNMP消息。
authentication service:根据一种或多种身份验证方案识别真实 SNMP 消息的实现函数称为身份验证服务。
SNMP MIB view:MIB视图。网元 MIB 中与元素相关的对象子集。
SNMP access mode:SNMP访问模式。{ READ-ONLY, READ-WRITE }元素的只读和读写集合。
SNMP community profile:SNMP 团体配置文件。SNMP access mode 及其对应的 SNMP MIB view。
SNMP 团体配置文件表示对指定 MIB 视图中变量的指定访问权限。这一权限与 SMI 中定义 MIB 的访问权限不同,是由网络管理员决定分配的管理权限。基于团体配置文件定义的读写权限,决定了是否可以执行 SNMP 的get、set 和 trap 操作。
SNMP access policy:SNMP 访问策略。SNMP团体串 及其对应的 SNMP团体配置文件 称为 SNMP 访问策略。SNMP 应用程序实体之间的所有管理关系都是根据 SNMP 访问策略在体系结构上定义的。
SNMP proxy access policy:SNMP 代理访问策略。不同于上文介绍的 SNMP agent 往往是依附于网元的程序/函数,这里的 SNMP proxy 是独立于管理实体和被管理实体的网络角色,是真正的代理。这样的功能可以实现复杂的访问控制设计。
protocol entity 在与其关联的主机上的 UDP 端口 161 接收所有消息的消息,但 trap的消息除外。应在 UDP 端口 162 上接收 trap 消息。
//这里展示了 TCP/IP 网络架构下由 UDP 协议的 161 端口承载 SNMP 消息的示例。之后也将在此架构下进行介绍。其他网络架构下的 SNMP 协议可查阅相关资料。
//snmp-agent udp-port用来修改 SNMP Agent 侦听的端口号,默认161。需要与 SNMP Manger 一致。
同样的 snmp-agent target-host 命令中也包含参数可以修改 trap 型 SNMP 消息的监听端口。默认162。
//默认情况下发送Trap报文的源端口号是随机分配的,可以通过 snmp-agent trap source-port 指定其端口固定为1025~65535 的任意值。
3.2.SNMPv1-RFC1157
关于 SNMPv1 协议交互的基本原理,可参考1990年发布的RFC1157-A Simple Network Management Protocol (SNMP)。
其中定义了SNMP 协议通过 protocol entity 交换消息来完成网络管理协议。每个消息都使用 ASN.1 的 BER 规则在单个 UDP 数据包中完全独立地表示。 消息由 version
identifier、SNMP community 名称和 PDU (protocol data unit,协议数据单元) 组成。
RFC1157 的第四章《4.Protocol Specification》中定义 SNMPv1 的封装结构为:
这是先前介绍的 ASN.1 的 BER 封装标准。也即 SNMPv1 消息公共部分由 SEQUENCE 类型的三部分组成:
version:INTEGER 类型的 version-1,取值 1。
community:OCTET STRING类型,取值取决于具体情况
data:ANY 的任意数据结构,为所携带的 PDU。
同时定义PDU:
从上述 5 种类型中进行选择。
报文解读示例:
这里选中的 UDP payload 为 37 字节,也即意味着 SNMPv1 被编码为这 37 字节。
编码方式由 RFC1157 指定选用 ASN.1 的 BER 规则。详细规则可点击此处查看对应内容。这里直接依照 TLV 的格式进行说明。
为便于分析,首先将这 37 字节部分罗列
0x30 23 02 01 00 04
0x06 70 75 62 6c 69 63 a1 16 02 …
其中开始的 2 个字节 Identifier octets = 0x30 表示本数据流格式为 SEQUENCE;Length octets = 0x23 表示后续内容有 35 字节。也即这之后的内容都为 SEQUENCE 数据结构的 Contents octets。
后续 Contents octets 的 2 个字节 Identifier octets = 0x02 表示本数据流格式为 INTEGER;Length octets = 0x01 表示后续内容有 1 字节。这里 Contents octets 取值为 0x00 表示 SNMP 版本为 v1。
version 后的 2 个字节 Identifier octets = 0x04 表示本数据流格式为 OCTET;Length octets = 0x06 表示后续内容有 6 字节。这里 Contents octets 取值为 0x70 75 62 6c 69 63,这是 ASCII 编码格式的 public。也即团体串为 public。
最后部分的前 2 个字节 Identifier octets = 0xA1 表示本数据流格式为 get-next-request;Length octets = 0x16 表示后续内容有 22 字节。
也即其结构为上图所示。
SNMPv1 中 PDU 的 Identifier octets 编码有:
PDU Type Identifier octets GetRequest-PDU 0xA0 GetNextRequest-PDU 0xA1 GetResponse-PDU 0xA2 SetRequest-PDU 0xA3 Trap-PDU 0xA4
3.2.1.SNMPv1的5种PDU
SNMPv1 定义了 5 种 PDU:GetRequest-PDU 、GetNextRequest-PDU 、GetResponse-PDU 、SetRequest-PDU 和 Trap-PDU 。
除 Trap-PDU 外,都具有如下结构类型:
实际取值需依照实际情况执行。
RequestIDs:用于区分未完成的请求。 通过使用 RequestID,SNMP 应用程序实体可以将传入响应与未完成的请求相关联。同时也可用于防重放攻击。
ErrorStatus:用于指示在处理请求时发生异常。GetRequest-PDU 和 GetNextRequest-PDU 中该字段总是置0。
ErrorIndex:在 ErrorStatus 非 0 情况下,指示列表中的哪个变量导致异常来提供其他信息。GetRequest-PDU 和 GetNextRequest-PDU 中该字段总是置0。
VarBind:变量名称和相应值的简单列表。
Trap-PDU具有如下结构类型:
实际取值需依照实际情况执行。
enterprise:MIB 树中属于 enterprise 节点及其 子节点/子树 的 OID。用于表示所 trap 的实例。
agent-addr:SNMP agent 的地址。用于表示所 trap 的源。
generic-trap:表示通用的 trap 类型。
specific-trap:特殊 trap code,在 generic-trap 非 enterpriseSpecific(6) 情况下使用。
time-stamp:协议实体初始化至今的时间。
VarBindList:包含 Trap-PDU 的特殊操作。
coldStart(0):表示发送方协议实体重新初始化以便改变生效。
warmStart(1):表示发送方协议实体重新初始化以便改变不生效。
linkDown(2):表示发送方协议实体的配置中某个通信链路的故障。
linkUp(3):表示发送方协议实体的配置中某个通信链路的出现。
authenticationFailure(4):表示发送方协议实体通告协议消息解析失败。
egpNeighborLoss(5):表示发送方协议实体 EGP 邻居失效。
enterpriseSpecific(6):表示发送方协议实体通告某些 私有事件的发生。
3.3.SNMPv2-RFC3416
关于 SNMPv2 协议交互的基本原理,可参考2002年发布的RFC3416-Version 2 of the Protocol Operations for SNMP。
SNMPv2 协议的封装结构与 SNMPv1 基本相同,区别在于:
version 字段的 Contents octets:取值为 0x01 表示 snmpv2c,取值 0x02 表示 SNMPv2u 和 SNMPv2*。
data 字段定义了 8 种 PDU:GetRequest-PDU、GetNextRequest-PDU、Response-PDU、SetRequest-PDU、GetBulkRequest-PDU、InformRequest-PDU、SNMPv2-Trap-PDU 和 Report-PDU。
这里只介绍常用的几种 PDU。
SNMPv1 和 SNMPv2c 中 PDU 的 Identifier octets 编码对别:
SNMPv1 SNMPv2c GetRequest-PDU 0xA0 0xA0 GetNextRequest-PDU 0xA1 0xA1 GetResponse-PDU 0xA2 0xA2 SetRequest-PDU 0xA3 0xA3 Trap-PDU 0xA4 0xA7 GetBulkRequest-PDU null 0xA5 InformRequest-PDU null 0xA6 Report-PDU null 0xA8
3.3.1.SNMPv2的PDU变化
相比于 SNMPv1,SNMPv2 的 GetRequest-PDU、GetNextRequest-PDU、Response-PDU 和 SetRequest-PDU 结构没有变化。
并且 InformRequest-PDU 和 SNMPv2-Trap-PDU 具有和 GetRequest-PDU 等 PDU 相同的结构类型。
RFC3416 定义 SNMPv2 除 GetBulk 类型外的 PDU 封装结构为:
相比于 SNMPv1, SNMPv2 大部分 PDU 的 error-status 字段多了更多的标识码。其他内容基本相同。
GetBulkRequest-PDU具有如下结构类型:
也是主要有 4 部分组成,区别在于字段含义不同。
3.4.SNMP交互原理
SNMPv1 和 SNMPv2c 原理基本相同,这里简单进行介绍。不同之处则单独进行说明。
Request 和 Response:
1@: 首先由 NMS 的协议实体根据其 SNMP 应用程序实体的请求生成 GetRequest-PDU。构造方式依照上文所介绍格式。
2@:收到 GetRequest-PDU 后,NE 上的接收协议实体根据 PDU 中 VarBindList 字段 get 操作的某些对象进行匹配响应。并回应 GetResponse-PDU。如果消息存在错误,则将 GetResponse-PDU 中 error-status 和 error-index 字段填充相应的信息进行响应。
3@:GetNextRequest-PDU 同样由其 SNMP 应用程序实体的请求生成。但区别在于 GetNextRequest 用于请求字典序的下一个参数值。
4@:收到 GetNextRequest-PDU 后,NE 上的接收协议实体依照相同逻辑回应 GetResponse-PDU。
这里没有提到的一点是 community团体串:>上文介绍这是一个 SNMP agent 中与 SNMP application entities 对应匹配的一串字符,可以提供身份认证。
在 SNMP agent 的应用实体上通过 community团体串 与 MIB 视图进行绑定,形成 团体串配置文件,可以表示对指定 MIB 视图中变量的指定访问权限。也即,在同一个 SNMP agent 上可以定义多个团体串配置文件,从而实现对设备管理的不同权限级别。
同时由于 community团体串 在网络中是明文传输的, SNMPv3 不在使用这种方式,而是基于 USM 模型同时指定加密和认证密钥的方式进行身份认证。
自动换行
为了简单示例有如下 routing table:
Destination NextHop Metric 9.1.2.3 99.0.0.3 5 10.0.0.51 89.1.1.42 5 10.0.0.99 89.1.1.42 5 1@NMS 请求:GetNextRequest ( ipRouteDest, ipRouteNextHop, ipRouteMetric1 )
2@SNMP agent 回应: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 )
)
3@NMS 请求: GetNextRequest ( ipRouteDest.9.1.2.3, ipRouteNextHop.9.1.2.3, ipRouteMetric1.9.1.2.3 )
4@SNMP 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 )
)
5@NMS 请求: GetNextRequest ( ipRouteDest.10.0.0.51, ipRouteNextHop.10.0.0.51, ipRouteMetric1.10.0.0.51 )
6@SNMP 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 )
)
7@NMS 请求:GetNextRequest ( ipRouteDest.10.0.0.99, ipRouteNextHop.10.0.0.99, ipRouteMetric1.10.0.0.99 )
8@SNMP agent 回应:由于表中没有其他条目,SNMP agent 将返回已知对象名称的字典顺序中下一个对象。 此响应向管理站发出路由表结束的信号。
set 和 trap/inform:
SetRequest-PDU 由 SNMP 应用实体驱动协议实体生成,用于向 SNMP agent 指派实例对象值。
NE/SNMP agent 在接受到 SetRequest-PDU 后
- 可以比对根据相关 MIB 视图所定义权限。无 write 权限时回应 error-status 字段的值为 noSuchName,error-index 字段的值是接收到的对象名称组件索引的 GetResponse-PDU 消息。
- 对象类型不匹配,回应error-status 字段的值为 badValue,error-index 字段的值是接收到的对象名称组件索引的 GetResponse-PDU 消息。
- 本应回应的 GetResponse-PDU 消息大小超过本地设置,回应 error-status 字段 tooBig,并且 error-index 字段的值为零的 GetResponse-PDU 消息。
- variable-bindings 字段命中对象但上述任何规则未涵盖的原因而无法更改命名对象的值,回应error-status 字段的值为 genErr,error-index 字段的值是接收到的对象名称组件索引的 GetResponse-PDU 消息。
- 在接收消息的 variable-bindings 字段中命名的每个对象,将向该变量分配相应的值。
trap-PDU 由协议实体在 SNMP 应用程序实体的请求下生成。SNMP 应用程序实体选择 SNMP 应用程序实体的目标地址的方法特定于实现。 也即在发生 MIB 所定义事件时,主动向 NMS 发送通知消息。
对于 SNMPv2 的 SNMPv2-Trap-PDU 的变量绑定列表中的前两个变量绑定分别是 sysUpTime.0 和 snmpTrapOID.0 [RFC3418]。
InformRequest-PDU 由协议实体在 SNMP 应用程序实体的请求下生成。InformRequest也是被管理设备向NMS主动发送告警。与Trap告警不同的是,被管理设备发送Inform告警后,需要NMS回复InformResponse来进行确认。SNMPv1 不支持。
GetBulkRequest-PDU 由协议实体在 SNMP 应用程序实体的请求下生成,目的是请求传输潜在的大量数据。包括但不限于高效、快速地检索大型数据表。SNMPv1 不支持。
收到 GetBulkRequest-PDU 后,接收 SNMP 实体将处理变量绑定列表中的每个变量绑定,以生成 Response-PDU,其 request-id 字段的值与请求中的值相同。并且对于 GetBulkRequest-PDU 类型,成功处理请求中的每个变量绑定会在 Response-PDU 中生成零个或多个变量绑定。
点击此处回到目录