zoukankan      html  css  js  c++  java
  • SNMP (Simple Network Management Protocol-简单网络管理协议)

    前言

    在运维工作中我们通常借助SNMP协议,以get/walk  oid到网络设备返回结果的方式,对网络设备进行被动监控。

    但是这种监控方式有如下缺陷:

    监控触发时机无法精确把握

    可监控项比较有限

    Trap是在网络设备上设置各种trap,一旦网络设备(交换机、防火墙、路由器、AC、AP)发生故障时立即触发已设置的trap时,网络设备主动把trap报文汇报到trap-server。(报警全面、及时)

    最终目标是可以做1个类似 H3C的IMC(Intelligent management center)智能管理中心。

    SNMP协议介绍

    什么是SNMP协议?

    Simple Network Management Protocol (SNMP是一种基于UDP协议的,简单的网络管理协议):

    The core of SNMP is a simple set of  operations that gives administrators the ability to get or change the sate of some SNMP-based devive.

    管理员通过1组操作(

    • Get:读取网络设备的状态信息。

    • Set:远程配置设备参数。

    • Trap:被监控设备主动 发送SNMP trap报文。 

    )  去获取和改变基于SNMP设备的状态。

      

    SMI和MIB是什么?

    SMI:The Structure of Management Infomaton.管理信息结构

    SMI defines how management information is grouped and named;allowed operations、permitted data type and synatax for specifying MIBs.

    SMI是一种用于描述单个管理信息节点的数据结构:包含管理节点的oid名称、数据类型、语法。

     VarBind:
      name=1.3.6.1.4.1.2011.5.25.207.1.2.1.1.4.34
      =_BindValue:
       value=ObjectSyntax:
        simple=SimpleSyntax:
         string-value=VTY0

    MIB(妹播):Management Information Base 管理信息库。

    The Management Infromation Base(MIB) can be thought of a database of managed object that the agent tracks

    如果我们采用倒置树结构,使用1个全球唯一的数字把每1个被管理节点的名称标识出来,并保证标识每个被管理节点的数字不重复,这样就组成了1个类似DNS的管理信息库,所以MIB就是1个管理对象名称和oid关系 映射表。

     

    A agent may implement many MIBs(NMS端)

    but all agents implement a particular MIB called MIB-II.(从上图可知:MIb2的从1.3.6.1.2.1开头)

    不管是华为交换机还是什么思科路由器只要它支持SNMP协议,厂家都都会实现了1个MIB库这就是:MIB2

    不同的是每个网络设备厂商都会在1.3.6.1.2.1.N.后面申请1个Enterprise ID例如华为是2011,用来标识自己生产的设备中被管理对象的oid.

    ps:以下是华为交换机的oid信息S2700 V100R006C05

    from pysnmp.entity.rfc3413.oneliner import cmdgen
    cg=cmdgen.CommandGenerator()
    #,安全名称my-agent、社区名public、snmp协议版本,之间用逗号隔开。(snmp协议版本:0代表 snmpv1版本,1代表snmpV2c版本)
    ret=cg.getCmd(cmdgen.CommunityData('xxxxx','xxxx',1), 
            cmdgen.UdpTransportTarget(('10.44.4.48',161)),'1.3.6.1.2.1.1.1.0')   #ip 端口 OID,一个OID对应一种设备(比如网卡、磁盘等,在不同机器上同种设备的OID是一样的)
                #1.3.6.1.2.1.1.1.0#获取系统基本信息
                #1.3.6.1.2.1.1.2.0#获取enterprises.2011.2.23.224
                #1.3.6.1.2.1.1.3.0#系统运行时间
                #1.3.6.1.2.1.1.4.0#系统联系人
                #1.3.6.1.2.1.1.5.0#机器名称
                #1.3.6.1.2.1.1.6.0#机器坐在位置
                #1.3.6.1.4.1.2011.5.25.31.1.1.1.1.5.67108873 CPU使用率
                #1.3.6.1.4.1.2011.5.25.31.1.1.1.1.7.67108873内存使用率
                #1.3.6.1.4.1.2011.5.25.31.1.1.1.1.11.67108873机器温度
                #(1,3,6,1,2,1,1,5,0)
    
                #(1,3,6,1,4,1,2011,6,3,4,1,2,0,0,0) 5秒钟
                #(1,3,6,1,4,1,2011,6,3,4,1,3,0,0,0) 1分钟
                #1.3.6.1.4.1.2011.6.3.4.1,
                #(1,3,6,1,4,1,2011,6,3,4,1,4,0,0,0)  5分钟
    # print(ret[-1])

    SNMP架构

    1.NMS向Agent发送Get/Set请求

    2.Agent接收请求,获取请求报文中携带的oid

    3.从Agent端的MIB中解析oid,执行命令。

    4.讲命令的结果返回NMS

    SNMP的版本

    V1:

    The inital version of SNMP protocol 

    SNMPv1's security is based on communities,which are nothing more than password:plain-text strings that allow any SNMP-based application that knows the strings to gain access to a devive's management infomation.

    SNMP协议的安全主要基于社区,社区就是一个明文字符串,只要监控端(NMS)和被监控端(Agent)之间都使用同了1个明文字符串,就说明他们属于同一社区,所以监控端(NMS)就可以获取、设置被监控设备(Agent)上的管理信息。

    There are typically these communities in SNMPV1:read-only、read-write、trap

    V2/V2C:

    It is often referred to as community-string-based SNMPv2

    The version of SNMP is technically called SNMPV2C 

    SNMPV2版本仍然使用基于社区字符串的方式进行传输数据,当扩展了SNMPv1版本的功能,SNMPv2也被称为SNMPV2C。

    V3:

    It adds support for strong authentication and private comminication between managed entities.

    v3版本在SNMP在NMS(监控端)和Agent(被监控端)之间增加了认证和私有社区字符串。

    ps:截止目前最流行的版本仍然是V1因为v1版本简单,还有就是网络设备更新迭代慢。

    snmpd安装(Agent端)

    在Linux上关于snmp的软件包有2个

    net-snmp:snmp的Agent也就是(被监端)

    net-snmp-utills:NetworkManagement System (NMS监控别人端)

    想要支持trap功能:net-snmp+net-snmp-utills全部安装,因为只有安装了net-snmp包才能监听在UDP的162端口上接收trap报文。

     

    安装(agent+NMS)

    yum install net-snmp net-snmp-utils

    启动snmpd(agent)

    [root@zhanggen snmp]# systemctl restart snmpd
    [root@zhanggen snmp]# netstat -unlp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name         
    udp        0      0 0.0.0.0:161             0.0.0.0:*                           3506/snmpd   

    获取监控信息

    [root@zhanggen snmp]# snmpwalk -v 2c -c public localhost
    SNMPv2-MIB::sysDescr.0 = STRING: Linux zhanggen 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64
    SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
    DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (63840) 0:10:38.40
    SNMPv2-MIB::sysContact.0 = STRING: Root <root@localhost> (configure /etc/snmp/snmp.local.conf)
    SNMPv2-MIB::sysName.0 = STRING: zhanggen
    SNMPv2-MIB::sysLocation.0 = STRING: Unknown (edit /etc/snmp/snmpd.conf)
    SNMPv2-MIB::sysORLastChange.0 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDCompliance
    SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
    SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
    SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
    SNMPv2-MIB::sysORID.5 = OID: TCP-MIB::tcpMIB
    SNMPv2-MIB::sysORID.6 = OID: IP-MIB::ip
    SNMPv2-MIB::sysORID.7 = OID: UDP-MIB::udpMIB
    SNMPv2-MIB::sysORID.8 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
    SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
    SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
    SNMPv2-MIB::sysORDescr.1 = STRING: The MIB for Message Processing and Dispatching.
    SNMPv2-MIB::sysORDescr.2 = STRING: The management information definitions for the SNMP User-based Security Model.
    SNMPv2-MIB::sysORDescr.3 = STRING: The SNMP Management Architecture MIB.
    SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
    SNMPv2-MIB::sysORDescr.5 = STRING: The MIB module for managing TCP implementations
    SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing IP and ICMP implementations
    SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
    SNMPv2-MIB::sysORDescr.8 = STRING: View-based Access Control Model for SNMP.
    SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
    SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
    SNMPv2-MIB::sysORUpTime.1 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.2 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.3 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.4 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.5 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.6 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.7 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.8 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.9 = Timeticks: (2) 0:00:00.02
    SNMPv2-MIB::sysORUpTime.10 = Timeticks: (2) 0:00:00.02
    HOST-RESOURCES-MIB::hrSystemUptime.0 = Timeticks: (121940) 0:20:19.40
    HOST-RESOURCES-MIB::hrSystemUptime.0 = No more variables left in this MIB View (It is past the end of the MIB tree)
    [root@zhanggen snmp]# 

     获取主机名

    [root@zhanggen long]# snmpget -v 2c -c public 127.0.0.1 .1.3.6.1.2.1.1.5.0
    SNMPv2-MIB::sysName.0 = STRING: zhanggen

    后台启动snmptrapd

    [root@zhanggen snmp]# systemctl restart snmptrapd
    [root@zhanggen snmp]# netstat -unlp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name         
    udp        0      0 0.0.0.0:161             0.0.0.0:*                           3506/snmpd          
    udp        0      0 0.0.0.0:162             0.0.0.0:*                           4304/snmptrapd         
    [root@zhanggen snmp]# 

    前台启动snmptrapd

    [root@zhanggen bin]# snmptrapd -C -c/etc/snmp/snmptrapd.conf -df -Lo
    NET-SNMP version 5.7.2
    
    Received 72 byte packet from UDP: [127.0.0.1]:56573->[127.0.0.1]:162
    0000: 30 46 02 01  01 04 06 70  75 62 6C 69  63 A7 39 02    0F.....public.9.
    0016: 04 29 A7 B1  EC 02 01 00  02 01 00 30  2B 30 18 06    .).........0+0..
    0032: 0A 2B 06 01  06 03 01 01  04 01 00 06  0A 2B 06 01    .+...........+..
    0048: 04 01 8F 65  81 7B 01 30  0F 06 08 2B  06 01 02 01    ...e.{.0...+....
    0064: 01 06 00 04  03 65 65 65                              .....eee
    
    

    2020-06-12 01:18:49 localhost [UDP: [127.0.0.1]:54044->[127.0.0.1]:162]:
    SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.2345 SNMPv2-MIB::sysLocation.0 = STRING: just here

    -C : 表示不使用net-snmp默认路径下的配置文件snmptrapd.conf;
    -c : 指定snmptrapd.conf文件;
    -d : 显示收到和发送的数据报,通过这个选项可以看到数据报文;
    -f  : 默认情况下,snmptrapd是在后台中运行的,加上这个选项,表示在前台运行;
    -L : 指定日志记录在哪里,后面的o表示直接输出到屏幕上,如果是跟着f表示日志记录到指定的文件中;

    snmp utills使用(NMS端)

    如果有snmpd工作在161端口,那我么就可以使用snmp utills发送各种SNMP操作了。

    发送snmptrap报文

    trap client发送
    [root@zhanggen long]# snmptrap -v 2c -c public 127.0.0.1 "zhanggen" 1.3.6.1.4.1.2345 SNMPv2-MIB::sysLocation.0 s "this is a trap pud please load oid-->1.3.6.1.4.1.2345 in SNMPv2-MIB::sysLocation.0"
    
    trap server接收
    2020-06-12 18:23:51 localhost [UDP: [127.0.0.1]:55926->[127.0.0.1]:162]:
    SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.2345    SNMPv2-MIB::sysLocation.0 = STRING: this is a trap pud please load oid-->1.3.6.1.4.1.2345 in SNMPv2-MIB::sysLocation.0

    参数说明:

    -v 1|2c|3 specifies SNMP version to use(指定SNMP协议版本)

    127.0.0.1:162 “zhanggen”:Trap server的IP、主机名,主机名称可以为空;

    -c COMMUNITY set the community string(设置社区名称:agent和nms的之间通过社区建立信任)

    .3.6.1.4.1.2345:企业OID,Enterprise-OID;

    -m MIB[:...] load given list of MIBs (ALL loads everything)(Trap消息使用MIB库解析oid和object name, 指定mib库文件)

    -M DIR[:...] look in given list of directories for MIBs(指定mib库所在目录)

    SNMPv2-MIB::sysLocation.0 s “just here”:SNMPv2-MIB::sysLocation.0 触发SNMPv2-MIB库下sysLocation.0对象(oid对应的objectname)的报警、s:数据类型、数据值。

    just her:说明

    Trap PDU结构 ( SNMP v1 )

    字段

    类型

    说明

    PDU Type

    PDU类型,Trap为4

    Enterprise

    Object Identifier

    产生该Trap的网络管理子系统,基于sysObjectID。如果是企业自定义Trap,此值为企业在enterprise子树下的注册子树。

    Agent-addr

    NetworkAddress

    产生Trap的SNMP实体地址,一般为代理地址

    Generic-trap

    Integer

    通用trap类型,取值为coldStart、warmStart、linkDown、linkUp、authenticationFailure、egpNeihborLoss、enterpriseSpecific

    Specific-trap

    Integer

    当Generic-trap为enterpriseSpecific时,specific-trap指明具体的企业自定义Trap类型,specific-trap跟在enterprise后面,组成了Trap的标识

    Time-stamp

    TimeTicks

    上次初始化网络实体和产生Trap的时间间隔,包含sysUpTime值

    Variable-bindings

    Sequences of

    和Trap相关的附加信息

    PDU结构(SNMP v2c)

    字段

    类型

    说明

    PDU Type

    PDU类型

    request-id

    Integer

    发送实体通过给每个PDU赋一个id使每一个到同一代理的请求能够被唯一识别,代理应答时原封不动返回request-id值,使发送方可以将应答和请求匹配,也可以使双方有能力处理UDP中可能产生的重复发送的消息

    Error-status

    Integer

    用于表示在处理请求时出现的异常,对于trap数据包该字段为0。

    Error-index

    Integer

    错误索引,对于trap数据包该字段为0。

    variableBindings

    Sequences of

    所要求的实例列表

    接收trap报文

    python的pysnmp实现了对snmp协议的封装,我们既可以使用这个模块发送 trap/get/walk消息,还可以使用它作为trap-server接收trap报文。

    #!/usr/bin/python3
    #encoding=utf8
    import datetime,requests,json
    from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
    from pysnmp.carrier.asynsock.dgram import udp, udp6
    from pyasn1.codec.ber import decoder
    from pysnmp.proto import api
    
    
    class TrapServer(object):
        def __init__(self,transfer_server):
            self.trap_server=transfer_server
    
        def run_trap_server(self):
            transportDispatcher = AsynsockDispatcher()
            #回调函数
            transportDispatcher.registerRecvCbFun(self.recive_trapPDU)
            # UDP/IPv4
            transportDispatcher.registerTransport(
                udp.domainName, udp.UdpSocketTransport().openServerMode(('0.0.0.0', 162))
            )
            # UDP/IPv6
            transportDispatcher.registerTransport(
                udp6.domainName, udp6.Udp6SocketTransport().openServerMode(('::1', 162))
            )
            transportDispatcher.jobStarted(1)
            try:
                # Dispatcher will never finish as job#1 never reaches zero
                transportDispatcher.runDispatcher()
            except:
                transportDispatcher.closeDispatcher()
                raise
    
        def recive_trapPDU(self, transportDispatcher, transportDomain, transportAddress, wholeMsg):
            while wholeMsg:
                # 解析消息版本
                msgVersion = int(api.decodeMessageVersion(wholeMsg))
                print("消息SNMP版本:0:v1, v1:v2c", msgVersion, datetime.datetime.now())
                ##根据snmp版本选择protoModules模块
                if msgVersion in api.protoModules:
                    pMod = api.protoModules[msgVersion]
                else:
                    print('不支持的 SNMP 版本 %s' % msgVersion)
                    return
                # 根据protoModules解码snmp的消息
                reqMsg, wholeMsg = decoder.decode(
                    wholeMsg, asn1Spec=pMod.Message(),
                )
                # SNMPv2TrapPDU:
                reqPDU = pMod.apiMessage.getPDU(reqMsg)
                # 判断是否为Mod.TrapPDU
                if reqPDU.isSameTypeWith(pMod.TrapPDU()):
                    trapPDU_metadata={}
                    if msgVersion == api.protoVersion1:
                        trapPDU_metadata["up_time"] =  pMod.apiTrapPDU.getTimeStamp(reqPDU).prettyPrint()
                        trapPDU_metadata["agent_address"] = pMod.apiTrapPDU.getAgentAddr(reqPDU).prettyPrint()
                        trapPDU_metadata["trap_generic"] = pMod.apiTrapPDU.getGenericTrap(reqPDU).prettyPrint()
                        trapPDU_metadata["trap_OID"] =pMod.apiTrapPDU.getEnterprise(reqPDU).prettyPrint()+'.'+pMod.apiTrapPDU.getSpecificTrap(reqPDU).prettyPrint()
                        #self.analy_trapPDU(trapPDU_metadata)
                        varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU)
                    else:
                        varBinds = pMod.apiPDU.getVarBindList(reqPDU)
                    bind_info = ''
                    for bind in varBinds:
                        for line in bind.values():
                            line=str(line)
                            '''
                        === 1.3.6.1.4.1.2011.6.122.62.1.4.0
                        === ObjectSyntax:
                            simple=SimpleSyntax:
                            string=ssh
                        '''
                            if line.startswith("1.3.6.1"):
                                line="[%s]"%line
                            bind_info+=line
                    trapPDU_metadata["trap_details"]=bind_info
                    self.trap_transfer(trapPDU_metadata)
                    return
    
        def trap_transfer(self,data):
            data=json.dumps(data,ensure_ascii=False)
            headers = {'Content-Type':'application/json'}
            requests.post(url=self.trap_server, headers=headers, data=data)
    
    if __name__ == '__main__':
        trapserver=TrapServer("http://127.0.0.1:8001/IToperation/trap/receive/API/")
        trapserver.run_trap_server()
    经典版

    经典版trap-server无法获取snmp v2c版本报文的up_time、agent_address、trap_generic。

    那就使用snmpv1版本把,可以当 AC发送报文过来时获取的agent_address是127.0.1.1。我中途研究了snmp 报文的编码规则 ASN1,试图通过ASN1进行解码。

    from socket import *
    from pysnmp.proto import api
    from pyasn1.codec.der.decoder import decode
    server = socket(AF_INET, SOCK_DGRAM)
    server.bind(('10.44.13.73', 162))
    while True:
        data1, addr = server.recvfrom(1024)
        msgVer = int(api.decodeMessageVersion(data1))
        pMod = api.protoModules[msgVer]
        reqMsg, wholeMsg =decode(data1,asn1Spec=pMod.Message())
        reqPDU = pMod.apiMessage.getPDU(reqMsg)
        varBinds = pMod.apiPDU.getVarBindList(reqPDU)
        print(addr)
        print('--------')
        print(varBinds)
        print('--------')
    pyasn1自己解码

    在研究如何对发送到udp:162的trap报文进行ASN解码的时候,我发现pysnmp模块的官网。

    可以同时监听在多个port上,支持snmp v1和v2c版本trap/infro报文。

    from pysnmp.entity import engine, config
    from pysnmp.carrier.asyncore.dgram import udp
    from pysnmp.entity.rfc3413 import ntfrcv
    
    # Create SNMP engine with autogenernated engineID and pre-bound
    # to socket transport dispatcher
    snmpEngine = engine.SnmpEngine()
    
    # Transport setup
    
    # UDP over IPv4, first listening interface/port
    config.addTransport(
        snmpEngine,
        udp.domainName + (1,),
        udp.UdpTransport().openServerMode(('127.0.0.1', 162))
    )
    
    # UDP over IPv4, second listening interface/port
    config.addTransport(
        snmpEngine,
        udp.domainName + (2,),
        udp.UdpTransport().openServerMode(('127.0.0.1', 2162))
    )
    
    # SNMPv1/2c setup
    
    # SecurityName <-> CommunityName mapping
    config.addV1System(snmpEngine, 'my-area', 'public')
    
    
    # Callback function for receiving notifications
    # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal
    def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
              varBinds, cbCtx):
        print('Notification from ContextEngineId "%s", ContextName "%s"' % (contextEngineId.prettyPrint(),
                                                                            contextName.prettyPrint()))
        for name, val in varBinds:
            print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
    
    
    # Register SNMP Application at the SNMP engine
    ntfrcv.NotificationReceiver(snmpEngine, cbFun)
    
    snmpEngine.transportDispatcher.jobStarted(1)  # this job would never finish
    
    # Run I/O dispatcher which would receive queries and send confirmations
    try:
        snmpEngine.transportDispatcher.runDispatcher()
    except:
        snmpEngine.transportDispatcher.closeDispatcher()
        raise
    Serving multiple network interfaces

    可以监听在ipv4和ipv6上,支持snmp v1和v2c版本trap/infro报文。

    from pysnmp.entity import engine, config
    from pysnmp.carrier.asyncore.dgram import udp, udp6
    from pysnmp.entity.rfc3413 import ntfrcv
    
    # Create SNMP engine with autogenernated engineID and pre-bound
    # to socket transport dispatcher
    snmpEngine = engine.SnmpEngine()
    
    # Transport setup
    
    # UDP over IPv4
    config.addTransport(
        snmpEngine,
        udp.domainName,
        udp.UdpTransport().openServerMode(('127.0.0.1', 162))
    )
    
    # UDP over IPv6
    config.addTransport(
        snmpEngine,
        udp6.domainName,
        udp6.Udp6Transport().openServerMode(('::1', 162))
    )
    
    # SNMPv1/2c setup
    
    # SecurityName <-> CommunityName mapping
    config.addV1System(snmpEngine, 'my-area', 'public')
    
    
    # Callback function for receiving notifications
    # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal
    def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
              varBinds, cbCtx):
        print('Notification from ContextEngineId "%s", ContextName "%s"' % (contextEngineId.prettyPrint(),
                                                                            contextName.prettyPrint()))
        for name, val in varBinds:
            print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
    
    
    # Register SNMP Application at the SNMP engine
    ntfrcv.NotificationReceiver(snmpEngine, cbFun)
    
    snmpEngine.transportDispatcher.jobStarted(1)  # this job would never finish
    
    # Run I/O dispatcher which would receive queries and send confirmations
    try:
        snmpEngine.transportDispatcher.runDispatcher()
    except:
        snmpEngine.transportDispatcher.closeDispatcher()
        raise
    Using multiple network transports

    监听在ipv4 ip地址的162端口

    from pysnmp.entity import engine, config
    from pysnmp.carrier.asyncore.dgram import udp
    from pysnmp.entity.rfc3413 import ntfrcv
    
    # Create SNMP engine with autogenernated engineID and pre-bound
    # to socket transport dispatcher
    snmpEngine = engine.SnmpEngine()
    
    # Transport setup
    
    # UDP over IPv4, first listening interface/port
    config.addTransport(
        snmpEngine,
        udp.domainName + (1,),
        udp.UdpTransport().openServerMode(('127.0.0.1', 162))
    )
    
    # SNMPv1/2c setup
    
    # SecurityName <-> CommunityName mapping
    config.addV1System(snmpEngine, 'my-area', 'public')
    
    
    # Callback function for receiving notifications
    # noinspection PyUnusedLocal,PyUnusedLocal
    def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
              varBinds, cbCtx):
        # Get an execution context...
        execContext = snmpEngine.observer.getExecutionContext(
            'rfc3412.receiveMessage:request'
        )
    
        # ... and use inner SNMP engine data to figure out peer address
        print('Notification from %s, ContextEngineId "%s", ContextName "%s"' % ('@'.join([str(x) for x in execContext['transportAddress']]),
                                                                                contextEngineId.prettyPrint(),
                                                                                contextName.prettyPrint()))
        for name, val in varBinds:
            print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
    
    
    # Register SNMP Application at the SNMP engine
    ntfrcv.NotificationReceiver(snmpEngine, cbFun)
    
    snmpEngine.transportDispatcher.jobStarted(1)  # this job would never finish
    
    # Run I/O dispatcher which would receive queries and send confirmations
    try:
        snmpEngine.transportDispatcher.runDispatcher()
    except:
        snmpEngine.transportDispatcher.closeDispatcher()
        raise
    Receive notifications noting peer address

    1个完整trap报文

    以下是pysnmp 接收到的一个完整的trap报文,由

    • transportDomain
    • transportAddress
    • wholeMsg
    • messageProcessingModel
    • securityModel
    • securityName
    • securityLevel
    • contextEngineId
    • contextName
    • pdu

    构成。

    transportDomain ----------- (1, 3, 6, 1, 6, 1, 1, 1)
    transportAddress ----------- ('10.8.193.10', 32774)
    wholeMsg ----------- b"0x82x01Hx02x01x00x04x08hbit@618xa4x82x017x06
    +x06x01x04x01x83x042x00x0b@x04x7fx00x01x01x02x01x06x02x01x14Cx04rQxa6xa40x82x01x150#x06x0c+x06x01x04x01x83x042x01x02x01x01x04x13EAP_OPP_CACHED_KEYS0x15x06x0c+x06x01x04x01x83x042x01x02x01x02x04x05DOT110x11x06x0c+x06x01x04x01x83x042x01x02x01x03x02x01x060x81x88x06x0c+x06x01x04x01x83x042x01x02x01x04x04xOpportunistic Key Cache used for client 'F8-DA-0C-54-29-79' on wlan 'JD' radio 'XH-6F01-AP03-5708:R1'. Skipping 802.1x. 0x16x06x0c+x06x01x04x01x83x042x01x02x01x05x04x06x84$x8dx87Wx080!x06x0c+x06x01x04x01x83x042x01x02x01x06x04x11XH-6F01-AP03-5708"
    messageProcessingModel ----------- 0
    securityModel ----------- 1
    securityName ----------- my-area
    securityLevel ----------- 1
    contextEngineId ----------- O¸4$¥H
    contextName ----------- 
    pdu ----------- TrapPDU:
     enterprise=1.3.6.1.4.1.388.50.0.11
     agent-addr=NetworkAddress:
      internet=127.0.1.1
    
     generic-trap=enterpriseSpecific
     specific-trap=20
     time-stamp=1917953700
     variable-bindings=VarBindList:
      VarBind:
       name=1.3.6.1.4.1.388.50.1.2.1.1
       value=ObjectSyntax:
        simple=SimpleSyntax:
         string=EAP_OPP_CACHED_KEYS
    
    
      VarBind:
       name=1.3.6.1.4.1.388.50.1.2.1.2
       value=ObjectSyntax:
        simple=SimpleSyntax:
         string=DOT11
    
    
      VarBind:
       name=1.3.6.1.4.1.388.50.1.2.1.3
       value=ObjectSyntax:
        simple=SimpleSyntax:
         number=6
    
    
      VarBind:
       name=1.3.6.1.4.1.388.50.1.2.1.4
       value=ObjectSyntax:
        simple=SimpleSyntax:
         string=Opportunistic Key Cache used for client 'F8-DA-0C-54-29-79' on wlan 'JD' radio 'XH-6F01-AP03-5708:R1'. Skipping 802.1x. 
    
    
      VarBind:
       name=1.3.6.1.4.1.388.50.1.2.1.5
       value=ObjectSyntax:
        simple=SimpleSyntax:
         string=0x84248d875708
    
    
      VarBind:
       name=1.3.6.1.4.1.388.50.1.2.1.6
       value=ObjectSyntax:
        simple=SimpleSyntax:
         string=XH-6F01-AP03-5708
    trap报文格式

    发送snmpget

    查看1个具体的oid节点

    [root@zhanggen long]# snmpget -v 2c -c 社区名称 10.44.4.48 1.3.6.1.4.1.2011.5.2.1.4.1.1.14.51.54.48.98.117.121.97.100.46.108.111.99.97.108
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.1.14.51.54.48.98.117.121.97.100.46.108.111.99.97.108 = STRING: "360.local"
    [root@zhanggen long]# snmpget -v 2c -c 社区名称 10.44.4.48 1.3.6.1.4.1.2011.5.2.1.4.1.1.14.51.54.48.98.117.121.97.100.46.108.111.99.97.108

    发送snmpwalk

    如果对某个叶子节点的OID值做walk遍历

    [root@zhanggen]# snmpwalk -v 2c -c 社区名称  10.44.4.48 1.3.6.1.4.1.2011.5
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.1.4.97.117.116.104 = STRING: "auth"
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.1.6.114.97.100.105.117.115 = STRING: "radius"
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.1.7.100.101.102.97.117.108.116 = STRING: "default"
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.2.4.97.117.116.104 = INTEGER: 5
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.2.6.114.97.100.105.117.115 = INTEGER: 3
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.2.7.100.101.102.97.117.108.116 = INTEGER: 1
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.3.4.97.117.116.104 = INTEGER: 1
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.3.6.114.97.100.105.117.115 = INTEGER: 1
    SNMPv2-SMI::enterprises.2011.5.2.1.1.1.3.7.100.101.102.97.117.108.116 = INTEGER: 1
    SNMPv2-SMI::enterprises.2011.5.2.1.2.1.1.7.100.101.102.97.117.108.116 = STRING: "default"
    SNMPv2-SMI::enterprises.2011.5.2.1.2.1.2.7.100.101.102.97.117.108.116 = INTEGER: 2
    SNMPv2-SMI::enterprises.2011.5.2.1.2.1.3.7.100.101.102.97.117.108.116 = INTEGER: 2
    SNMPv2-SMI::enterprises.2011.5.2.1.2.1.4.7.100.101.102.97.117.108.116 = INTEGER: 1
    SNMPv2-SMI::enterprises.2011.5.2.1.2.1.5.7.100.101.102.97.117.108.116 = INTEGER: 0
    SNMPv2-SMI::enterprises.2011.5.2.1.2.1.6.7.100.101.102.97.117.108.116 = INTEGER: 1
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.1.7.100.101.102.97.117.108.116 = STRING: "default"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.1.13.100.101.102.97.117.108.116.95.97.100.109.105.110 = STRING: "sss"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.1.14.51.54.48.98.117.121.97.100.46.108.111.99.97.108 = STRING: "ssss"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.2.7.100.101.102.97.117.108.116 = STRING: "ssss"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.2.13.100.101.102.97.117.108.116.95.97.100.109.105.110 = STRING: "default"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.2.14.51.54.48.98.117.121.97.100.46.108.111.99.97.108 = STRING: "auth"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.3.7.100.101.102.97.117.108.116 = STRING: "default"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.3.13.100.101.102.97.117.108.116.95.97.100.109.105.110 = STRING: "default"
    SNMPv2-SMI::enterprises.2011.5.2.1.4.1.3.14.51.54.48.98.117.121.97.100.46.108.111.99.97.108 = STRING: "default"

     

    trap接收

    S2750常用OID

    华为

    SNMP MIB

  • 相关阅读:
    统计:概述
    概率论总结
    概率论13 中心极限定律
    概率论12 矩与矩生成函数
    概率论11 协方差与相关系数
    概率论10 方差与标准差
    概率论09 期望
    概率论08 随机变量的函数
    mysql 分区
    Linux 搭建svn版本库
  • 原文地址:https://www.cnblogs.com/sss4/p/13097510.html
Copyright © 2011-2022 走看看