markabrahams / node-net-snmp

JavaScript implementation of the Simple Network Management Protocol (SNMP)
204 stars 96 forks source link

agent v3 - discovery not completed #237

Open michelevince opened 11 months ago

michelevince commented 11 months ago

Hi all!

I'm implementing a snmp agent which must support v3 version. I'm using a commercial MIB browser.

Currently I'm having a problem in the discovery process that the MIB browser starts against the agent. The MIB Browser I'm using to test my agent is sending a "get-request" with user "initial". To that request my agent answers with a "report" but nothing next happens (I have tracked with wireshark the flow).

[ The same MIB Browser can verify correctly a user against a commercial agent. The flow I observe is: (i) "get-request" from MIB browser to agent with user "initial", (ii) "report" answer from agent with an oid, (iii) "get-next-request" from MIB browser with correct username, (iv) "report" answer from agent with an oid. Then the user is accepted by the MIB Browser ]

I'll post the actual code (a simplified version), I know it's pretty close to the examples. I have added a "initial" user in my agent in order the be able to answer to the first MIB browser request. Without the "initial" user i get the following error on the agent RequestFailedError: Local user not found for message with user initial

Can you provide some help in order to make it work? Thanks!

let snmp = require ('net-snmp');
const util = require('util');

const snmpOptions = {
  port: 161,
  disableAuthorization: false,
  accessControlModelType: snmp.AccessControlModelType.Simple, // None: 0, Simple: 1
  engineID: '8000B9838086f88205eb4fe74a5bb58dcf',
  address: null,
  transport: 'udp4'
};

const  callback = (error, data) => {
  if(error) {
    console.error(util.inspect(error, { depth: 7 }));
  }else {
    console.info(util.inspect(data, { depth: 7 }));
  }
};

let agent = snmp.createAgent(snmpOptions, callback);

//
// Authorization
//
let authorizer = agent.getAuthorizer ();
authorizer.addCommunity ('public');

const user = {
  name: 'test',
  level: snmp.SecurityLevel.authPriv,
  authProtocol: snmp.AuthProtocols.sha,
  authKey: 'test1',
  privProtocol: snmp.PrivProtocols.des,
  privKey: 'test3'
};
authorizer.addUser (user);
authorizer.addUser ({
  name: 'initial',
  level: snmp.SecurityLevel.noAuthNoPriv
});

let acm = authorizer.getAccessControlModel ();
acm.setCommunityAccess ('public', snmp.AccessLevel.ReadOnly);
acm.setUserAccess (user.name, snmp.AccessLevel.ReadWrite);
acm.setUserAccess ('initial', snmp.AccessLevel.ReadWrite);
markabrahams commented 7 months ago

Hi @michelevince - have you populated the MIB elsewhere in your code? You'll need to register MIB provider(s) and add MIB value(s) to populate the MIB and get the agent returning data. e.g.

var scalarProvider = {
    name: "sysDescr",
    type: snmp.MibProviderType.Scalar,
    oid: "1.3.6.1.2.1.1.1",
    scalarType: snmp.ObjectType.OctetString,
    maxAccess: snmp.MaxAccess['read-write']
};
agent.registerProvider(scalarProvider);
agent.getMib().setScalarValue("sysDescr", "Rage inside the machine!");

With that added to the end of your code, an snmp-get of "sysDescr" works both with this library acting as the client, and it also works with Net-SNMP package's "snmpget" tool e.g.

snmpget -v3 -u initial -l noAuthNoPriv localhost 1.3.6.1.2.1.1.1.0

returns the MIB value fine.

Given that these two independent clients are successful and the commercial MIB browser isn't, you might want to raise the same issue with the commercial MIB browser vendor to give some guidance on what problem their MIB browser might be having here?

Also, can you shed some light the result of your Wireshark analysis? In particular, the comparison of the contents of the "report" (packet (ii) in your flow) from the commercial agent and the "report" packet from your library agent here would be enlightening.