了解SNMP协议之前,先要了解ISO/OSI和TCP/IP的网络模型。ISO/OSI将网络分为7层,业界分为5层,如图所示:
SNMP位于两种网络模型的顶层即应用层,属于应用层协议,在传输层依靠UDP协议进行传输。SNMP(Simple Network Management Protocol)即简单网络管理协议,主要用在局域网中对设备进行管理,应用最为广泛的是对路由器交换机等网络设备的管理,当然不仅限于网络设备。SNMP分为管理端和代理端(agent),管理端的默认端口为UDP 162,主要用来接收Agent的消息如TRAP告警消息;Agent端使用UDP 161端口接收管理端下发的消息如SET/GET指令等。
SNMP协议目前在用的有3个版本,分别是V1,V2C,V3,主要差异在安全性、消息封装格式、GET效率等方面。
SNMP V1中定义了5种类型的PDU:Get(获取参数值,不能遍历table类型的参数组),GetNext(可获取table类型的参数值,一组参数),Set(设置参数值) 和Trap(发送告警)、Response(GET操作的响应信息)。SNMPv1使用团体字(community)来作为身份认证信息。当Agent接收到与其一样的团体字的管理端消息后才会进行消息应答。V1整个消息采用明文传送,通过wireshark/tcpdump等抓包工具可看到明文。
SNMP V2C定义了7种类型的PDU:Get(获取参数值,不能遍历table类型的参数组),GetNext(可获取table类型的参数值,一组参数),Set(设置参数值) 和Trap(发送告警),GetBulk(GetBulk操作所对应的基本操作是GetNext,通过对Non repeaters和Max repetitions参数的设定,高效率地从Agent获取大量管理对象数据,如果get-request中的参数有一个不存在,请求照样会被正常执行;而在SNMPv1种将收到一个错误消息),inform(相当于Trap的升级版,但是Trap消息发出去之后不会收到响应消息,而inform消息在发出之后能收到响应消息)、Response(GET操作的响应信息)。V2C也采用团体字认证,整个消息采用明文传送。
SNMP V3中沿用了V2C中7种类型的PDU,增加了report(当消息不能解密时发送该消息)。V3采用了USM和VACM技术。USM提供了认证和加密功能,VACM确定用户是否允许访问特定的MIB对象以及访问方式。USM(基于用户的安全模型):Agent通过对管理端消息中携带的用户、密码(采用MD5或者SHA加密)、authkey(认证秘钥)以及engineid(agent的标识码)对消息进行鉴权和完整性验证,整个消息体采用DES进行加密。V3数据消息采用密文传送,通过wireshark/tcpdump等抓包工具不可见其实际的内容。
SNMP管理端和代理端(Agent)进行通信时,双方必须有共同的一套参数才能正常“交流”,这套参数被称作MIB(管理信息库),因文件组织格式为树形,统称MIB树,下面介绍一下MIB文件的格式,主要包括 :
1. ASN.1如何语言无关的表示数据;
2. BER编码,如何传输数据;
3. mib2c简介;
4. snmptranslate,snmpget,snmpwalk的使用;
ASN.1(Abstract Syntax Notation dot one),抽象记法1。它是定义抽象数据类型规格形式的标准,提供了一套正式,无歧义,精确的描述,来描述独立于特定计算机硬件的对象。举个例子:
TEST-MIB DEFINTIONS ::= BEGIN
company OBJECT IDENTIFIER ::={ enterprises 12345}
person OBJECT-TYPE
SYNTAX person
ACCESS read-only
STATUS current
::={company 1}
person ::= SEQENCE {
name OCTET STRING
age Integer32
}
name OBJECT-TYPE
SYNTAX OCTET STRING
ACCESS read-only
STATUS current
::={ person 1 }
age OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
::={ person 2 }
END
这个例子很浅显易懂,如果要获取一个人的信息(名字,年纪)就可以通过oid来查询;这就是ASN.1语法,无歧义。
BER ( Basic Encoding Rules)基本编码规则,它可以在报文转换成bit串时候发挥作用,一切都是TLV,整个的SNMP报文就是一个TLV结构,里面不断嵌套而成的,像这样:
TLV
|----TLV
|----TLV
|----TLVs ...
:
:
|----TLV
这样做的好处是编解码规则就变得非常简单好操作了。
mib2c(一个Perl脚本)的主要作用是把用ASN.1描述的对象转变成C语言描述的对象,只要配置好环境变量MIBS,直接输入mib2c param(要对象的oid或者对象描述),就可以生成对应的.c.h;这个时候,configure --with-mib-modules=“TEST-MIB”就可以生成带这个mib的配置了,然后make就行了。这样子编出来的mib库里就会带着刚才那个person信息了。
接下来,可以用snmptranslate,snmpget,snmpwalk去查询mib信息了,如:
#snmptranslate 1.3.6.1.4.1.12345.1
TEST-MIB:: person
#snmpget 1.3.6.1.4.1.12345.1.1.0
TEST-MIB::person.name.0 = STRING:"wang"
#snmpwalk 1.3.6.1.4.1.12345.1
TEST-MIB::person.name.0 = STRING:"wang"
TEST-MIB::person.age.0 = INTEGER: 24
怎么样,是不是很简单呢?