Коротко: В реализации SNMPv3 на перечисленных моделях коммутаторов time window (150 секунд согласно rfc 3414) считается только назад от текущего времени.
В результате если на клиенте время "тикнет" на секунду вперед, а на коммутаторе нет, пакет SNMPv3 будет коммутатором считаться невалидным, поскольку не укладывается в time window (usmStatsNotInTimeWindows).
Теперь длинно (просто вставлю отчет по внутренней задаче).
Проблема с snmpv3 на свичах dlinkЕсть плагин nagios для мониторинга петель (loop detect) на коммутаторах. Написан на perl, использует Net::SNMP.
Периодически запросы snmp выдают ошибку "Received usmStatsNotInTimeWindows.0 Report-PDU with value XXXX"
Проблема замечена на свичах D-Link DGS-1210-52/ME, DGS-1210-28X/ME, DGS-1210-52MP (возможно подвержена вся серия DGS-1210).
На DGS 3420-28TC такого нет.
Для начала - что такое usmStatsNotInTimeWindows:
В SNMPv3 для предотвращения возможности атак через повторную отправку SNMP сообщений введено ограничение по времени. В пакетах присутствует поле engine time, которое стороны синхронизируют при установлении сессии.
Если мы получили пакет, а engine time в нем отличается от локального engine time более чем на 150 секунд, в ответ отправляется report с OID usmStatsNotInTimeWindows и значением счетчика таких пакетов.
Т.е. свичу не нравится engine time в запросе.
Плагин открывает сессию SNMP и последовательно шлет несколько запросов. Какой-то из них (не первый) выдает ошибку.
Смотрим дамп dump3.png и видим, что engine time в последнем запросе увеличилось на единицу, а в report на единицу меньше.
Hint: в wireshark в свойствах диссектора SNMP можно указать Auth и Priv пароли с алгоритмами и смотреть траффик в расшифрованом виде.
Вложение:
dump3.png [ 33.59 KiB | Просмотров: 5256 ]
Похоже причина в том, что несмотря на настроенный на свиче NTP время сторон отличается на доли секунды. И когда на сервере мониторинга время на секунду опережает свич отправленный пакет считается свичом не попадающим в time window.
Кстати, интересно как оно (окно) считается - 150 секунд от текущего времени назад, 150 секунд назад и вперед или 75 секунд назад и 75 вперед?
Поиск в интернет вывел на
http://vladimir-stupin.blogspot.com/201 ... ineid.html но тут выяснилось, что Net::SNMP не использует библиотеки net-snmp - там своя реализация на чистом perl. Оно и к лучшему.
Лезем в код Net::SNMP. Если мы работаем со временем явно где-то будет вызов time().
Файл /usr/share/perl5/Net/SNMP/Security/USM.pm, функция sub _engine_time
$this->{_engine_time} = time() - $this->{_time_epoc};
А что если сделать так:
$this->{_engine_time} = time() - $this->{_time_epoc} + 1;
и теперь мы в 100% случаев имеем "Received usmStatsNotInTimeWindows.0 Report-PDU with value XXXX"
Меняем плюс на минус. И проблема больше не воспроизводится. Дамп dump4.png
Вложение:
dump4.png [ 76.07 KiB | Просмотров: 5256 ]
А engine time в запросах стал на единицу меньше чем в ответах.
Еще немного поигравшись с плюс/минус и значениями 149/151 выясняем, что на DGS-1210 time window считается от текущего времени только назад, а на DGS 3420 назад и вперед.