数据中心网络设备管理(二)

SNMP TRAP

为什么要使用SNMP trap

上篇数据中心网络设备管理(一)中介绍了如何使用snmp get 获取设备信息,网管要在尽量短的时间内获取到设备告警,使用snmp get来获取设备告警,需要网管设置轮询来实现,如果设置轮询时间为5min,告警就有可能在设备发生故障5分钟后才被网管发现,如果设置轮询时间颗粒度过短,就增加了网络流量,增大设备处理数据压力,而snmp trap为网管被动接收设备的告警信息,设备出现告警,会自动给网管发送告警消息。
在这里插入图片描述

SNMP trap 设备配置

以华为设备为例进行配置snmp trap

snmp-agent trap type base-trap                                           //配置trap类型为base-trap
snmp-agent                                                                 //使能snmp-agent
snmp-agent sys-info version all                                           //兼容V1、V2C、V3版本
snmp-agent trap source Loopback0                                   //设置Trap源地址为Loopback0
snmp-agent mib-view included proxyping mib-2 
snmp-agent target-host trap address udp-domain 网管ip params securityname 团体字 v2c

如何解析SNMP trap 报文

接下来进行抓包,分析SNMP trap报文内容,通过tcpdump进行抓包,查看包的形式

sudo tcpdump -i 网卡 udp port 162  -w snmp.pcap

使用wireshark及trapbuffer的一条数据进行分析

time device_name %%01CONFIGURATION/6/hwCfgChgNotify(t):CID=0x80cb000c-OID=1.3.6.1.4.1.2011.5.25.191.3.1;Configuration changed. (CurrentCfgChgSeqID=676, CfgChgSeqIDReveralCount=0, CfgChgTableMaxItem=10000, CfgBaselineTime=2020-01-16 时间)

在这里插入图片描述
variable-bindings为6项,对应分别对应

参数名称参数含义
TIMETICKS可以理解为时间戳
OIDMIB中的告警号标识
CurrentCfgChgSeqID系统配置变更标识。
CfgChgSeqIDReveralCount配置变更流水号反转次数。
CfgChgTableMaxItem系统可以保存的配置变更点数目。
CfgBaselineTime系统配置的基线时间。

明白trap消息格式后,就可以通过程序作为snmp trap的服务器,并根据snmp trap格式还原告警。我这里使用python进行实现

from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import decoder
from pysnmp.proto import api
def cb_fun(self,transport_dispatcher, transport_domain, transport_address, whole_msg):  # 处理Trap信息的函数,返回处理后的字典信息

        while whole_msg:
            msg_ver = int(api.decodeMessageVersion(whole_msg))
            print(msg_ver)#打印下报文

def snmp_trap_receiver(self,if_ip,port):  # 创建snmp_trap_receiver服务器,监听发送来的SNMP Trap信息

        transport_dispatcher = AsynsockDispatcher()  # 创建实例

        transport_dispatcher.registerRecvCbFun(self.cb_fun)  # 调用处理Trap信息的函数

        # UDP/IPv4
        transport_dispatcher.registerTransport(
            udp.domainName, udp.UdpSocketTransport().openServerMode((if_ip,port))  # 绑定到本地地址与UDP/162号端口
        )
        transport_dispatcher.jobStarted(1)  # 开始工作
        print("[SNMP Trap Receiver Started]")
        try:
            transport_dispatcher.runDispatcher()  # 运行
        except Exception as e:
            transport_dispatcher.closeDispatcher()
            print(e)
if __name__ == '__main__':
    snmp_trap_receiver(0.0.0.0,162)

在设备上造一条告警出来后,打印snmp trap报文,为下一步分析做准备


Message:
 version=version-2c
 community=
 data=PDUs:
  snmpV2-trap=SNMPv2TrapPDU:
   request-id=37471
   error-status=noError
   error-index=0
   variable-bindings=VarBindList:
    VarBind:
     name=1.3.6.1.2.1.1.3.0
     =_BindValue:
      value=ObjectSyntax:
       application-wide=ApplicationSyntax:
        timeticks-value=45719668

    VarBind:
     name=1.3.6.1.6.3.1.1.4.1.0
     =_BindValue:
      value=ObjectSyntax:
       simple=SimpleSyntax:
        objectID-value=1.3.6.1.4.1.2011.5.25.191.3.1

    VarBind:
     name=1.3.6.1.4.1.2011.5.25.191.1.1.0
     =_BindValue:
      value=ObjectSyntax:
       simple=SimpleSyntax:
        integer-value=676

    VarBind:
     name=1.3.6.1.4.1.2011.5.25.191.1.2.0
     =_BindValue:
      value=ObjectSyntax:
       simple=SimpleSyntax:
        integer-value=0

    VarBind:
     name=1.3.6.1.4.1.2011.5.25.191.1.3.0
     =_BindValue:
      value=ObjectSyntax:
       simple=SimpleSyntax:
        integer-value=10000

    VarBind:
     name=1.3.6.1.4.1.2011.5.25.191.1.4.0
     =_BindValue:
      value=ObjectSyntax:
       simple=SimpleSyntax:
        string-value=time

使用分割将这6项的值全部提取出来


def analysis(msg_ver):
  if msg_ver in api.protoModules:  # 如果版本兼容
                p_mod = api.protoModules[msg_ver]
            else:  # 如果版本不兼容,就打印错误
                print('Unsupported SNMP version %s' % msg_ver)
                return
            req_msg, whole_msg = decoder.decode(
                whole_msg, asn1Spec=p_mod.Message(),  # 对信息进行解码

            )
            print(req_msg)
            req_pdu = p_mod.apiMessage.getPDU(req_msg)
            if req_pdu.isSameTypeWith(p_mod.TrapPDU()):
                if msg_ver == api.protoVersion1:  # SNMPv1的特殊处理方法,可以提取更加详细的信息
                    var_binds = p_mod.apiTrapPDU.getVarBindList(req_pdu)
                else:  # SNMPv2c的处理方法
                    var_binds = p_mod.apiPDU.getVarBindList(req_pdu)

                result_dict = {}  # 每一个Trap信息,都会整理返回一个字典
                for x in var_binds:  # 打印详细Trap信息
                    result = {}
                    for x, y in x.items():
                        # print(x, y.prettyPrint())  # 最原始信息打印y = {ObjectName: 9} 1.3.6.1.2.1.1.3.0
                        # 处理信息到字典
                        if x == "name":
                            id = y.prettyPrint()  # 把name写入字典的键
                        else:
                            bind_v = [x.strip() for x in y.prettyPrint().split("\n")]
                            for v in bind_v:
                                print(v)
                                if "=" in v:
                                    result[v.split('=')[0]] = v.split('=')[1]
                    result_dict[id] = result
                print(result_dict)

根据提取出来的值和snmp trap对应OID告警模板进行拼接,就可以还原设备告警了,本条告警模板如下:


Configuration changed. (CurrentCfgChgSeqID=[CurrentCfgChgSeqID], CfgChgSeqIDReveralCount=[CfgChgSeqIDReveralCount], CfgChgTableMaxItem=[CfgChgTableMaxItem], CfgBaselineTime=[CfgBaselineTime])
设备当前运行的配置发生改变。

其他告警模板可以在华为官网对应设备文档中找到,这样当设备发生故障或因某些原因导致系统进入不正常的工作状态时,就网管可以被动收到设备产生事件和告警信息。

参考:

https://bbs.csdn.net/topics/391964541?page=1
https://support.huawei.com/carrierindex/zh/anony/index.html
https://stackoverflow.com/questions/33752602/listen-traps-with-pysnmp

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值