【问题标题】:Agent not returning correct OID value when using SNMP4j (org.snmp4j) v3 and user authentication?使用 SNMP4j (org.snmp4j) v3 和用户身份验证时,代理没有返回正确的 OID 值?
【发布时间】:2017-09-07 06:20:34
【问题描述】:

我编写了一个 SNMP 代理并注册了一个托管对象(创建/设置了 MIB OID 的值)。 当我使用 SNMPv2c 检索此值时,该值被正确返回 - 来自 ResponseEvent.getResponse 的 PDU 具有 type=GET 并且变量绑定具有预期数据 - 正确的 OID 等。 当我使用 SNMPv3 和用户身份验证检索此值时,该值未正确返回 - 来自 ResponseEvent.getResponse 的 PDU 具有 type=REPORT 并且变量绑定具有 与请求中的 OID 不同 - 从我目前阅读的内容来看,这表明配置/身份验证错误。 下面是用于客户端和代理的示例代码 (sn-ps) - 请告诉我如何创建代理和客户端 - 我哪里出错了?

// TestSNMPAgent:
public class TestSNMPAgent {

    private OID sysDescr = new OID("1.3.6.1.2.1.1.1.0");
    ...
    public static void main(String[] args) throws IOException {
        TestSNMPAgent agent = new TestSNMPAgent();
        agent.init("0.0.0.0/4071");

    private void init(String agentIp) throws IOException {

        agent = new SNMPAgent(agentIp);

        agent.start();

        agent.unregisterManagedObject(agent.getSnmpv2MIB());

        agent.registerManagedObject(new MOScalar(oid,
            MOAccessImpl.ACCESS_READ_WRITE,
            getVariable(value),sysDescr,
            "1")));
        ...
    }

}

// SNMPAgent:
public class SNMPAgent extends BaseAgent {
...
    @Override
    protected void addUsmUser(USM arg0) {
       UsmUser user = new UsmUser(new OctetString("SHADES"), 
       AuthSHA.ID, 
       new OctetString("SHADESAuthPassword"), 
       PrivDES.ID, 
       new OctetString("SHADESPrivPassword"));
    }

    @Override
    protected void addViews(VacmMIB vacm) {
        vacm.addGroup(SecurityModel.SECURITY_MODEL_USM, 
                  new OctetString("SHADES"), 
                  new OctetString("v3group"), 
                  StorageType.nonVolatile); 

        vacm.addAccess(new OctetString("v3group"), new OctetString(), 
                   SecurityModel.SECURITY_MODEL_USM, 
                   SecurityLevel.NOAUTH_NOPRIV, VacmMIB.vacmExactMatch, 
                   new OctetString("fullReadView"), 
                   new OctetString("fullWriteView"), 
                   new OctetString("fullNotifyView"), 
                   StorageType.nonVolatile); 
    }

    public void registerManagedObject(ManagedObject mo) {
        try {
            server.register(mo, null);
        } catch (DuplicateRegistrationException ex) {
        throw new RuntimeException(ex);
    }
}

// TestSNMPMgr
public class TestSNMPMgr {

    public static void main(String[] args) throws IOException {

        TestSNMPMgr client = new TestSNMPMgr();
        client.init();
    }

    public void init() {
        SNMPMgr client = new SNMPMgr();
        client.start();
        // Get back Value which is set
        String value = client.getAsString(new OID("1.3.6.1.2.1.1.1.0"));
    }
}

// SNMPMgr
public class SNMPMgr {

    Snmp snmp = null;
    Address address = null;

    public SNMPMgr()
    {
        address = "1.3.6.1.2.1.1.1.0";
    }

    /**
     * Start the Snmp session. If you forget the listen() method you will not
     * get any answers because the communication is asynchronous
     * and the listen() method listens for answers.
     * @throws IOException
    */
    public void start() throws IOException {
       address = GenericAddress.parse("udp:127.0.0.1/4701");
       TransportMapping transport = new DefaultUdpTransportMapping();
       snmp = new Snmp(transport);
       USM usm = new USM(SecurityProtocols.getInstance(),
                         new OctetString(MPv3.createLocalEngineID()), 0);
       SecurityModels.getInstance().addSecurityModel(usm);
       transport.listen();
    }

    public void end() {
        try {
            snmp.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * Method which takes a single OID and returns the response from the agent as a String.
     * @param oid
     * @return
     * @throws IOException
     */
    public String getAsString(OID oid) throws IOException {
        ResponseEvent event = get(new OID[] { oid });
        return event.getResponse().get(0).getVariable().toString();
    }


    public ResponseEvent get(OID oids[]) throws IOException {
       PDU pdu = new ScopedPDU();
       for (OID oid : oids) {
            pdu.add(new VariableBinding(oid));
       }

       pdu.setType(PDU.GET);

       // add user to the USM
       snmp.getUSM().addUser(new OctetString("SHADES"),
               new UsmUser(new OctetString("SHADES"),
               AuthSHA.ID, 
               new OctetString("SHADESAuthPassword"), 
               PrivDES.ID, 
               new OctetString("SHADESPrivPassword")));


       // send the PDU
       ResponseEvent event = snmp.send(pdu, getTarget(), null);

       if(event != null) {
           return event;
       }
       throw new RuntimeException("GET timed out");
    }

    /**
     * This method returns a Target, which contains information about
     * where the data should be fetched and how.
     * @return
     */
    private UserTarget getTarget() {
       UserTarget target = new UserTarget();
       target.setAddress(address);
       target.setRetries(1);
       target.setTimeout(5000);
       target.setVersion(SnmpConstants.version3);
       target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
       target.setSecurityName(new OctetString("SHADES"));
       return target;
    }

}

【问题讨论】:

    标签: snmp snmp4j


    【解决方案1】:

    报告 PDU 中的 OID 应该告诉您发生了什么。在典型情况下,将有一个或两个(或两个之一)请求/报告交换,以在管理器和代理(或者,更确切地说,分别是非权威和权威引擎)之间建立初始 SNMPv3 通信。

    第一个通常是usmStatUnknownEngineIDs 报告,它允许管理器发现代理的引擎 ID(需要用于密钥本地化等),如果您没有在初始请求中指定正确的引擎 ID,就会发生这种情况。如果使用auth/noPrivauth/priv 级别的安全性,则会发生第二种/其他情况,即usmStatsNotInTimeWindows,如果请求未在代理值的适当范围内指定引擎启动/引擎时间值,则会发送该值。这些值通过使请求在超出时间窗口时不再有效来防止消息重放攻击,并且管理器通常不知道它们是什么,直到它通过报告 PDU 从代理接收它们。

    在管理器获得正确的引擎 ID、引导和时间,并在必要时为引擎 ID 本地化密钥后,正常的请求/响应交换可以按预期进行。一些 SNMP API 会为您处理此交换,因此您只需发送请求并在交换后获得最终结果。 SNMP4j 似乎没有,如果它是这些报告之一,您可能必须自己处理。

    如果不是这些报告之一,那么您的配置可能不匹配。

    【讨论】:

      猜你喜欢
      • 2023-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      相关资源
      最近更新 更多