SNMP(简单网络管理协议)详解

您所在的位置:网站首页 网络管理主要由管理站被管设备以及什么构成 SNMP(简单网络管理协议)详解

SNMP(简单网络管理协议)详解

2023-08-21 04:25| 来源: 网络整理| 查看: 265

一、简介

SNMP(简单网络管理协议): 专门用于在 IP 网络管理网络节点(服务器、工作站、路由器、交换机及HUBS等)的一种标准协议,它是一种应用层协议。 SNMP 使网络管理员能够管理网络效能,发现并解决网络问题以及规划网络增长。通过 SNMP 接收随机消息(及事件报告)网络管理系统获知网络出现问题。

SNMP的前身是简单网关监控协议(SGMP),用来对通信线路进行管理。随后,人们对SGMP进行了很大的修改,特别是加入了符合Internet定义的SMI和MIB,改进后的协议就是著名的SNMP。

管理信息结构SMI(Structure ofManagement Information)定义了SNMP框架所用信息的组织和标识,为MIB定义管理对象及使用管理对象提供模板。管理信息库MIB(,Management Information Base)定义了可以通过SNMP进行访问的管理对象的集合,一种树状数据库,MIB管理的对象,就是树的端节点。对象识别符OID(Object Identifier)定义了端节点的唯一位置和唯一名字,其命名规则就是父节点的名字作为子节点名字的前缀。 

二、架构原理

 一个SNMP管理的网络由下列三个关键组件组成:

网络管理系统(NMS,Network-management systems)NMS运行应用程序,监控被管理的设备。网络管理系统提供网络管理需要的大量运算和记忆资源。被管理的设备(managed device)被管理的设备是一个网络节点,它包含一个SNMP agent。被管理的设备通过管理信息库(MIB)收集并存储管理信息,并且让网络管理系统通过agent读取这些信息。代理者(agent)agent是一种存在于被管理的设备中的网络管理软件模块。agent控制本地机器的管理信息,以和SNMP兼容的格式传送这项信息。

主代理是一个在可运行的SNMP网络组件上运作的软件,可回应从管理站发出的SNMP要求。它的角色类似C/S术语中的服务器。主代理依赖子代理提供有关特定功能的管理信息。

子代理是一个在可运行的SNMP网络组件上运作的软件,运行在特定子系统的特定管理信息库(MIB,Management Information Base)中定义的信息和管理功能。子代理的一些能力有:搜集主代理的信息、配置主代理的参数、回应管理者的要求、产生警告或陷阱trap

主代理和子代理的角色可以合并,在这种情况下我们可以简单的称之为代理(agent)。

​SNMP定义了五种Manager与Agent之间的通讯形式。

Get-requestGet-next-requestSet-requestGet-responseTrap

前三项都是属于Manager向Agent发出的讯息,后两项则属于Agent向Manager发出的讯息

Trap:当设备发生了各种事件之后,产生的MIB信息由SNMP代理主动向NMS发送,是不需要NMS请求的,NMS收到之后不需要向SNMP代理发送确认消息,SNMP发出去的Trap是根本不知道NMS是否收到,自己发送完毕之后,这些MIB信息会马上删除,不会驻留内存里面。

informs:informs和Trap恰好相反、设备发生事件后,这些信息并不会主动向NMS通告,除非NMS发送requst来查询,然后才会发出去,但是发出去的informs之后会保留在内存里面,当NMS收到informs之后必须向SNMP代理发送确认消息,如果不发送确认消息,SNMP代理会重复多次发送informs(informs具有可靠性)

通过NMS来更改设备上的配置,查询设备信息,发送的数据包为Get,更改设备的配置为Set

三、现存版本 SNMPV1:该版本基于简单网关监视协议发展而来的,于1988年发布,安全性差,错误状态较少。典型的,SNMP为代理使用UDP端口161,为管理站使用UDP端口162。客户端的认证使用明码传送。SNMPV2:SNMP v2c(基于社区的SNMP第二版)定义于RFC 1901–RFC 1908,SNMP v2u(基于用户的SNMP第二版)定义于RFC 1909–RFC 1910。由于高复杂度,产生了商业化的变种,称为SNMP v2*,而且它的机制最后被SNMP第三版的两个安全性框架之一采用。SNMPV3:Internet工程工作小组(IETF)把在RFC3411-RFC3418(STD0062)中定义的SNMP第三版作为2004年的标准版本,以替代SNMPV1正式成为标准协议,SNMP第三版提供三项重要的服务:认证、隐私和访问控制。 四、技术优点

SNMP是管理进程(NMS)和代理进程(Agent)之间的通信协议。它规定了在网络环境中对设备进行监视和管理的标准化管理框架、通信的公共语言、相应的安全和访问控制机制。网络管理员使用SNMP功能可以查询设备信息、修改设备的参数值、监控设备状态、自动发现网络故障、生成报告等。

SNMP具有以下技术优点:

基于TCP/IP互联网的标准协议,传输层协议一般采用UDP。自动化网络管理。网络管理员可以利用SNMP平台在网络上的节点检索信息、修改信息、发现故障、完成故障诊断、进行容量规划和生成报告。屏蔽不同设备的物理差异,实现对不同厂商产品的自动化管理。SNMP只提供最基本的功能集,使得管理任务与被管设备的物理特性和实际网络类型相对独立,从而实现对不同厂商设备的管理。简单的请求—应答方式和主动通告方式相结合,并有超时和重传机制。报文种类少,报文格式简单,方便解析,易于实现。SNMPv3版本提供了认证和加密安全机制,以及基于用户和视图的访问控制功能,增强了安全性。 五、snmp4j代码示例

先看一下SNMP协议要传输的内容:SNMP的5种协议数据单元_协议分析网

接下来就是用SNMP4J协议的jar包来完成各个功能:http://www.snmp4j.org/html/download.html

SNMP4J把开发包分为了两个,一个SNMP4J.jar主要负责get,trap,set,一个是SNMP4J-Agent.jar主要负责作为一个网元被管理。

5.1、开发一个Agent

 需要用到两个配置文件bc和cfg文件,可以在这里下载:http://download.csdn.net/detail/three_man/7477991

import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.snmp4j.agent.BaseAgent; import org.snmp4j.agent.CommandProcessor; import org.snmp4j.agent.DuplicateRegistrationException; import org.snmp4j.agent.io.ImportModes; import org.snmp4j.agent.mo.DefaultMOTable; import org.snmp4j.agent.mo.MOTableRow; import org.snmp4j.agent.mo.snmp.RowStatus; import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB; import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB; import org.snmp4j.agent.mo.snmp.SnmpTargetMIB; import org.snmp4j.agent.mo.snmp.StorageType; import org.snmp4j.agent.mo.snmp.VacmMIB; import org.snmp4j.agent.security.MutableVACM; import org.snmp4j.mp.MPv3; import org.snmp4j.security.SecurityLevel; import org.snmp4j.security.SecurityModel; import org.snmp4j.security.USM; import org.snmp4j.smi.Integer32; import org.snmp4j.smi.OID; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.Variable; public class MyAgent extends BaseAgent { private List moTables = new ArrayList(); private String community; protected MyAgent(File bootCounterFile, File configFile, List moTables, String community) { super(bootCounterFile, configFile, new CommandProcessor(new OctetString(MPv3.createLocalEngineID()))); this.moTables = moTables; this.community = community; } @Override protected void registerManagedObjects() { try { for (DefaultMOTable table : moTables) { server.register(table, null); } } catch (DuplicateRegistrationException e) { e.printStackTrace(); } } public void startUp(){ try { this.init(); } catch (IOException e) { e.printStackTrace(); } this.loadConfig(ImportModes.REPLACE_CREATE); this.addShutdownHook(); this.getServer().addContext(new OctetString(community)); this.finishInit(); this.run(); this.sendColdStartNotification(); } /** * to set community */ @Override protected void addCommunities(SnmpCommunityMIB communityMIB) { Variable[] com2sec = new Variable[] { new OctetString(community), // community name new OctetString("cpublic"), // security name getAgent().getContextEngineID(), // local engine ID new OctetString(community), // default context name new OctetString(), // transport tag new Integer32(StorageType.nonVolatile), // storage type new Integer32(RowStatus.active) // row status }; MOTableRow row = communityMIB.getSnmpCommunityEntry().createRow( new OctetString("public2public").toSubIndex(true), com2sec); communityMIB.getSnmpCommunityEntry().addRow(row); } }  主要的代码是需要继承BaseAgent需要设置community需要注册Table,这个注册中的内容将是供给get和walk的内容。可以从MIB直接构建Agent,可能需要的包为:mibble-mibs是能够独MIB结构。这个也提供个下载地址吧: http://download.csdn.net/detail/three_man/7478061 5.2、Trap Receiver import java.io.IOException; import java.util.logging.Logger; import org.snmp4j.MessageDispatcherImpl; import org.snmp4j.Snmp; import org.snmp4j.TransportMapping; import org.snmp4j.mp.MPv2c; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.UdpAddress; import org.snmp4j.transport.DefaultUdpTransportMapping; import org.snmp4j.util.MultiThreadedMessageDispatcher; import org.snmp4j.util.ThreadPool; import com.prince.snmp.tool.Command; import com.prince.snmp.tool.util.Configure; import com.prince.snmp.tool.util.Const; /** * 构建一个多线程的Trap Receiver * @author wangzijian * */ public class SnmpReceiver implements Command{ private final Logger log = Logger.getLogger(SnmpReceiver.class.getName()); @Override public void startUp() throws IOException { log.info("Snmp Trap Receiver Start"); log.info("listened on " + Configure.getInstance().getUdpTrapIpPort()); ThreadPool pool = ThreadPool.create(Const.THREAD_POOL_NAME, Const.AGENT_THREAD_NUM); MultiThreadedMessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(pool, new MessageDispatcherImpl()); Address listenAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort()); TransportMapping transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress); // 构建SNMP,并且使其开始监听 Snmp snmp = new Snmp(dispatcher, transport); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c()); snmp.listen(); snmp.addCommandResponder(new CommandResponderImpl()); } } package com.prince.snmp.tool.receiver; import java.util.List; import java.util.logging.Logger; import org.snmp4j.CommandResponder; import org.snmp4j.CommandResponderEvent; import org.snmp4j.PDU; import org.snmp4j.smi.OID; import org.snmp4j.smi.VariableBinding; public class CommandResponderImpl implements CommandResponder { private final Logger log = Logger.getLogger(CommandResponderImpl.class.getName()); @Override public void processPdu(CommandResponderEvent event) { PDU pdu = event.getPDU(); if(PDU.TRAP == pdu.getType()){ operate(pdu); }else{ log.info("pdu method is:" + pdu.getType() + " not a trap"); } } private void operate(PDU pdu) { List bindings = pdu.getBindingList(new OID(".1")); for (VariableBinding binding : bindings) { System.out.println(binding.getOid() + "====" + binding.getVariable().toString()); } } }  需要一个多线程的服务器MultiThreadedMessageDispatcher还需要一个处理类 CommandResponderImpl  snmp.addCommandResponder在处理类中能够得到PDU,这个类不只可以作为Receiver还能够开发为Agent,但是需要自己来写很多逻辑,还有可能用到文件或者内存数据库 5.3、send trap package com.prince.snmp.tool.trap; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Vector; import org.snmp4j.CommunityTarget; import org.snmp4j.PDU; import org.snmp4j.Snmp; import org.snmp4j.TransportMapping; import org.snmp4j.event.ResponseEvent; import org.snmp4j.smi.Address; import org.snmp4j.smi.GenericAddress; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.UdpAddress; import org.snmp4j.smi.VariableBinding; import org.snmp4j.transport.DefaultUdpTransportMapping; import com.prince.snmp.tool.Command; import com.prince.snmp.tool.trap.dataGenerator.ITrapGenerator; import com.prince.snmp.tool.util.Configure; public class TrapSender implements Command{ private Snmp snmp; private Address targetAddress; private ITrapGenerator generator; public TrapSender(ITrapGenerator generator) { this.generator = generator; targetAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort()); TransportMapping transport = null; try { transport = new DefaultUdpTransportMapping(); snmp = new Snmp(transport); transport.listen(); } catch (IOException e) { e.printStackTrace(); } } public void sendTrap(){ CommunityTarget target = new CommunityTarget(); target.setAddress(targetAddress); target.setRetries(Configure.getInstance().getRetries()); target.setTimeout(Configure.getInstance().getTimeOut()); target.setCommunity(new OctetString(Configure.getInstance().getCommunity())); target.setVersion(Configure.getInstance().getSnmpVersion()); List datas = generator.generateTrapData(); try { for (TrapData trapData : datas) { sendPdu(trapData, target); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void sendPdu(TrapData trapData, CommunityTarget target) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException { PDU pdu = MoToPdu.moToPdu(trapData); ResponseEvent respEvnt = snmp.send(pdu, target); // 解析Response if (respEvnt != null && respEvnt.getResponse() != null) { Vector recVBs = (Vector) respEvnt.getResponse().getVariableBindings(); for (int i = 0; i < recVBs.size(); i++) { VariableBinding recVB = recVBs.elementAt(i); System.out.println(recVB.getOid() + " : " + recVB.getVariable()); } } } }   trap主要注意必须设置两个VariableBingding

                pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(trap.getSysUpTime())));

                pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(trap.getTrapOid())))

5.4、get private static void simpleGet() throws IOException { TransportMapping transport = new DefaultUdpTransportMapping(); Snmp snmp = new Snmp(transport); transport.listen(); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString("CONV")); Address targetAddress = GenericAddress.parse("udp:10.141.43.237/161"); target.setAddress(targetAddress); target.setRetries(3); target.setTimeout(3000); target.setVersion(SnmpConstants.version2c); PDU pdu = new PDU(); pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.7569.1.2.1.23.3.1"))); pdu.setType(PDU.GETBULK); pdu.setMaxRepetitions(20); pdu.setNonRepeaters(0); ResponseEvent respEvnt = snmp.send(pdu, target); if (respEvnt != null && respEvnt.getResponse() != null) { Vector recVBs = (Vector) respEvnt.getResponse().getVariableBindings(); for (int i = 0; i < recVBs.size(); i++) { VariableBinding recVB = recVBs.elementAt(i); System.out.println(recVB.getOid() + " : " + recVB.getVariable()); } } }  get相对于比较简单,资料也比较多。主要是设定pdu.setType(PDU.GETBULK);利用getnext和一些判断可以实现walk.http://blog .sina.com.cn/s/blog_6cb15f8f0100yx4p.html 这个哥们儿写得非常好

具体的代码没有写,因为下一篇会共享一个小的工具,可以以配置文件为基础来构建Receiver,发送Trap,构建Agent等。

六、附录

具体参考:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台

简单网络管理协议SNMP(史上最全)_奇妙之二进制的博客-CSDN博客_snmp是什么协议



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3