SNMP-агент

SNMP используется для мониторинга таких устройств, как: принтеры, сетевые коммутаторы, маршрутизаторы или ИБП, которые, как правило, поддерживают SNMP и на которых было бы непрактично пытаться устанавливать полноценные ОС и Агенты.

Чтобы была возможность получать данные, переданные SNMP-агентами с этих устройств, Сервер должен быть изначально сконфигурирован с поддержкой SNMP.

SNMP-проверки выполняются только через UDP-протокол.

Серверы и Прокси опрашивают устройства SNMP по несколько значений за один запрос. Такое поведение влияет на все виды элементов данных SNMP (обычные элементы данных SNMP, элементы данных с динамическими индексами, а также низкоуровневые SNMP обнаружения), и делает работу SNMP более эффективной. Также массовые запросы можно отключить у устройств, которые не способны обработать их должным образом, используя настройку "Использовать массовые запросы", доступную в каждом интерфейсе.

Процессы Сервера и Прокси запишут в журнал строки наподобие следующих в случае получения неправильного/искаженного SNMP-ответа:

SNMP response from host "gateway" does not contain all of the requested variable bindings

Пока они не покрывают все возможные проблемные случаи, но они полезны для идентификации отдельных SNMP-устройств, на которых массовую обработку нужно отключить.

Сервер/Прокси всегда повторят запрос минимум один раз после неуспешной попытки: либо через механизм библиотеки SNMP, либо через внутренний механизм сбора множества значений за один запрос (bulk).

При мониторинге устройств по SNMPv3 следует убедиться, что msgAuthoritativeEngineID (также известное как snmpEngineID или "Engine ID") никогда не будет общим для двух и более устройств. Согласно RFC 2571 оно должно быть уникальным для каждого устройства.

RFC3414 требует, чтобы SNMPv3-устройства сохраняли свои значения engineBoots. Некоторые устройства не выполняют этого требования, что приводит к тому, что после перезагрузки их SNMP-сообщения отбрасываются как устаревшие. В этой ситуации необходимо вручную очистить кэш SNMP на Сервере/Прокси (используя "-R snmp_cache_reload") или же перезапустить Сервер/Прокси.

Для настройки мониторинга устройства по SNMP нужно выполнить следующие шаги:

Шаг 1. Узнать строку SNMP (или OID) элемента данных, который требуется мониторить.

Для получения списка строк SNMP использовать команду snmpwalk или эквивалентную утилиту:

snmpwalk -v 2c -c public <IP хоста>

где "2c" означает версию SNMP (можно заменить его на "1", чтобы использовать на устройстве SNMPv1).

Эта команда должна показать список SNMP-строк и их последние значения. Если это не произойдет, то возможно, что SNMP-"community" отличается от стандартного "public". В этом случае необходимо узнать это имя.

Для поиска конкретной строки, которую нужно мониторить, используют список; например, если требуется мониторить количество входящих байтов на третьем порту коммутатора, можно использовать IF-MIB::ifInOctets.3 из этой строки:

IF-MIB::ifInOctets.3 = Counter32: 3409739121

Также можно воспользоваться командой snmpget, чтобы определить цифровой OID для IF-MIB::ifInOctets.3:

snmpget -v 2c -c public -On 10.62.1.22 IF-MIB::ifInOctets.3

Следует обратить внимание, что последнее число в строке – это номер порта, который ищется для мониторинга.

Вывод команды покажет примерно следующее:

.1.3.6.1.2.1.2.2.1.10.3 = Counter32: 3472126941

Последнее число в OID является номером порта.

Некоторые из наиболее часто используемых SNMP OID автоматически конвертируются Подсистемой в числовое представление.

В последнем примере тип значения Counter32 (32-битный счетчик) внутренне соответствует типу ASN_COUNTER. Полный список поддерживаемых типов: ASN_COUNTER, ASN_COUNTER64, ASN_UINTEGER, ASN_UNSIGNED64, ASN_INTEGER, ASN_INTEGER64, ASN_FLOAT, ASN_DOUBLE, ASN_TIMETICKS, ASN_GAUGE, ASN_IPADDRESS, ASN_OCTET_STR и ASN_OBJECT_ID. Приведенные типы грубо соответствуют "Counter32", "Counter64", "UInteger32", "INTEGER", "Float", "Double", "Timeticks", "Gauge32", "IpAddress", "OCTET STRING", "OBJECT IDENTIFIER" в выводе утилиты snmpget, но могут также отображаться как "STRING", "Hex-STRING", "OID" и другими в зависимости от наличия подсказки.

Шаг 2. Создать узел сети, соответствующий устройству.

Добавить к узлу сети SNMP-интерфейс:

  1. ввести IP-адрес/DNS-имя и номер порта;
  2. выбрать Версия SNMP из выпадающего списка;
  3. добавить учетные данные к интерфейсу в зависимости от выбранной версии SNMP:
    • SNMPv1, v2 требуют только community (обычно "public");
    • SNMPv3 требует более специфичные опции (таблица 71);
  4. оставить выбранным "Использовать массовые запросы", чтобы разрешить массовую обработку SNMP-запросов.

В случае некорректных учетных данных SNMPv3 (имя безопасности, протокол/фраза-пароль аутентификации, протокол безопасности):

  • Подсистема получит ERROR от net-snmp, за исключением ошибочного значения "Ключевая фраза безопасности", в этом случае – ошибку превышения "ВРЕМЕНИ ОЖИДАНИЯ" от net-snmp;
  • доступность интерфейса SNMP переключится на красный цвет (недоступно).

Изменения в "Протокол аутентификации", "Пароль аутентификации", "Протокол безопасности" или "Ключевая фраза безопасности" без изменения "Имя безопасности" вступят в силу только после ручной очистки кэша на Сервере/Прокси (используя "-R snmp_cache_reload") или при перезапуске Сервера/Прокси. В случае если "Имя безопасности" также меняется, все параметры будут обновлены немедленно.

Можно использовать один из поставляемых шаблонов SNMP ("Template SNMP Device" и другие), которые автоматически добавят набор элементов данных. Но шаблон может быть несовместим с узлом сети. Далее нажать на кнопку Добавить для сохранения узла сети.

Шаг 3. Создать элемент данных для мониторинга.

В меню Подсистемы нажать на Элементы данных у ранее созданного SNMP узла сети. В зависимости от того, использовался ли шаблон при создании узла сети или нет, можно увидеть или список элементов данных SNMP, связанных с узлом сети, или пустой список. Для самостоятельного создания элемента данных с помощью собранной информации, используя snmpwalk или snmpget, нажать на Создать элемент данных. В окне нового элемента данных (рисунок 3):

  1. ввести имя элемента данных;
  2. изменить поле Тип на SNMP Агент;
  3. ввести в поле Ключ, например: SNMP-InOctets-Bps;
  4. убедиться, что в поле "Интерфейс узла сети" указан нужный коммутатор/роутер;
  5. ввести в поле "SNMP OID" текстовый или числовой OID, который получен ранее, например: .1.3.6.1.2.1.2.2.1.10.3;
  6. установить "Тип информации" в значение равное "Числовой (с плавающей точкой)";
  7. ввести "Интервал обновления" и период "Хранения истории", если нужно, чтобы значения параметров отличались от значений по умолчанию;
  8. на вкладке Предобработка добавить шаг "Изменение в секунду" (это важно, так как иначе с SNMP-устройства будут получены накопленные значения вместо последнего изменения); выбрать пользовательский множитель при необходимости.

Рисунок 3 — Окно ввода

Теперь нужно сохранить элемент данных и перейти в "Мониторинг → Последние данные", чтобы увидеть данные SNMP.

Обработка массовых SNMP-запросов

Сервер и Прокси одним запросом опрашивают множество SNMP-элементов данных. Такое поведение затрагивает следующие типы SNMP-элементов данных:

  • обычные SNMP-элементы данных;
  • SNMP-элементы данных с динамическими индексами;
  • правила низкоуровневого SNMP-обнаружения.

Все элементы данных SNMP с одного интерфейса планируются на опрос в одно время. Первые два типа элементов данных собираются поллерами порциями не более чем по 128 элементов данных, в то время как правила низкоуровневого обнаружения обрабатываются индивидуально, как и ранее.

На низком уровне есть два вида операций, выполняемых при опросе значений: получение нескольких заданных объектов и обход дерева OID.

Для "получения" используется GetRequest-PDU c не более чем 128 привязанных переменных. Для "обхода" используется GetNextRequest-PDU для SNMPv1 и GetBulkRequest с полем "max-repetitions" с наибольшим количеством в 128 полученных значений для SNMPv2 и SNMPv3.

Таким образом, преимущества массовой обработки для каждого типа SNMP элемента данных описаны ниже:

  • обычные SNMP элементы данных получают преимущество от улучшенного получения;
  • SNMP-элементы данных с динамическими индексами получают преимущество и от улучшенного "получения "и "обхода": "получение" используется для проверки индексов, а "обход" – для построения кэша значений;
  • правила низкоуровневого SNMP обнаружения получают преимущество от улучшенного "обхода".

Тем не менее есть техническая проблема: не все устройства способны вернуть 128 значений за один запрос. Некоторые всегда возвращают корректный ответ, но другие либо отвечают с ошибкой "tooBig(1)", либо не отвечают вообще, если потенциальный запрос превышает определенный лимит.

Для вычисления оптимального количества объектов, запрашиваемых с данного устройства, Подсистема использует итерационную стратегию. Начинается с осторожного запроса одного значения. Если запрос выполнен успешно, запрашивается 2 значения за один запрос. Если запрос снова выполнен успешно, запрашивается 3 значения за запрос и продолжается аналогично путем умножения количества запрашиваемых значений на 1.5, в результате получается следующая последовательность размера запросов: 1, 2, 3, 4, 6, 9, 13, 19, 28, 42, 63, 94, 128.

Как только устройство отказывается давать корректный ответ (к примеру, на 42 переменных), Подсистема выполняет два действия.

Во-первых, для текущей серии элементов данных Подсистема делит пополам количество объектов на один запрос и запрашивает 21 переменную. Если устройство доступно, то запрос должен работать в большинстве случаев, потому что было известно, что с 28 переменными работало, а 21 значительно меньше. Если проблема продолжается, Подсистема возвращается к опросу значений по одному. Если проблемы есть и в этом случае, значит устройство определенно не отвечает и проблема не в размере запроса.

Во-вторых, для дальнейших порций элементов данных Подсистема начинает с последнего удачного количества переменных (28 в нашем случае) и продолжает, увеличивая количество переменных за запрос на 1 до достижения лимита. Например, если наибольший размер ответа – это 32 переменных, то последующие запросы будут размерами 29, 30, 31, 32 и 33. Последний запрос будет неудачным, и Подсистема никогда более не запросит 33 значения за один запрос. С этого момента Подсистема всегда будет опрашивать максимум по 32 переменных для этого устройства.

Если большие запросы неудачно завершаются с этим количеством переменных, это может означать одно из двух. Точный критерий, используемый устройством для ограничения размера ответа, неизвестен, но пытаются приблизительно оценить это, используя количество переменных. Поэтому первая возможность – в общем случае это количество переменных около реального ограничения размера ответа для данного устройства: иногда ответ меньше этого предела, иногда больше. Вторая возможность – что UDP-пакет (в любом направлении) просто был потерян. По этим причинам, если Подсистема сталкивается с неудачным запросом, то он уменьшает максимальное количество переменных, чтобы попытаться перейти в приемлемый для устройства диапазон, но только до 2 раз.

В примере выше, если запрос с 32 переменными будет неудачен, Подсистема уменьшит количество до 31. Если неудача случится снова, Подсистема уменьшит количество до 30. Тем не менее Подсистема не будет уменьшать количество ниже 30, потому что он предположит, что дальнейшие проблемы по причине потерянных UDP-пакетов, нежели из-за ограничения устройства.

Если устройство не умеет обрабатывать массовые запросы корректно и описанная выше эвристика не работает, то у каждого интерфейса имеется настройка "Использовать массовые запросы", позволяющая отключить массовые запросы у этого устройства.

Динамические индексы

Не всегда требуемый номер индекса (например, сетевого интерфейса) из всех SNMP OID остается таким же.

Индексы могут быть динамическими – они могут изменяться время от времени и, как следствие, элемент данных может перестать работать.

Чтобы избежать этого, имеется возможность указать OID, который принимает во внимание возможность изменения номера индекса.

Например, если необходимо получить значение индекса, который относится к ifInOctets, которое соответствует интерфейсу GigabitEthernet0/1 на устройстве Cisco, используют следующий OID:

ifInOctets["index","ifDescr","GigabitEthernet0/1"]

Для OID используется специальный синтаксис (параметры – в таблице 72).

<OID данных>["index","<базовый OID индекса>","<искомая строка>"]

Например, для получения использования памяти процессом apache, если используется этот синтаксис OID:

HOST-RESOURCES-MIB::hrSWRunPerfMem["index","HOST-RESOURCES-MIB::hrSWRunPath", "/usr/sbin/apache2"]

номер индекса будет искаться здесь:

...
HOST-RESOURCES-MIB::hrSWRunPath.5376 = STRING: "/sbin/getty"
HOST-RESOURCES-MIB::hrSWRunPath.5377 = STRING: "/sbin/getty"
HOST-RESOURCES-MIB::hrSWRunPath.5388 = STRING: "/usr/sbin/apache2"
HOST-RESOURCES-MIB::hrSWRunPath.5389 = STRING: "/sbin/sshd"
...

Теперь при наличии индекса, равного 5388, он будет присоединен к OID данных, чтобы получить требуемое значение:

HOST-RESOURCES-MIB::hrSWRunPerfMem.5388 = INTEGER: 31468 KBytes

При запросе динамического индекса элемента данных Подсистема извлекает и кэширует всю таблицу SNMP под базовым OID, даже если совпадение будет найдено ранее. Это делается на тот случай, если другой элемент данных в дальнейшем ссылается на тот же самый базовый OID – Подсистема будет искать индекс в кэше вместо еще одного запроса к наблюдаемому устройству. Следует обратить внимание, что каждый процесс поллера использует свой собственный кэш.

Во всех последующих операциях получения значений проверяется только найденный индекс. Если он не изменился, значение запрашивается. Если он изменился, кэш перестраивается – каждый поллер, который встречает измененный индекс, снова обходит и кэширует таблицу индексов SNMP.

Специальные OID

Некоторые OID, наиболее часто используемые в SNMP, автоматически преобразовываются в числовые представления самим Подсистемой. Например, ifIndex преобразовывается в 1.3.6.1.2.1.2.2.1.1, ifIndex.0 преобразовывается в 1.3.6.1.2.1.2.2.1.1.0.

В таблице 73 содержится перечень специальных OID.

MIB-файлы

MIB (база управляющей информации) – это виртуальная база данных, используемая для управления объектами в сети связи. MIB-файлы позволяют использовать текстовое представление OID. При мониторинге Подсистемой устройств SNMP можно использовать первичные OID, но для комфортного использования текстовых представлений потребуется установить MIB-файлы.

Например, ifHCOutOctets является текстовым представлением OID 1.3.6.1.2.1.31.1.1.1.10.

Установка MIB-файлов на ОС на основе Debian:

apt install snmp-mibs-downloader
download-mibs

Установка MIB-файлов на ОС на основе RedHat:

dnf install net-snmp-libs

На ОС на основе RedHat MIB-файлы должны быть подключены по умолчанию. На ОС на основе Debian нужно отредактировать файл /etc/snmp/snmp.conf и закомментировать строку, которая содержит mibs:

As the snmp packages come without MIB files due to license reasons, loading# of MIBs is disabled by default. If you added the MIBs you can re-enable# loading them by commenting out the following line.
mibs :

Тестирование snmp MIB-файлов можно выполнить с использованием утилиты snmpwalk. Если эта утилита не установлена, можно воспользоваться следующими инструкциями:

  1. для ОС на основе Debian:
apt install snmp
  1. для ОС на основе RedHat:
dnf install net-snmp-utils

После этого следующая команда должна не выдавать ошибку при выполнении запроса к сетевому устройству:

$ snmpwalk -v 2c -c public <IP СЕТЕВОГО УСТРОЙСТВА> ifInOctets
IF-MIB::ifInOctets.1 = Counter32: 176137634
IF-MIB::ifInOctets.2 = Counter32: 0
IF-MIB::ifInOctets.3 = Counter32: 240375057
IF-MIB::ifInOctets.4 = Counter32: 220893420
[...]

Следует обратить внимание, что процессы Подсистемы не определяют изменения, выполненные с MIB-файлами, поэтому после каждого изменения необходимо перезапускать Сервер или Прокси, например:

service zabbix-server reStart

После выполнения этой команды изменения, сделанные в MIB-файлах, вступят в силу.