带有 AuthPriv 的 SNMP4J V3 Trap 未处理
SNMP4J V3 Trap with AuthPriv not processing
我正在尝试使用 SNMP4J 在 Java 中创建一个 SNMP TRAP/Notify 代理。
traps/notify 用于发送给远程侦听器。
我想通过身份验证添加对 V2 和 V3 陷阱的支持。
我目前的设置:
Dev machine 运行 通知程序。 (192.168.1.61)
VM on debian 9(Stretch) (192.168.1.92) 运行 snmptrapd
我的问题简要描述:
- V2 消息有效。
- 从 Java.
发送时收到但未处理的 V3 消息
我已经使用以下命令尝试了我的设置,确认它有效:
虚拟机:
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)进行了 Wireshark,我注意到的唯一区别是它们都有不同的 AuthorativeEngineID。
Java 有一个生成的,因为它在每个请求上都不同,snmp-trap 有一个静态的。
我做错了什么?
能否附上到达的snmp数据包的详细日志?
我认为用户 "o2m-user" 是在 192.168.1.92 上使用 AuthorativeEngineID 0x80001370017f000101 创建的,所以我尝试用它发送陷阱消息。
所以,我更新了
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();
然后trap消息可以正常发送,但是192.168.1.92在engineID上还是匹配不上,详细日志如下(使用命令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”,所以出现了引擎ID不匹配的错误?我现在不确定,我会继续研究。
我的问题:
我不确定是否应该将本地引擎ID设置为0x80001370017f000101,如果不是,如何避免问题SNMPv3_USM_UNKNOWN_SECURITY_NAME?
在 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
守护进程中。
我正在尝试使用 SNMP4J 在 Java 中创建一个 SNMP TRAP/Notify 代理。 traps/notify 用于发送给远程侦听器。
我想通过身份验证添加对 V2 和 V3 陷阱的支持。
我目前的设置:
Dev machine 运行 通知程序。 (192.168.1.61)
VM on debian 9(Stretch) (192.168.1.92) 运行 snmptrapd
我的问题简要描述:
- V2 消息有效。
- 从 Java. 发送时收到但未处理的 V3 消息
我已经使用以下命令尝试了我的设置,确认它有效:
虚拟机:
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)进行了 Wireshark,我注意到的唯一区别是它们都有不同的 AuthorativeEngineID。
Java 有一个生成的,因为它在每个请求上都不同,snmp-trap 有一个静态的。
我做错了什么?
能否附上到达的snmp数据包的详细日志?
我认为用户 "o2m-user" 是在 192.168.1.92 上使用 AuthorativeEngineID 0x80001370017f000101 创建的,所以我尝试用它发送陷阱消息。
所以,我更新了
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();
然后trap消息可以正常发送,但是192.168.1.92在engineID上还是匹配不上,详细日志如下(使用命令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”,所以出现了引擎ID不匹配的错误?我现在不确定,我会继续研究。
我的问题:
我不确定是否应该将本地引擎ID设置为0x80001370017f000101,如果不是,如何避免问题SNMPv3_USM_UNKNOWN_SECURITY_NAME?
在 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
守护进程中。