0x00 SNMP TRAP简介

SNMP(Simple Network Management Protocol) trap是一种很有用,但是也容易让人难以理解的协议。

虽然名字叫做简单网络管理协议,但实际上并不是字面上的意思,尤其是看到.1.3.6.1.2.1.1.1.0这样一串串诡异的数字时候,就会有点让人崩溃。

不管怎么说,现在所有的网络设备的都需要支持SNMP。而且现在还有很多的开源的网络管理系统,所以就有利于我们来学习和理解SNMP。

SNMP trap是由被管理的设备主动的向管理服务器发送设备的异常情况,可以看成是管理服务器被动的去接收的过程。

所以会有很多的工具会把snmptrap集成到自己的工具中,对网络设备进行监控。

把SNMP trap集成的到Nagios当中的,大体的工作流程是:

1. 由snmptrapd来接收网络设备发出的trap
2. snmptrapd调用snmptt(snmp trap translator 翻译器)
3. snmptt中定义了每一种trap的级别,以及什么样的trap才有必要写入到syslog中
4. SEC(simple event correlator是一个事件收集器)从syslog中读取每一个事件,并把调用用户的脚本snmptraphandling.py 来处理。
5. snmptraphandling.py 会调用根据主机名和trap的级别来调用相当的Nagios命令行。

这个过程包含了很多层,所以感觉很复杂,还是深入进去看看snmptrapd是怎么工作的。从而尽可能简化snmptrap的使用方法。

snmptrapd来自开源软件Net-SNMP. Net-SNMP会有很多的用途,当然使用trap也是一个很有用的用途。当snmptrapd接收到trap以后,可以调用用户自定义的脚本或者命令行来处理trap。如果想使用这个功能就需要在snmptrapd的配置文件中设置traphandle。 snmptrapd接收到的trap信息格式是:

1. 数据包来源的主机名字。
2. 数据包来源的ip地址。
3. 数据包中的内容。

traphandle的工作就是读取这些内容并进行处理就可以了。

Trap信息例子:

cisco2611.lon.altinity
192.168.10.20
RFC1213-MIB::sysUpTime.0 0:18:14:45.66
SNMPv2-MIB::snmpTrapOID.0 IF-MIB::linkDown
RFC1213-MIB::ifIndex.2 2
RFC1213-MIB::ifDescr.2 "Serial0/0"
RFC1213-MIB::ifType.2 ppp
OLD-CISCO-INTERFACES-MIB::locIfReason.2 "administratively down"
SNMP-COMMUNITY-MIB::snmpTrapAddress.0 192.168.10.20
SNMP-COMMUNITY-MIB::snmpTrapCommunity.0 "public"
SNMPv2-MIB::snmpTrapEnterprise.0 CISCO-SMI::ciscoProducts.186

因为snmptt对trap信息中的OID进行了翻译,如果不进行翻译的话,那么trap信息的样子应该是

cisco2611.lon.altinity
192.168.10.20
.1.3.6.1.2.1.1.3.0 0:18:13:59.95
.1.3.6.1.6.3.1.1.4.1.0 .1.3.6.1.6.3.1.1.5.3
.1.3.6.1.2.1.2.2.1.1.2 2
.1.3.6.1.2.1.2.2.1.2.2 "Serial0/0"
.1.3.6.1.2.1.2.2.1.3.2 ppp
.1.3.6.1.4.1.9.2.2.1.1.20.2 "administratively down"
.1.3.6.1.6.3.18.1.3.0 192.168.10.20
.1.3.6.1.6.3.18.1.4.0 "public"
.1.3.6.1.6.3.1.1.4.3.0 .1.3.6.1.4.1.9.1.186

这就说明了,snmptt拥有自己的配置文件,文件中包含了OID和对应的属性名,并且是使用OID来进行索引的。如果snmptt在配置文件中无法找到对应的OID的话,那么snmptt也就无法对信息进行翻译,我们看到的信息内容也就是原始的格式了。

snmptt使用的配置文件叫做MIBs(Management Information
Base管理信息基础),在MIBs以OID为索引的key,可以快速查找到对应的文字形式和警告的级别。每一个MIB都有自己固定的定义格式,其中会包含一个宏(用来说明要显示信息的内容)。

可是为什么要有MIBs的存在呢?直接由snmptrapd来完成OID到信息的翻译不可以么?
1. MIBs是可以由用户自己来定义,使用的。因为各厂商对trap信息定义的内容肯定是不同的,所以想要snmp有一定的扩展性,那么就必须要支持用户自定义MIBs文件。这也就是MIBs存在的原因。
2.
如果由snmptrapd自己来完成翻译也是可以的,因为如果每次都去通过检索OID对应的消息的话,那对性能的影响是非常的大的,因此snmptrapd就需要读入MIBs。问题也就出现了,如果更新MIBs话,就要把snmptrapd重新启动,必定会影响到trap消息的接收。所以把snmptt作为一个独立的deamon存在是很正确的选择。

最后要做的事情就是添加traphandle了,handle会影响到snmptrap的接收性能,所以处理的速度要快,因为handle有可能1秒中会有数百次的调用。
 这样以来上面的处理流程就可以进行简化的:
1. snmptrapd接收到trap的信息
2. snmptrapd调用handle(如果不是调用现有的命令的话,在handle中就可以完成所有的处理了,就没有下面的处理了。又节省了一步,哈哈)
3. handle中再调用Nagios的命令行就可以了

这样一看流程就简单许多了,以后再使用snmptrap的时候也可以参考这个处理的流程

0x01 SNMP TRAP流程

SNMP Trap流程可参考这篇文章

0x02 SNMP Trap接受用Python实现

下载 安装pysnmp-4.2.5.tar.gz (md5)

https://pypi.python.org/pypi/pysnmp/

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
from test_case_common import * def cbFun(transportDispatcher, transportDomain, transportAddress, wholeMsg):
while wholeMsg:
msgVer = int(api.decodeMessageVersion(wholeMsg))
if msgVer in api.protoModules:
pMod = api.protoModules[msgVer]
else:
print('Unsupported SNMP version %s' % msgVer)
return
reqMsg, wholeMsg = decoder.decode(
wholeMsg, asn1Spec=pMod.Message(),
)
print('Notification message from %s:%s: ' % (
transportDomain, transportAddress
)
)
reqPDU = pMod.apiMessage.getPDU(reqMsg)
if reqPDU.isSameTypeWith(pMod.TrapPDU()):
if msgVer == api.protoVersion1:
print('Enterprise: %s' % (
pMod.apiTrapPDU.getEnterprise(reqPDU).prettyPrint()
)
)
print('Agent Address: %s' % (
pMod.apiTrapPDU.getAgentAddr(reqPDU).prettyPrint()
)
)
print('Generic Trap: %s' % (
pMod.apiTrapPDU.getGenericTrap(reqPDU).prettyPrint()
)
)
print('Specific Trap: %s' % (
pMod.apiTrapPDU.getSpecificTrap(reqPDU).prettyPrint()
)
)
print('Uptime: %s' % (
pMod.apiTrapPDU.getTimeStamp(reqPDU).prettyPrint()
)
)
varBinds = pMod.apiTrapPDU.getVarBindList(reqPDU)
else:
varBinds = pMod.apiPDU.getVarBindList(reqPDU)
print('Var-binds:')
for oid, val in varBinds:
a = oid.prettyPrint().strip()
b = val.prettyPrint().strip().split('\n')
print a
for line in b:
item = line.strip()
if item.startswith('string-value'):
print 'string-value='+item.replace('string-value=0x','').decode('hex')
else:
print item
return wholeMsg if __name__ == '__main__':
transportDispatcher = AsynsockDispatcher() transportDispatcher.registerRecvCbFun(cbFun) # 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

SNMP学习笔记之SNMP TRAP简介、流程以及使用Python实现接受Trap信息的更多相关文章

  1. SNMP学习笔记之SNMP 原理与实战详解

    原文地址:http://freeloda.blog.51cto.com/2033581/1306743 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法 ...

  2. SNMP学习笔记之SNMP报文协议详解

    0x00 简介 简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议.在1988年被制定,并被Internet体系结构委员会(IAB)采纳作为一个短期的网络管理解决方案:由于SNMP的简单 ...

  3. SNMP学习笔记之SNMP介绍,OID及MIB库

    1.1.    SNMP概览 SNMP的基本知识介绍简单网络管理协议(SNMP-Simple Network Management Protocol)是一个与网络设备交互的简单方法.该规范是由IETF ...

  4. SNMP学习笔记之SNMP报文以及不同版本(SNMPv1、v2c、v3)的区别

    本篇文章将重点分析SNMP报文,并对不同版本(SNMPv1.v2c.v3)进行区别! 四.SNMP协议数据单元 在SNMP管理中,管理站(NMS)和代理(Agent)之间交换的管理信息构成了SNMP报 ...

  5. SNMP学习笔记之SNMP简单概述

    0x00 SNMP简单概述 0.1.什么是Snmp SNMP是英文"Simple Network Management Protocol"的缩写,中文意思是"简单网络管理 ...

  6. SNMP学习笔记之SNMP的安装及Python的调用

    0x00 概述 本文是介绍SNMP在Windows和Linux(Ubuntu)下的安装,以及通过Python调用其接口的文章. 0x01 开发环境 Python 3.5.1 Windows 10 64 ...

  7. SNMP学习笔记之SNMP树形结构介绍

    Basic command of SNMP: GET: The GET operation is a request sent by the manager to the managed device ...

  8. 【web开发学习笔记】Structs2 Result学习笔记(一)简介

    Structs2 Result学习笔记(一)简介 问题一 <struts> <constant name="struts.devMode" value=" ...

  9. Linux学习笔记之 Btrfs文件系统简介及使用

    Btrfs 也有一个重要的缺点,当 BTree 中某个节点出现错误时,文件系统将失去该节点之下的所有的文件信息.而 ext2/3 却避免了这种被称为”错误扩散”的问题. Btrfs相关介绍: Btrf ...

随机推荐

  1. tomcat启动报错“Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: iZ25fsk1ifk: iZ25fsk1ifk”

    在启动了Tomcat的时候出现下面的错误,导致启动不了,卡在读日志的状态 Error: Exception thrown by the agent : java.net.MalformedURLExc ...

  2. TOP100summit 2017:微博如何做到1小时增加一千台服务器应对鹿晗恋情带来的流量暴增

    10月8日中午12点,鹿晗和关晓彤宣布恋情,年近30的我并不关心小鲜肉们的分分合合,但是作为壹佰案例这个软件研发行业自媒体的小编,我更关注因此引发的微博宕机事件. 鹿晗公布恋情的微博获得462884次 ...

  3. hihocoder 1323 - 回文字符串 - [hiho一下162周][区间dp]

    用dp[i][j]表示把[i,j]的字符串str改写成回文串需要的最小操作步数. 并且假设所有dp[ii][jj] (ii>i , jj<j)都为已知,即包括dp[i+1][j].dp[i ...

  4. 应该掌握的JQuery的7个效果

    一: 语法: $(selector).hide(speed,callback); $(selector).show(speed,callback); 实例 //点击隐藏 $("#hide&q ...

  5. 《Nginx - 变量》- log_format/核心变量

    一:log_format - 概述 - log_format 用于管理 Nginx 的详细信息,日志管理等信息,很多都是基于这个来实现. - 可配置参数 $remote_addr 客户端地址 $rem ...

  6. MongoDB的固态list

    在MongoDB中当前数据库所指定的list可以是一个固态的list,所谓固态就是大小确定,如创建一个固态的集合:db.createCollection("固态集合的名字",{ca ...

  7. oracle数据迁移到mysql

    今天遇到需求要把oracle的部分数据搬到mysql,用java代码抓数据,然后拼接成sql语句,然后用navicat执行sql脚本的方法,导入数据库. import oracle.jdbc.driv ...

  8. Linux新建用户 useradd&groupadd

    建立一个新组,并设置组ID加入系统:#groupadd -g 1000 sparkgroup #useradd -u 2000 -g sparkgroup sparkuser #mkdir -p /a ...

  9. HandlerThread分析

    Handy class for starting a new thread that has a looper. The looper can then be used to create handl ...

  10. csv参数化,数据驱动

    首先我们要有一个接口测试用例存放的地方,我们这里用EXCEL模板管理,里面包含用例编号.入参.优先级.请求方式.url等等. 1:新建一个txt文件,命名为sjqd,后缀名改为csv,右键excel格 ...