目录

  1. 简说SNMP

  2. 开源软件包NET-SNMP

  3. 守护进程snmpd


从互连网初期起,研究者就开始规划如何方便地进行网络环境下各种设备(包括计算机设备)的管理,由此诞生的简单网络管理协议(SNMP - Simple Network Management Protocol)也经历了第一版、第二版和第三版的演变过程

↑TOP↑

1. 简说SNMP

上世纪八十年代后期,基于简单网关监视协议(SGMP - Simple Gateway Monitor Protocol),当时工作在Tennessee大学的Jeff Case博士等人发表了IETF的SNMP第一版SNMPv1标准。模型在网络设备上运行一个SNMP代理(Agent),它和网络管理工作站(NMS)协调完成对网络设备的管理。SNMP代理和NMS在162/udp端口上进行数据报文交换,格式如下:

    SNMP版本号    
    Community名        PDU   


Community是通信双方在交换数据报文前要对的“暗号”。假如双方的Community名都设置成“威虎山”,SNMP代理和NMS就能以共同的Community名进行SNMP数据报文交换。而这个NMS不能控制以“奶头山”作为Community名的SNMP代理。座山雕和许大马棒是两个山头的人,一定禁止他们互相打探军情、也不会听从对方的调遣。第一版的PDU有五种类型:

  • Get-Request:NMS发送给代理的请求,获取参数表或参数值

  • Get-Next-Request:NMS发送给代理的请求,用于发现参数表中下一个参数和它的值

  • Response:代理发送给NMS的响应,回答NMS的请求

  • Set-Request:NMS发送给代理的请求,改变参数值

  • Trap:代理发送给NMS的通知(Notification)


时间进入九十年代,Case博士创建了自己的公司SNMP Research, Inc,牵头发布了改进的第二版SNMPv2。在原来基础上,第二版增加了两种新PDU类型:

  • Get-Bulk-Request:为提高效率而设计,一次完成Get-Next-Request的多重递归

  • Inform-Request:完成Trap同样功能,但增加响应机制确保通知成功


此外,第二版改进了第一版的Community机制,但遗憾没有得到协议各方的普遍认可。因此,目前普遍使用的SNMP第二版,仍然保留第一版的Community机制,这个折衷版本称为SNMPv2c。


SNMP第三版SNMPv3在2000年以后完成,它增加提供SNMP的安全×××:

  • 认证(authentication):检验数据报文来源的正确性

  • 保密(privacy):保证数据报文传输中不被串改和泄密


↑TOP↑

2. 开源软件包NET-SNMP

NET-SNMP是一款同时支持SNMPv1、SNMPv2c和SNMPv3的开源软件包,用C语言写成。


1992年,那是一个春天,有一个老人就是参加过起草SNMPv2标准的Steve Waldbusser。当时在Carnegie-Mellon大学工作,他开始为学校研发CMU-SNMP软件包。此后,UC Davis大学的Wes Hardaker在CMU-SNMP基础上作进一步的完善工作,在1995年完成了可扩展的SNMP代理,新版软件包被称为UCD-SNMP。以后又有一些自愿者加入,开发队伍不断壮大,并在2000年易名为NET-SNMP。


RedHat或CentOS需要安装net-snmp、net-snmp-utils和net-snmp-libs软件包。

root@centos:# yum -y install net-snmp net-snmp-utils net-snmp-libs


而Debian上安装snmp、snmpd和libsnmp-base软件包,并且要人工下载MIB。

root@debian:# apt-get install snmp snmpd libsnmp-base
root@debian:# apt-get install snmp-mibs-downloader
root@debian:# download-mibs


安装好NET-SNMP软件包以后,一批SNMP实用程序就展现在眼前,其联机手册可以查阅snmpcmd。

$ man snmpcmd
DESCRIPTION
This manual page describes the common options for the SNMP commands: 
snmpbulkget, snmpbulkwalk, snmpdelta, snmpget, snmpgetnext, snmpnetstat, 
snmpset, snmpstatus, snmptable, snmptest, snmptrap, snmpdf, snmpusm , 
snmpwalk . The command line applications use the SNMP protocol to 
communicate with an SNMP capable network entity, an agent. Individual 
applications typically (but not necessarily) take additional parameters 
that are given after the agent specification. These parameters are 
documented in the manual pages for each application.


所有程序启动时都要从文件目录$MIBDIRS中读取其配置文件$MIBS,下列命令告诉我们环境变量$MIBDIRS和$MIBS的具体值。

$ snmptranslate -Dinit_mib .1 2>&1 | grep MIB
init_mib: Seen MIBDIRS: Looking in '/user/.snmp/mibs:/usr/share/snmp/mibs' 
for mib dirs...
init_mib: Seen MIBS: Looking in ':SNMPv2-SMI:SNMPv2-MIB:UCD-SNMP-MIB:
NET-SNMP-AGENT-MIB:NET-SNMP-EXTEND-MIB:NET-SNMP-VACM-MIB' for mib files...


在SNMP世界里,每一个监控对象(Object)都被分类赋予一个标识OID (Object Identifier)。全体即构成管理信息库MIB (Management Information Base),它是树型的组织结构,根节点下有:
    .ccitt (0)
    .iso (1)
    .joint (2)

NET-SNMP的设计目标是管理MIB中.iso.org.dod.internet(或.1.3.6.1)的子树结构。

$ more /usr/share/snmp/mibs/SNMPv2-SMI.txt
SNMPv2-SMI DEFINITIONS ::= BEGIN
org            OBJECT IDENTIFIER ::= { iso 3 }  --  "iso" = 1
dod            OBJECT IDENTIFIER ::= { org 6 }
internet       OBJECT IDENTIFIER ::= { dod 1 }
directory      OBJECT IDENTIFIER ::= { internet 1 }
mgmt           OBJECT IDENTIFIER ::= { internet 2 }
experimental   OBJECT IDENTIFIER ::= { internet 3 }
private        OBJECT IDENTIFIER ::= { internet 4 }
security       OBJECT IDENTIFIER ::= { internet 5 }
snmpV2         OBJECT IDENTIFIER ::= { internet 6 }
mib-2          OBJECT IDENTIFIER ::= { mgmt 1 }
transmission   OBJECT IDENTIFIER ::= { mib-2 10 }


执行snmptranslate可以观测到更形象的树型结构:

$ snmptranslate -Tp .iso
+--iso(1)
   |
   +--org(3)
      |
      +--dod(6)
         |
         +--internet(1)
            |
            +--directory(1)
            |
            +--mgmt(2)
            |  |
            |  +--mib-2(1)
            |     |
            |     +--system(1)
            |     |  |
            |     |  +-- -R-- String    sysDescr(1)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -R-- ObjID     sysObjectID(2)
            |     |  +-- -R-- TimeTicks sysUpTime(3)
            |     |  |  |
            |     |  |  +--sysUpTimeInstance(0)
            |     |  |
            |     |  +-- -RW- String    sysContact(4)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -RW- String    sysName(5)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -RW- String    sysLocation(6)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -R-- INTEGER   sysServices(7)
            |     |  |        Range: 0..127
            |     |  +-- -R-- TimeTicks sysORLastChange(8)
            |     |  |        Textual Convention: TimeStamp
            |     |  |
            |     |  +--sysORTable(9)
            |     |  |
            |     |  +--sysOREntry(1)
            |     |  |  Index: sysORIndex
            |     |  |
            |     |  +-- ---- INTEGER   sysORIndex(1)
            |     |  |        Range: 1..2147483647
            |     |  +-- -R-- ObjID     sysORID(2)
            |     |  +-- -R-- String    sysORDescr(3)
            |     |  |        Textual Convention: DisplayString
            |     |  |        Size: 0..255
            |     |  +-- -R-- TimeTicks sysORUpTime(4)
            |     |           Textual Convention: TimeStamp
            |  ......     ......
            |
            +--snmpV2(6)
               |
               +--snmpDomains(1)
               |  |
               |  +--snmpUDPDomain(1)
               |  +--snmpCLNSDomain(2)
               |  +--snmpCONSDomain(3)
               |  +--snmpDDPDomain(4)
               |  +--snmpIPXDomain(5)


进一步查看.iso.org.dod.internet.mgmt.mib-2.system (.1.3.6.1.2.1.1)部分的子树结构:

$ snmptranslate .iso.org.dod.internet.mgmt.mib-2.system
SNMPv2-MIB::system

$ snmptranslate -On .iso.org.dod.internet.mgmt.mib-2.system
.1.3.6.1.2.1.1

$ more /usr/share/snmp/mibs/SNMPv2-MIB.txt
SNMPv2-MIB DEFINITIONS ::= BEGIN
system   OBJECT IDENTIFIER ::= { mib-2 1 }
sysDescr OBJECT-TYPE
    SYNTAX      DisplayString (SIZE (0..255))
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
            "A textual description of the entity.  This value should
            include the full name and version identification of
            the system's hardware type, software operating-system,
            and networking software."
    ::= { system 1 }
... ...

$ snmptranslate -Tp SNMPv2-MIB::system
+--system(1)
   |
   +-- -R-- String    sysDescr(1)
   |        Textual Convention: DisplayString
   |        Size: 0..255
   +-- -R-- ObjID     sysObjectID(2)
   +-- -R-- TimeTicks sysUpTime(3)
   |  |
   |  +--sysUpTimeInstance(0)
... ...


↑TOP↑

3. 守护进程snmpd

snmpd是NET-SNMP的一个重要组成部分,它是由运行在后台的一个守护进程实现的。在宿主机上snmpd侦听161/udp端口,对接收到的SNMP查询进行回应。首先设置其配置文件:

# vi /etc/snmp/snmpd.conf
sysContact admin
sysLocation wellington
rwcommunity tiger # Community String for SNMP v1 & v2c
rwuser tiger      # User Name for SNMP v3

由于它同时支持三个不同版本的SNMP查询,其配置文件中可以为SNMPv1SNMPv2c设置community名(rwcommunity或rocommunity),也可以为SNMPv3设置user名(rwuser或rouser)。SNMPv3的user有一个认证密码(authentication passphrase)和一个加密密码(privacy passphrase),密码要求8位以上。

# vi /var/lib/net-snmp/snmpd.conf
createUser tiger MD5 authpass DES privpass

启动snmpd后,它会重写/var/lib/net-snmp/snmpd.conf,把所有动态配置的用户等信息写入该文件。

# service snmpd start
# lsof -i udp:snmp


守护进程snmpd启动运行以后,可以从本机上执行NET-SNMP实用程序,测试snmpd是否能对的SNMPv1或SNMPv2c或SNMPv3查询请求做出回应。运行实用程序的同时可以运行tcpdump,侦听本地接口(lo)的所有数据报文。

# tcpdump -i lo
$ snmpwalk -v1 -ctiger localhost system
SNMPv2-MIB::sysDescr.0 = STRING: Linux linux 2.6.32-642.1.1.el6.x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (3224) 0:00:32.24
SNMPv2-MIB::sysContact.0 = STRING: [email protected]
SNMPv2-MIB::sysName.0 = STRING: centos-6
SNMPv2-MIB::sysLocation.0 = STRING: wellington
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (7) 0:00:00.07


执行SNMPv1的实用程序,传递community名,本例中为tiger。可以查询监控对象sysContact.0,其值在snmpd.conf配置文件中设置。

$ snmpget -v1 -ctiger localhost sysContact.0
SNMPv2-MIB::sysContact.0 = STRING: admin


同样可以执行SNMPv2c实用程序,测试snmpd:

$ snmpget -v2c -ctiger localhost sysLocation.0
SNMPv2-MIB::sysLocation.0 = STRING: wellington


用SNMPv3实用程序,就必须要传递user名,本例中为tiger,及其认证密码authpass和加密密码privpass。

$ snmpget -v3 -lAuthPriv -aMD5 -Aauthpass -xDES -Xprivpass -utiger localhost sysUpTimeInstance
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (11641) 0:01:56.41

也可以只做认证,不做数据报文加密:

$ snmpget -v3 -lAuthNoPriv -aMD5 -Aauthpass -utiger localhost sysUpTimeInstance
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (11649) 0:01:56.49

当然还可以既不做认证,也不对数据报文加密。此时的user名就变成和community名一样的功能了。

# sed -i 's/rwuser tiger/rwuser tiger noauth/' /etc/snmp/snmpd.conf
# service snmpd restart

$ snmpget -v3 -lNoAuthNoPriv -utiger localhost sysUpTimeInstance
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (11655) 0:01:56.55


为了简化实用程序的运行,可以事先把调用参数安置于配置文件中。如:

$ vi /etc/snmp/snmp.conf
defVersion 3
defSecurityLevel AuthPriv
defAuthType MD5
defAuthPassphrase authpass
defPrivType DES
defPassphrase privpass
defSecurityName tiger

$ snmpget localhost sysUpTimeInstance
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (11641) 0:01:56.46


同样,可以有如下的SNMPv2c配置文件:

$ vi /etc/snmp/snmp.conf
defVersion 2c
defCommunity tiger



【未完待续】