SNMP(简单网络管理协议)详解
Posted Jeremy_Lee123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SNMP(简单网络管理协议)详解相关的知识,希望对你有一定的参考价值。
一、简介
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-request
- Get-next-request
- Set-request
- Get-response
- Trap
前三项都是属于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<DefaultMOTable> moTables = new ArrayList<DefaultMOTable>();
private String community;
protected MyAgent(File bootCounterFile, File configFile, List<DefaultMOTable> 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<VariableBinding> 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<UdpAddress> 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<TrapData> 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<VariableBinding> recVBs = (Vector<VariableBinding>) 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<UdpAddress> 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<VariableBinding> recVBs = (Vector<VariableBinding>) 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是什么协议
snmp简单网络管理协议
Snmp是什么
简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议。在1988年被制定,并被Internet体系结构委员会(IAB)采纳作为一个短期的网络管理解决方案;由于SNMP的简单性,在Internet时代得到了蓬勃的发展,1992年发布了SNMPv2版本,以增强SNMPv1的安全性和功能。现在,已经有了SNMPv3版本。
snmp干什么
简单网络管理协议(SNMP:Simple Network Management Protocol)是由互联网工程任务组(IETF:Internet Engineering Task Force )定义的一套网络管理协议。该协议基于简单网关监视协议(SGMP:Simple Gateway Monitor Protocol)。利用SNMP,一个管理工作站可以远程管理所有支持这种协议的网络设备,包括监视网络状态、修改网络设备配置、接收网络事件警告等。 虽然SNMP开始是面向基于IP的网络管理,但作为一个工业标准也被成功用于电话网络管理
介绍一下snmp
在使用snmp的工具前,我们要先了解一下snmp的结构。
一套完整的SNMP系统主要包括管理信息库(MIB)、管理信息结构(SMI)及SNMP报文协议。
在结构上又分为NMS和Agent
https://blog.csdn.net/shanzhizi/article/details/11606767
https://www.ibm.com/developerworks/cn/linux/l-cn-snmp/index.html
NMS network-manager-system 网络管理系统
基于TCP/IP的网络管理包含两个部分:网络管理站(也叫管理进程,manager)和被管的网络单元(也叫被管设备)。被管的设备种类繁多,例如:路由器、X终端、终端服务器和打印机等。这些被管设备的共同点就是都运行TCP/IP协议。被管设备端和关联相关的软件叫做代理程序(agent)或代理进程。管理站一般都是带有色彩监视器的工作站,可以显示所有被管理设备的状态(例如连接是否掉线、各种连接上的流量状况等)。
MIB manager-infomation-base 管理信息库包含所有代理进程的所有可被查询和修改的参数
SMI Structure of Management Information 关于MIB的一套共用的结构和表示符号。叫做管理信息结构
SNMP Simple Network Management Protocol 简单网络管理协议 管理进程和代理进程之间的通信协议
协议
管理进程和代理进程之间的通信可以有两种方式,一种是管理进程向代理进程发出请求,询问(get)一个具体的参数值(例如询问你产生了多少个不可达的ICMP端口) 修改(set) 按要求改变代理进程的参数值 另外由代理端向管理端主动汇报某些内容(trap)(例如:一个接口掉线了)
请求方法
1)get_request (询问) 从代理进程处提取一个或多个参数值
2)get_next_request (下一次询问) 从代理进程处提取一个或多个参数的下一个参数值
3)set_request (修改) 设置代理进程一个或多个参数值
4)get_response (获取请求响应)
5)trap 代理进程主动发出的报文,通知管理进程有某些事发生。
这些操作的前4钟操作是简单的请求应答方式,而且在SNMP钟往往使用UDP协议,所以可能发生管理进程和代理进程之间数据包丢失的情况。因此一定要有超时和重传机制。
管理进程发出的前面三种操作采用UDP的161端口,而trp走的是162端口
在Linux下使用snmp
安装
yum install net-snmp net-snmp-utils -y
# 查看是否安装完成
snmpd -v
snmpwalk -V
其中net-snmp是snmp软件
net-snmp-utils 是snmp的工具
使用
开启snmp服务,snmpd是一个linux的服务,但是我们是通过使用snmpwalk来操作snmp这个服务的
systemctl start snmpd
常用的snmpwalk数
-h # 显示帮助
-v # 指定snmp的版本,1或者2或者3
-c # 指定连接设备snmp密码。
-V # 显示当前snmpwalk命令行版本
-r # 指定重试次数,默认为0次
-t # 指定每次请求的等待超时
-l # 指定安全级别:noAuthNoPriv|authNoPriv|authPriv
-a # 验证协议:MD5|SHA。只有-l指定为authNoPriv或authPriv时才需要
–A # 验证字符串。只有-l指定为authNoPriv或authPriv时才需要
–x # 加密协议:DES。只有-l指定为authPriv时才需要
–X # 加密字符串。只有-l指定为authPriv时才需要。
常用方法
snmpwalk -v 2c -c public 10.1.1.1 .1.3.6.1.2.1.25.1 # 得到取得windows端的系统进程用户数等
# 其中 -v指定版本 -c 指定密码 10.1.1.1 指定地址(localhost表示本地) .1.3.6.1.2.1.25.1表示oid 不同的oid表示了不同的操作
常用oid
http://www.ttlsa.com/monitor/snmp-oid/
以上是关于SNMP(简单网络管理协议)详解的主要内容,如果未能解决你的问题,请参考以下文章