2017-09-07 8 views
0

J'ai écrit un agent SNMP et enregistré un objet géré (créé/défini une valeur d'un MIB OID). Lorsque je récupère cette valeur à l'aide de SNMPv2c, la valeur est renvoyée correctement - la PDU de ResponseEvent.getResponse a type = GET et les liaisons de variables ont des données attendues - OID correct, etc. Lorsque je récupère cette valeur à l'aide de SNMPv3 et de l'authentification utilisateur, le valeur n'est pas renvoyée correctement - l'unité PDU de ResponseEvent.getResponse a type = REPORT et les liaisons de variable ont un OID différent de celui de la demande - d'après ce que j'ai lu jusqu'à présent cela indique une erreur de config/authentication. Ci-dessous est l'exemple de code (snippets) utilisé pour le client & agent - s'il vous plaît pouvez-vous me dire comment créer l'agent & client - où je vais mal? L'OID de l'unité PDU de rapport doit vous indiquer ce qui se passe.L'agent ne retourne pas la valeur OID correcte lors de l'utilisation de SNMP4j (org.snmp4j) v3 et de l'authentification de l'utilisateur?

// 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; 
    } 

} 

Répondre

0

Dans des circonstances typiques, il y aura un ou deux (ou un des deux) échanges de demandes/rapports pour établir les communications SNMPv3 initiales entre le gestionnaire et l'agent (ou plutôt, les moteurs non autorisés et faisant autorité, respectivement). Le premier est généralement un rapport usmStatUnknownEngineIDs qui permet au gestionnaire de découvrir l'ID du moteur de l'agent (requis pour la localisation des clés/etc.) Et qui se produira si vous ne spécifiez pas l'ID du moteur approprié dans la demande initiale. Le second/autre se produit si vous utilisez la sécurité de niveau auth/noPriv ou auth/priv, et c'est usmStatsNotInTimeWindows, qui est envoyé si la requête ne spécifie pas les valeurs de Bottes moteur/temps moteur dans la plage appropriée des valeurs de l'agent. Ces valeurs empêchent les attaques de rejeu de message en rendant les requêtes non valides si elles tombent hors de la fenêtre de temps, et le gestionnaire ne sait généralement pas ce qu'elles sont avant de les recevoir de l'agent via une PDU de rapport. Une fois que le gestionnaire dispose de l'ID du moteur, de la durée et de l'heure, et que les clés de l'ID du moteur ont été localisées, l'échange normal de demande/réponse peut se dérouler comme prévu. Certaines API SNMP se chargeront de cet échange pour vous. Vous envoyez simplement votre demande et obtenez le résultat final après l'échange. Il semblerait que SNMP4j ne le fasse pas et vous devrez peut-être le gérer vous-même si c'est l'un de ces rapports.

Si ce n'est pas l'un de ces rapports, vous avez probablement une discordance de configuration.