SNMP4J使用SNMPv3请求超时问题排查与解决
问题描述
我正在开发一个Java交换机管理程序,目前仅尝试从交换机获取单个OID值。SNMPv2c版本的代码可以正常运行,但使用SNMPv3时始终返回Agent Timeout错误。不过使用相同参数的snmpget命令能正常得到结果,说明环境本身支持SNMPv3。
改用SNMPv2c并替换为CommunityTarget的代码可正常执行,因此怀疑问题出在SNMPv3的用户或目标配置上,但一直没找到解决办法。交换机配置没问题,因为net-snmp的控制台工具可以正常工作。
可用的snmpget命令
snmpget -v3 -l AuthPriv -u snmpuser -a MD5 -A "foo#Bar0815" -x DES -X "foo#Bar0815" 10.1.0.4:161 1.3.111.2.802.1.1.30.1.2.1.1.8.1.1
无法运行的SNMPv3代码
public static void getAdminCycleTimeNumeratorv3() throws IOException { String ipAddress = "10.1.0.4"; String port = "161"; String oidValue = "1.3.111.2.802.1.1.30.1.2.1.1.8.1.1"; int snmpVersion = SnmpConstants.version3; TransportMapping transport = new DefaultUdpTransportMapping(); Snmp snmp = new Snmp(transport); USM usm = new USM( SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0 ); SecurityModels.getInstance().addSecurityModel(usm); transport.listen(); // Set the target UserTarget target = new UserTarget(); target.setAddress(GenericAddress.parse("udp:10.1.0.4/161")); target.setRetries(2); target.setTimeout(2000); target.setVersion(SnmpConstants.version3); target.setSecurityLevel(SecurityLevel.AUTH_PRIV); target.setSecurityName(new OctetString("snmpuser")); // Set the security settings snmp.getUSM().addUser( new OctetString("snmpuser"), new UsmUser( new OctetString("snmpuser"), AuthMD5.ID, new OctetString("foo#Bar0815"), PrivDES.ID, new OctetString("foo#Bar0815") ) ); // Create PDU PDU pdu = new ScopedPDU(); pdu.add(new VariableBinding(new OID(oidValue))); pdu.setType(PDU.GET); System.out.println("Sending SNMP Request"); ResponseEvent response = snmp.get(pdu, target); // Process Agent Response if (response != null) { PDU responsePDU = response.getResponse(); if (responsePDU != null) { int errorStatus = responsePDU.getErrorStatus(); int errorIndex = responsePDU.getErrorIndex(); String errorStatusText = responsePDU.getErrorStatusText(); if (errorStatus == PDU.noError) { System.out.println("Snmp Get Response = " + responsePDU.getVariableBindings()); } else { System.out.println("Error: Request Failed"); System.out.println("Error Status = " + errorStatus); System.out.println("Error Index = " + errorIndex); System.out.println("Error Status Text = " + errorStatusText); } } else { System.out.println("Error: Response PDU is null"); } } else { System.out.println("Error: Agent Timeout"); } snmp.close(); }
解决方法
问题出在SecurityProtocols实例的初始化上,需要手动添加所需的认证协议,再将该实例传入USM。修改后的关键代码如下:
// 先创建SecurityProtocols实例并添加认证协议 SecurityProtocols securityProtocols = SecurityProtocols.getInstance(); securityProtocols.addAuthenticationProtocol(new AuthSHA()); securityProtocols.addAuthenticationProtocol(new AuthMD5()); // 将配置好的实例传入USM USM usm = new USM( securityProtocols, new OctetString(MPv3.createLocalEngineID()), 0 ); SecurityModels.getInstance().addSecurityModel(usm);
内容的提问来源于stack exchange,提问作者Astor
相关产品推荐
相关产品推荐

