Problem with receiving SNMPv3 traps with authentication

I would like to add that this report message contains “1.3.6.1.6.3.15.1.1.4.0” OID.

The report OID means: usmStatsUnknownEngineIDs
That engine ID discovery message does not make sense. Where is it originated from? That message discovers the engine ID of the trap receiver, but the trap sender must send its own engine ID. Therefore the discovery is useless (for being able to send SNMPv3 traps/notifications)

I have adjusted the engineBoot and engineTime parameters on the device and now the Java trap receiver works properly.
Thank’s very much fo your help.

Best regards,
Michael

1 Like

Hi,
I have one more question: is it possoble to turn off the engineTime counter on the snmp4j trap receiver automatically?
I can also do it manually by resetting the counter i.e. every 2 minutes.

Best regards,
Michael

Hi Michael,
You cannot configure SNMP4J to not check the engineTime, but you can implement and use your own USM that does not check the engineTime.
Best regards,
Frank

So if I want to do this, do I have to create my own USM object and there is no parameter for USM which turns off engineTime checking?

Best regards,
Michael

Yes, the UsmTimeTable is a private member in USM and therefore cannot be easily changed. The intention for this was indeed trying to increase security, but of course modifying the source code of USM would be an option too.

1 Like

Hello,
I decided to return to this post, because currently the trap transmitter, from which I receive traps, works in accordance with the SNMPv3 standard and after each reload it correctly increments engineBoot and engineTime.
For creating the USM I use the command:
usm = new USM(SecurityProtocols.getInstance(), getEngineId(), 0)
The listening dispatcher is defined as follows:
dispatcher.addMessageProcessingModel(new MPv3(usm))

In addition, I no longer set engineBoot or engineTime in the receiver, and the engineID should match, although I no longer use the setLocalEngine command when initializing the listener.
The receiver defined in this way does not receive traps correctly, probably due to different engineBoot and engineTime parameters.
I would like to ask if the engineBoot and engineTime parameters should be automatically synchronized via the SNMP protocol, or should something be manually set in the code? Maybe EngineBootsProvider is necessary?

Best regards,
Michael

Hi,

if you always create the USM with engineBoot value 0, your application can only be the non authoritative engine in a communication. So it can only send out get/getnext/set/inform,… requests and receive traps. It cannot receive an inform request. Sending out traps will not work.

If any engine just increases the engineBoot value at each startup, everything will work. The non authoritative receiver can then synchronize to the engineBoot and engineTime value of the authoritative engine through the normal message exchange (this is part of the SNMP RFC). There is no need to set the engineTime manually.

Kind regards,
Jochen

1 Like

Hello,
Ok, because I thought that remembering and synchronizing engineBoot might have to be done manually.
But what if there is a restart of the transmitter and increasing engineBoot, and the receiver is still running? Do I also need to restart the receiver then to synchronize?
And another question, how to initialize the USM without engineBoot which is equal to zero? What value should I set in the constructor?

Best regards,
Michael

Hi Michael,
I think there is still a misunderstanding: every SNMP entity has engineTime and engineBoots.

Thus, the constructor above defines the local notions of both values - not any remote values. And these values are not synchronized with the values local to any remote instance. The synchronization is done in a separate engine times table.
As consequence from the above, you always have to increase the engineBoots value on each restart. Otherwise, communication will need a manual reset of the engine time table entry on all remote peers for this target.

Hope this helps.
Frank

1 Like

Hello,
The above answer explained me the concept of working SNMP.
In my case, the devices from which I received traps can be independently rebooted many times and after a few reboots my trap receiver starts listening for traps from these devices. My receiver is also restarted any number of times in the meantime, so I can’t manually keep the engineBoot parameter matched. Isn’t this engineBoot synchronization automatically done when the protocol detects an engineBoot value mismatch? How to implement this in my case?

Best regards
Michael

Hi,

as long as each involved engine (trap sender, trap receiver, agent, manager,…) increases its own engineBoots value with each restart, everything will work. There is no need that all engines have the same engineBoots value.

Kind regards,
Jochen

2 Likes

I am trying to implement this mechanism, but logs from LogFactory when receiving traps show me error 1411 (SNMPv3_USM_NOT_IN_TIME_WINDOW). The trap transmitter correctly increments engineBoot and engineTime. When I start my trap receiver, the received traps have an initial engineBoot value of eg 20 and incremented engineTime, and my receiver on startup starts with engineBoot and engineTime = 0.
When initializing the receiver, I use the following commands with engineBoot and engineTime parameters:

usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0);
usm.addUser(user, localEngineID, createUsmUser());
usm.setEngineDiscoveryEnabled(true);
dispatcher.addMessageProcessingModel(new MPv3(usm));
snmp=new Snmp(dispatcher, transport);
snmp.setLocalEngine(localEngineID, 0 ,0);
snmp.listen();

Could you please give me a hint where the problem lies?

Best regards,
Michael

The problem ist the hard coded 0 for the engineBoots. Whenever you restart your receiver, the sender will have a different engineBoots value remembered for your receiver from the last run with the same local engine ID.If the boots of the sender is greater than the one of the receiver, then a usmNotInTimeWindow error is reported.

Currently traps received from the transmitter have engineBoot=40 and engineTime e.g. 200.
In the receiver, I made several attempts with engineBoot, setting:

usm = new USM(SecurityProtocols.getInstance(), localEngineID, 40);
snmp.setLocalEngine(localEngineID, 40, 0);

or

usm = new USM(SecurityProtocols.getInstance(), localEngineID, 41);
snmp.setLocalEngine(localEngineID, 41, 0);

However, I had error 1411 each time.

Please consult the SNMPv3 USM RFC 3414 about the engine time synchronisation. I do not think that we can solve it here anymore.
As explained before, trying to use the same value for the local engineBoots as the sender uses for its engine has no use and is the wrong approach.

I seem to have solved the engineBoot issue.
Traps are correctly received only when the receiver has a different engineId than the transmitter, and in the receiver I set e.g.

snmp.setLocalEngine(receiverEngineID, 0, 0);

So I suppose that I must have two engineId values defined, and if I want to send traps, I will include the receiver’s local engineId in the sent trap, and engineBoot incremented after each receiver restart for a given fixed receiver engineId.

Yes, the following sentence should be part of every SNMPv3 FAQ:

The first sentence of the following quote is not correct, because the trap sender is authoritative. Thus, the engineID relevant for the authenticity is the engine ID of the sender (= authoritativeEngineID in UsmParameters of the SNMPv3 ScopedPDU). The second part about the need of incrementing the engineBoots counter on each restart (=reset of the egineTime) is true:

1 Like

Yes, that’s what I thought, only I worded it wrong above, because I was thinking about my receiver becoming a transmitter :grinning:.
Thanks all for help in solving the problem.