net-snmp / net-snmp

A SNMP application library, tools and daemon
Other
330 stars 219 forks source link

SNMPv3 traps via device reboot doesn't update EngineBoot counter #827

Open iyyapa opened 4 months ago

iyyapa commented 4 months ago

I was testing the Snmpv3 traps and found that the USM time synchronization is failing.
Reload the switch, upon booting the SLX will send the traps to the ubuntu server and from the packet capture we can see the msgAuthoritativeEngineBoots is always 1.

According to RFC 3414 the value should be persist even after reboot. It should increment every reboot. Can you please help us to identify the root cause?

image

hardaker commented 4 months ago

This sounds like the persistent storage for the device is not working. IE, if the agent is an net-snmp agent it should be able to write to the persistent snmpd.conf file and if it fails to write that it can't remember where it left off across reboots.

iyyapa commented 4 months ago

Hi @hardaker Thank you for your feed back. Yes. It is an net-snmp agent also writing into persistent snmpd.conf file. It would be very helpful if you point any code where we need to check and all.

hardaker commented 4 months ago

Try running the agent with -Dread_config to see everything that the configuration system is doing, which should print out where it is trying to load/save information.

iyyapa commented 4 months ago

After checking the code, Looks like it's hardcode the value as 1. At this point, not sure any reason? We have EmanateLite to net-snmp and hardcode this as 1.

image image

iyyapa commented 4 months ago

Hi @hardaker Instead of hardcode I tried to fetch the value from snmpv3_local_snmpEngineBoots() API. But it's always returns 1. why this snmpv3_local_snmpEngineBoots() API returns always 1. The snmpwalk works fine.

hardaker commented 4 months ago

engineboots is never less than 1, so the =1 case you point to above is for when an agent starts and has no value (and thus the value of the variable starts at 0), so the agent sets the very first value to 1 instead of 0.

snmpv3_local_snmpEngineBoots() will also always return 1 inside the agent if you fail to have the agent properly write to the persistant storage configuration file, as I mentioned above: this is likely the problem.

iyyapa commented 4 months ago

Thanks for clarification.

Can you please suggest/point the code where we need to check persistent storage config file. Are you referring the below code.

--- net-snmp-5.9.1/snmplib/snmpv3.c     2024-06-17 17:03:18.195804588 -0700
+++ net-snmp-5.9.1-Modified/snmplib/snmpv3.c    2024-06-17 17:06:29.866841528 -0700
@@ -994,8 +994,8 @@ init_snmpv3(const char *type)
                                     engineIDType_conf, NULL, "num");
     register_prenetsnmp_mib_handler(type, "engineIDNic", engineIDNic_conf,
                                     NULL, "string");
-    register_config_handler(type, "engineBoots", engineBoots_conf, NULL,
-                            NULL);
+    register_prenetsnmp_mib_handler(type, "engineBoots", engineBoots_conf, NULL,
+                                    NULL);

     /*
      * default store config entri
tfidecki commented 3 months ago

I have the same problem with snmpv3 traps. We use the snmptrap command to send notifications to the upstream OSS system. After a restart of the snmptrapd daemon (no matter if it's a service restart or a device restart), the EngineBoots parameter in the /var/lib/net-snmp/snmptrapd.conf file correctly increments its value. But in the sent trap, the value is not changed and always msgAuthoritativeEngineBoots=1

image

iyyapa commented 3 months ago

Please check the code, the might hardcoded the value as below..

updateEngineID() if (session->engineBoots == 0) session->engineBoots = 1;

fenner commented 3 months ago

use the snmptrap command to send notifications to the upstream OSS system.

When using the snmptrap command to send a trap using SNMPv3, you have to supply the boot and engine time to the command with the -Z argument; snmptrap itself has no persistent store so by necessity starts with engineBoots=1 .

To avoid this complexity, if you have an snmpd running, you can configure it to listen to agentx, configure the trap destinations in the agent config, and use agentxtrap. agentxtrap sends the message over the agentx socket and requests that the server send the trap, and the server has all the context and configuration needed to send it properly.

caojg123 commented 1 month ago

@iyyapa I also meet the problem with snmpV3 traps. In the sent trap, the value is not changed and always msgAuthoritativeEngineBoots=1. Could you have method to solve it? Thanks!

iyyapa commented 1 month ago

@caojg123 Have you narrow down issue. Whether engineBoots value in SNMPV3 traps is hardcoded to 1 or not. If it's hardcode you can call API to get the engineID value to open the file "/var/lib/net-snmp/snmpd.conf" and fetch engineboots.

Also, did you checked whether engineboots vlaue is properly incremented under this /var/lib/net-snmp/snmpd.conf file.

fenner commented 1 month ago

snmptrap does not use persistent storage.

The best way to get engineBoots working properly for traps is to use snmpd to send traps, and use the agentxtrap command-line program to create the traps. This requires configuring agentx, and requires configuring trap destinations in snmpd.conf, but provides the required semantics of engineTime and engineBoots.

caojg123 commented 1 month ago

@iyyapa I use the net-snmp version 5.9 and the engineBoots value in SNMPV3 traps is always 1. Do you use the below method to fetch engineboots from "/var/lib/net-snmp/snmpd.conf" file which you refer in above comment?

image

fenner commented 1 month ago

If you are using snmpd's persistent file to load engineBoots for the snmptrap command line app, please realize that you will not have the same engineTime as snmpd does, so if snmpd sends some traps and you send some using snmptrap, the engineTime will be changing incorrectly and the receiver will not be able to authenticate all of the messages.

tfidecki commented 1 month ago

But doesn't the RFC allow a certain amount of time for inaccuracy? https://datatracker.ietf.org/doc/html/rfc3414#page-28

fenner commented 1 month ago

But doesn't the RFC allow a certain amount of time for inaccuracy?

Sure. snmptrapd uses the system uptime to generate engine time. snmpd starts engine time at zero when the process is started, and counts from there; the system uptime is not used. So if snmpd was started at system boot time and never restarted, then the engineTime will likely be close enough to work.