带有AuthPriv的SNMP4J V3陷阱未处理

时间:2018-10-29 13:52:12

标签: java snmp net-snmp snmp4j snmp-trap

我正在尝试使用SNMP4J在Java中创建SNMP TRAP /通知代理。 陷阱/通知旨在发送给远程侦听器。

我想通过身份验证添加对V2和V3陷阱的支持。

我当前的设置:

  • 运行通知程序的Dev设备。 (192.168.1.61)

  • 运行snmptrapd的debian 9(Stretch)(192.168.1.92)上的VM

我的问题很快描述了:

  • V2消息有效。
  • V3消息已收到,但从Java发送时未处理。

我已尝试使用以下命令进行设置,确认其有效:

VM:

sudo snmptrapd -f -Lo -c /usr/share/snmpdtrapd.conf

开发:

sudo snmptrap -e 0x80001370017f000101 -v 3 -a SHA -A 02m-auth -x DES -X o2m-priv -l authPriv o2m-user 192.168.1.92:162 1 .1.3.6.1.2.1.1.8

在VM上,它生成以下日志消息:

2018-10-29 14:42:21 <UNKNOWN> [UDP: [192.168.1.61]:44309-> 
[192.168.1.92]:162]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1) 0:00:00.01  
SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-MIB::sysORLastChange

现在我运行了以下代码,并确认它已到达VM(运行启用了-d的snmptrapd命令以查看snmp数据包实际到达)

        TransportMapping transportMapping = new DefaultUdpTransportMapping();
        Snmp snmp = new Snmp(transportMapping);
        OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());

        USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);

        SecurityModels.getInstance().addSecurityModel(usm);


        OctetString securityName = new OctetString("o2m-user");

        OID authProtocol = AuthSHA.ID;
        OID privProtocol = PrivDES.ID;

        OctetString authPassphrase = new OctetString("o2m-auth");
        OctetString privPassphrase = new OctetString("o2m-priv");

        snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));

        UserTarget target = new UserTarget();
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(securityName);

        target.setAddress(new UdpAddress("192.168.1.92" + "/" + 162));
        target.setVersion(SnmpConstants.version3);

        snmp.listen();

        ScopedPDU pdu = new ScopedPDU();
        pdu.setType(PDU.TRAP);
        pdu.setContextEngineID(localEngineId);
        pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(1)));
        pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(".1.3.6.1.2.1.1.8")));


        System.out.println("Sending V3 trap");
        snmp.send(pdu, target);
        snmp.close();

上面的代码在snmptrapd服务器上不会生成任何日志消息。

我还尝试用实际的引擎ID替换MPv3.createLocalEngineId(),但这似乎也无济于事。

我已经对两个请求(来自JAVA和来自snmp-trap的请求)进行了窃听,而我注意到的唯一区别是它们都具有不同的AuthorativeEngineID。

Java生成了一个,因为每个请求都不同,snmp-trap有一个静态的。

我在做什么错了?

2 个答案:

答案 0 :(得分:0)

您可以附加有关到达的snmp数据包的详细日志吗?

我认为已经在192.168.1.92上创建了具有AuthorativeEngineID 0x80001370017f000101的用户“ o2m-user”,因此我尝试使用它发送陷阱消息。

所以,我更新了

snmp.getUSM().addUser(securityName, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));

OctetString  authorativeEngineID = createOctetString("0x80001370017f000101");  +
snmp.getUSM().addUser(securityName, authorativeEngineID, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));  -+

private OctetString createOctetString(String s) {
    if (s == null) {
        return null;
    }
    OctetString octetString = null;
    if (s.startsWith("0x")) {
        octetString = createStr16(s.substring(2));
    }
    else {
        octetString = new OctetString(s);
    }
    return octetString;
}

private OctetString createStr16(String str10) {
    String[] strs  = str10.split("");
    byte[] value = new byte[strs.length];
    for (int n = 0; n < strs.length; n++) {
        value[n] = (byte)Integer.parseInt(strs[n], 16);
    }
    return new OctetString(value);
}

此后,当我尝试发送v3陷阱时,出现错误 SNMPv3_USM_UNKNOWN_SECURITY_NAME 。然后,我阅读了SNMP4J的snmp.send(pdu,target)的源代码,发现本地引擎ID应该与所请求的AuthorativeEngineID相同,因此我继续设置本地引擎ID,如下所示,

snmp.setLocalEngine(authorativeEngineID.getValue(), 0, 0);  +
snmp.listen();

然后可以发送陷阱消息而没有任何错误,但是在engineID上仍然无法匹配192.168.1.92,详细日志如下(使用命令 snmptrapd -f -d -Dusm -Lo 查看日志):
注意:我的测试authorativeEngineID为0x8000000001020305,我的测试用户名为mytrapuser2

Received 559 byte packet from UDP: [xxxxxx]:xxxxx->[xxxxxx]:162
0000: 30 82 01 B0  02 01 03 30  11 02 04 6B  E7 AD 69 02    0......0...k..i.
0016: 03 00 FF FF  04 01 00 02  01 03 04 2B  30 29 04 10    ...........+0)..
0032: 08 00 00 00  00 00 00 00  00 01 00 02  00 03 00 05    ................
0048: 02 01 00 02  01 00 04 0B  6D 79 74 72  61 70 75 73    ........mytrapus
0064: 65 72 32 04  00 04 00 30  82 01 69 04  10 08 00 00    er2....0..i.....
...

usm: USM processing begun...
usm: match on user mytrapuser2
usm: no match on engineID (08 00 00 00 00 00 00 00 00 01 00 02 00 03 00 05 )
usm: Unknown User(mytrapuser2)
...

“ 08 00 00 00 00 00 00 00 00 01 00 02 00 03 00 05”是否不等于“ 0x8000000001020305”,所以在engineID上出现了不匹配错误?我现在不确定,我将继续调查。

我的问题:
我不确定是否应将本地引擎ID设置为0x80001370017f000101,如果不能,如何避免SNMPv3_USM_UNKNOWN_SECURITY_NAME问题?

答案 1 :(得分:0)

借助Vicky的问题,我实际上已经确定了问题。

我没有设置正确的ID,却忘记在两个地方设置ID。

我在服务器端的引擎ID实际上是Mpv3.createLocaleEngineId()创建的程序localEngineID的前9个字节。

所以我实际上只是将ID细分为以下字符串:

OctetString localEngineId = new OctetString(MPv3.createLocalEngineID()).substring(0, 9);

并在addUser部分中添加了localEngineId,如下所示:

snmp.getUSM().addUser(securityName, localEngineId, new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase));

对于snmp引擎ID:

snmp.setLocalEngine(localEngineId.getValue(), 0, 0);

此问题解决了我的问题,该消息记录在snmptrapd守护程序中。