SNMP
1.什么是SNMP
简单网络管理协议SNMP(Simple Network Management Protocol)用于网络设备的管理。网络设备种类多种多样,不同设备厂商提供的管理接口(如命令行接口)各不相同,这使得网络管理变得愈发复杂。为解决这一问题,SNMP应运而生。SNMP作为广泛应用于TCP/IP网络的网络管理标准协议,提供了统一的接口,从而实现了不同种类和厂商的网络设备之间的统一管理。
SNMP协议分为三个版本:SNMPv1、SNMPv2c和SNMPv3。
- SNMPv1是SNMP协议的最初版本,提供最小限度的网络管理功能。SNMPv1基于团体名认证,安全性较差,且返回报文的错误码也较少。适用于规模较小,设备较小,安全性要求不高或者本身就比较安全的网络,如校园网,小型企业网。
- SNMPv2c也采用团体名认证。在SNMPv1版本的基础上引入了GetBulk和Inform操作,支持更多的标准错误码信息,支持更多的数据类型(Counter64、Counter32)。但还是没有足够的安全机制。
- SNMPv3主要在安全性方面进行了增强,提供了基于USM(User Security Module)的认证加密和基于VACM(View-based Access Control Model)的访问控制。SNMPv3版本支持的操作和SNMPv2c版本支持的操作一样。
2.SNMP管理模型
SNMP系统由网络管理系统NMS(Network Management System)、SNMP Agent、被管对象Management object和管理信息库MIB(Management Information Base)四部分组成。NMS作为整个网络的网管中心,对设备进行管理。
每个被管理设备中都包含驻留在设备上的SNMP Agent进程、MIB和多个被管对象。NMS通过与运行在被管理设备上的SNMP Agent交互,由SNMP Agent通过对设备端的MIB进行操作,完成NMS的指令。
这里着重介绍一下MIB:
MIB是一个数据库,指明了被管理设备所维护的变量。MIB在数据库中定义了被管理设备的一系列属性:对象的名称、对象的状态、对象的访问权限和对象的数据类型等。MIB也可以看作是NMS和SNMP Agent之间的一个接口,通过这个接口,NMS对被管理设备所维护的变量进行查询/设置操作。
MIB是以树状结构进行存储的,如图1-2所示。树的节点表示被管理对象,它可以用从根开始的一条路径唯一地识别,这条路径就称为OID,如system的OID为1.3.6.1.2.1.1,interfaces的OID为1.3.6.1.2.1.2。
OID | 节点名称 | .... |
---|---|---|
1.3.6.1.2.1.1 | system | ... |
1.3.6.1.2.1.2 | interfaces | ... |
... | ... | ... |
用户可以配置MIB视图来限制NMS能够访问的MIB对象。MIB视图是MIB的子集合,用户可以将MIB视图内的对象配置为exclude或include。exclude表示当前视图不包含该MIB子树的所有节点;include表示当前视图包含该MIB子树的所有节点。
3.SNMP基本操作
SNMP查询
SNMP查询是指NMS主动向SNMP Agent发送查询请求,如图所示。SNMP Agent接收到查询请求后,通过MIB表完成相应指令,并将结果反馈给NMS。
SNMP查询操作有三种:Get、GetNext和GetBulk。SNMPv1版本不支持GetBulk操作。
- Get操作:NMS使用该操作从SNMP Agent中获取一个或多个参数值。
- GetNext操作:NMS使用该操作从SNMP Agent中获取一个或多个参数的下一个参数值。
- GetBulk操作:基于GetNext实现,相当于连续执行多次GetNext操作。在NMS上可以设置被管理设备在一次GetBulk报文交互时,执行GetNext操作的次数。
SNMPv1与SNMPv2在执行get与set操作时面临安全问题,SNMPv3在安全方面做了极大的提升
SNMP查询一般是NMS主要向代理进程Agent发送get请求报文,代理进程Agent收到报文后进行认证,认证成功后根据报文内指定的变量查询。
SNMP设置
NMS设置(修改)被管理设备MIB节点sysName的值为XXX,他的原理基本与get相同,只是他们的的请求报文中要写明操作类型与参数绑定表
SNMP Traps
SNMP Traps是指SNMP Agent主动将设备产生的告警或事件上报给NMS,以便网络管理员及时了解设备当前运行的状态。
SNMP Agent上报SNMP Traps有两种方式:Trap和Inform。SNMPv1版本不支持Inform。Trap和Inform的区别在于,SNMP Agent通过Inform向NMS发送告警或事件后,NMS需要回复InformResponse进行确认
4.SNMP4J
SNMP4J是一个用Java来实现SNMP(简单网络管理协议)协议的开源项目.它支持以命令行的形式进行管理与响应。
总的来看,SNMP4J有以下核心,SNMP(管理端,负责接收与发送报文),target(接收端,可以接受报文),PDU(报文),
因此SNMP4J变成主要围绕这三大部分(以下代码适用于SNMPv1,SNMPv2,SNMPv3使用用户而不是公共组,并引入了更强大的安全机制,因此SNMPv3使用的类与v1,v2有很大不同,比如:PDU类适用于SNMPv1和SNMPv2c。ScopedPDU类继承于PDU类,适用于SNMPv3;Target接口适用于SNMPv1和SNMPv2c。CommunityTarget类实现了Target接口,用于SNMPv1和SNMPv2c这两个版本,UserTarget类实现了Target接口,适用于SNMPv3;在实例化SNMP时,还需要额外安全机制和用户)
`
public class SnmpUtil {
//管理端
private Snmp snmp = null;
//接收端的地址
private Address targetAddress = null;
public void initComm() throws IOException {
// 设置Agent方的IP和端口
targetAddress = GenericAddress.parse("udp:127.0.0.1/161");
/**
明确SNMP在传输层所使用的协议为UDP
值得一提的是S按照RFC的规定,SNMP是只使用UDP作为传输层协议的。
而SNMP4J支持管理端和代理端使用UDP或者TCP进行传输。该接口有两个子接口
*/
TransportMapping transport = new DefaultUdpTransportMapping();
//实例化SNMP对象
snmp = new Snmp(transport);
//开始监听消息
transport.listen();
}
public ResponseEvent sendPDU(PDU pdu) throws IOException {
// 设置 target,构造我们的发送目标 如公共组 地址 失败重试次数 超时时间 SNMP协议版本等等
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
// 通信不成功时的重试次数
target.setRetries(2);
// 超时时间
target.setTimeout(1500);
target.setVersion(SnmpConstants.version1);
// 通过snmp向Agent发送PDU(报文),并返回Response
return snmp.send(pdu, target);
}
public void setPDU() throws IOException {
// set PDU
//构建报文内容 oid value 操作类型
PDU pdu = new PDU();
pdu.add(new VariableBinding(
new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 5, 0 }),
new OctetString("Test")));//你想修改的内容
pdu.setType(PDU.SET);
sendPDU(pdu);
}
public void getPDU() throws IOException {
// get PDU
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(new int[] { 1, 3, 6, 1, 2, 1, 1, 5, 0 })));
pdu.setType(PDU.GET);
readResponse(sendPDU(pdu));
}
/**
SNMP4J支持两种消息发送模式:同步发送模式和异步发送模式。
同步发送模式也称阻塞模式。当管理端发送出一条消息之后,线程会被阻塞,直到收到对方的回应或者时间超时。
同步发送模式编程较为简单,但是不适用于发送广播消息。使用同步模式,直接调用send方法,方法会返回一个ResponseEvent对象。
异步发送模式也称非阻塞模式。当程序发送一条消息之后,线程将会继续执行,当收到消息的回应的时候,
程序会对消息作出相应的处理。要实现异步发送模式,需要实例化一个实现了ResponseListener接口的类的对象。
ResponseListener接口中有一个名为onResponse的函数。这是一个回调函数,当程序收到响应的时候,会自动调用该函数。
*/
public void readResponse(ResponseEvent respEvnt) {
// 解析Response
if (respEvnt != null && respEvnt.getResponse() != null) {
Vector<VariableBinding> recVBs = respEvnt.getResponse()
.getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
public static void main(String[] args) {
try {
SnmpUtil util = new SnmpUtil();
util.initComm();
util.setPDU();
util.getPDU();
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结:
- 指明传输方式,初始化SNMP;
- 指明远程设备信息Target,如地址、端口、超时时间,SNMP协议版本;
- 编辑报文PDU,OID,value,操作类型,并发送;
- 接受返回信息
5.工具推荐
5.1 SNMP报文发送工具iReasoning MIB Browser
iReasoning MIB Browser可以作为NMS(即SNMP管理端),这个软件免费版只有SNMPv1与SNMPv2。
如果你想测试一下:
SNMP分为管理端与远程设备,但windows本身默认是没有SNMP协议的,所以:
- 在远程设备安装SNMP协议,并设置接受的公共组(v1,v2)
- 配置iReasoning MIB Browser,填入远程设备的 ip port 操作类型 oid
- 检查无误后,点击Go
5.2网络抓包分析工具 wireshark
这个软件很简单,点击你想抓包的网络,就会开始
注意:如果你是自己给自己发送报文,那么他是抓不到的,因为他默认使用的WinPcap(安装wireshark时,如果你没有选择其它接口,就会下载WinPcap),只能看到经过网卡的流量,看不到访问localhost的流量,所以你需要卸载WinPcap与wireshark,重新安装,安装时选择Npcap接口,就会出现Adapter for loopback traffic capture选项了
利用SNMP4J编写代码自己给自己发一个
查看wireshark捕获的报文