SNMP

发布时间 2023-07-07 10:27:39作者: 吟风者的旅途

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的指令。

image-20230703173210997

这里着重介绍一下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。

image-20230703174401145

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基本操作

image-20230703175357230

SNMP查询

SNMP查询是指NMS主动向SNMP Agent发送查询请求,如图所示。SNMP Agent接收到查询请求后,通过MIB表完成相应指令,并将结果反馈给NMS。

image-20230703175420666

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在安全方面做了极大的提升

image-20230703180414565

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进行确认

image-20230704101544487

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();
              }
       }
}

总结:

  1. 指明传输方式,初始化SNMP;
  2. 指明远程设备信息Target,如地址、端口、超时时间,SNMP协议版本;
  3. 编辑报文PDU,OID,value,操作类型,并发送;
  4. 接受返回信息

5.工具推荐

5.1 SNMP报文发送工具iReasoning MIB Browser

iReasoning MIB Browser可以作为NMS(即SNMP管理端),这个软件免费版只有SNMPv1与SNMPv2。

image-20230707095848813

如果你想测试一下:

SNMP分为管理端与远程设备,但windows本身默认是没有SNMP协议的,所以:

  1. 在远程设备安装SNMP协议,并设置接受的公共组(v1,v2)
  2. 配置iReasoning MIB Browser,填入远程设备的 ip port 操作类型 oid
  3. 检查无误后,点击Go

5.2网络抓包分析工具 wireshark

这个软件很简单,点击你想抓包的网络,就会开始

注意:如果你是自己给自己发送报文,那么他是抓不到的,因为他默认使用的WinPcap(安装wireshark时,如果你没有选择其它接口,就会下载WinPcap),只能看到经过网卡的流量,看不到访问localhost的流量,所以你需要卸载WinPcap与wireshark,重新安装,安装时选择Npcap接口,就会出现Adapter for loopback traffic capture选项了

利用SNMP4J编写代码自己给自己发一个

image-20230707100857044

查看wireshark捕获的报文

image-20230707101426485