我即将实现客户端/代理设置,以便学习使用
SNMP。我想使用 SNMPv3 和 authPriv
建立安全且加密的通信作为安全级别。
这是我的设置:
代理
代理在 Ubuntu 上运行(在 Docker 镜像内)。为了进行设置,我按照 this tutorial 进行设置。 .
我的/etc/snmp/snmpd.conf
看起来像这样:
agentAddress udp:161
...
createUser authOnlyUser MD5 "test1234"
createUser authPrivUser SHA "test1234" DES
createUser internalUser MD5 "test1234"
...
rouser authOnlyUser
rwuser authPrivUser authPriv
SNMP 正在端口 161
上运行,转发到端口 1025
由 Docker 提供。
客户端
我可以使用以下方式确保我的代理正常工作
-
snmpget
在同一台机器上(Ubuntu,在 Docker 中):
snmpget -v3 -a SHA -A test1234 -X test1234 -l authPriv -u authPrivUser localhost 1.3.6.1.2.1.1.1.0
-
snmpget
从远程计算机 (Debian):
snmpget -v3 -u authPrivUser -X test1234 -A test1234 -l authPriv -x DES -a SHA <HOST-IP>:1025 1.3.6.1.2.1.1.1.0
- 使用 SNMP-Tester .
在所有三种情况下,我都得到给定 OID 的预期值:
Linux 9b98a8808b1a 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64
.
现在我想用 Java 实现一个客户端,使用 latest version 3.2.2 of snmp4j 。这是我已经实现的:
public class SNMPTestClient {
public static void main(String[] args) throws Exception {
// enable logging
ConsoleLogFactory consoleLogFactory = new ConsoleLogFactory();
consoleLogFactory.getRootLogger().setLogLevel(LogLevel.DEBUG);
LogFactory.setLogFactory(consoleLogFactory);
TransportMapping<? extends Address> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
// create and add user security model
OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
SecurityModels.getInstance().addSecurityModel(usm);
// user credentials
OctetString securityName = new OctetString("authPrivUser");
OctetString authPassphrase = new OctetString("test1234");
OctetString privPassphrase = new OctetString("test1234");
OID authProtocol = AuthSHA.ID;
OID privProtocol = PrivDES.ID;
UsmUser usmUser = new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase);
snmp.getUSM().addUser(securityName, usmUser);
// create target
UserTarget target = new UserTarget();
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(securityName);
target.setAddress(GenericAddress.parse("udp:127.0.0.1/1025"));
target.setVersion(SnmpConstants.version3);
target.setRetries(3);
target.setTimeout(10000);
transport.listen();
ScopedPDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1.0")));
pdu.setType(PDU.GET);
ResponseEvent event = snmp.send(pdu, target);
if (event != null) {
System.out.println(event.getUserObject());
System.out.println(event.getError());
System.out.println(event.getPeerAddress());
PDU responsePDU = event.getResponse();
System.out.println(responsePDU.getErrorStatus());
System.out.println(responsePDU.getErrorIndex());
if (responsePDU.getErrorStatus() == PDU.noError) {
for (int k = 0; k < responsePDU.size(); k++) {
VariableBinding vb = responsePDU.get(k);
if (vb != null) {
System.out.println(vb.getOid() + "-" + vb.getVariable().toString());
}
}
} else {
System.out.println("SNMP Error:" + responsePDU.getErrorStatusText());
}
} else {
System.out.println("SNMP send unsuccessful.");
}
}
}
正如您所看到的,我使用的是与上面提到的相同的凭据和协议(protocol)。但是当我运行它时,我收到以下异常:
org.snmp4j.MessageException: Message processing model 3 returned error: Unsupported security level
我在这里做错了什么?作为用户authPrivUser
配置为使用authPriv
代理端的安全级别,我还将级别设置为 AUTH_PRIV
在客户端内并传递正确的凭据,我不知道为什么会抛出此异常。
预先感谢您的支持和提示!
编辑
我发现我上面发布的代码确实可以使用 SNMP4J v2.7.0 工作。任何版本 >=3.0.0 都会引发错误 Unsupported security level
。不幸的是,使用 2018 年 11 月的旧版本无法解决问题...
最佳答案
在 SNMP4J 3.x 中,安全协议(protocol) AuthSHA
(和 AuthMD5
)不再默认添加到静态 SecurityProtocols
实例中,因为它们现在被认为是不安全的。
您可以通过调用再次添加它:
SecurityProtocols.addAuthenticationProtocol(new AuthSHA());
关于java - SNMP4J 客户端给出 "Unsupported security level",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57273315/