我正在尝试使用SNMP4J在Java中创建SNMP TRAP /通知代理。 陷阱/通知旨在发送给远程侦听器。
我想通过身份验证添加对V2和V3陷阱的支持。
我当前的设置:
运行通知程序的Dev设备。 (192.168.1.61)
运行snmptrapd的debian 9(Stretch)(192.168.1.92)上的VM
我的问题很快描述了:
我已尝试使用以下命令进行设置,确认其有效:
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有一个静态的。
我在做什么错了?
答案 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
守护程序中。