SNMPv3 example with multiple devices and DirectUserTarget

Hi there.

I have some code which does SNMPv3 queries to a bunch of devices periodically.
Currently, the code was written such that when a connection is set up to do a query,
it does the following:

==============================

DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
snmp.listen();

OctetString localEngineID = new OctetString(MPv3.createLocalEngineID());
USM usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0 );
SecurityModels.getInstance().addSecurityModel(usm);

snmp.getUSM().addUser(new OctetString(authUsername), new UsmUser(
        new OctetString(authUsername),
        getAuthProtocolOID(authProtocol),
        new OctetString(authPassword),
        getPrivacyProtoOID(privacyProtocol),
        new OctetString(privacyPassword)));

UserTarget target = new UserTarget();
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString(authUsername));
target.setVersion(SnmpConstants.version3);
target.setAddress(addr);
target.setRetries(retries);
target.setTimeout(timeoutMillis);
this.target = target;
this.contextName = contextName;

==============================

Recently on a couple of requests we have seen the error:
Error: org.snmp4j.MessageException: Message processing model 3 returned error: Unknown security name

I came across a stackoverflow article:
Stack Overflow - Unknown Security Name

Which mentions how the USM should be a singleton and not created on every fetch.
I was thinking of doing it that way but then was wondering about how we have different users and passwords for various devices which might share the username but have different passwords or protocols.
Then on the question of “USM as global creds storage” I saw it was mentioned about using a DirectUserTarget which can specify all the v3 security fields.

If one uses a singleton USM, and a DirectUserTarget for the SNMPv3 security fields, would that make sense?
Do you have examples of using SNMP v3 over various devices and showing what needs to be a singleton and what needs to be created per connection?
I have seen references that mention that one should just use one snmp object, for example.

Thanks,
Tim.

Hi Tim,
A DirectUser example can be found on snmp4j.org

To use direct users, a USM is still necessary but you do not need to add any users to it.
In any case, you should use localized users with your USM only.

Then you will not have any problems with same username but different passwords (see How-to configure SNMPv3 users with same name but different passphrases? - XWiki)

The above code is not adding a localized USM user. Instead the localization is deferred until each first usage with a concrete target.
The security drawback of this approach is, that the original passkey needs to be kept in memory. That way all targets using the passkey are put on risk instead only those where actually communication takes place.
Of course, that “risk” is somehow secondary but should be avoided if possible.

Thanks for the information and replying so quickly, Frank. Very helpful.

The example in the Configuration FAQ is helpful for using the localised user and getting the engine id.

I didn’t see an example for the DirectUser on the site other than the documentation with the specification. However, that will be fine.
I was just thinking a complete example for SNMPv3 showing the querying for a set of devices would be handy to show what data needs to be kept global and what needs to be done per device as I find that is not clear and hence why I think the questions came up in Stack Overflow and possibly on the forum.

Thanks a bunch, Tim.