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

SNMP протокол задумывался как универсальное средство мониторинга и управления сетевыми устройствами, и изначально позволял как опрашивать устройство (агент), так и отправлять устройством (агентом) событие на сервер.

Для этого существует два сообщения - Trap и Inform.
И если трапы еще худо-бедно используются то про inform многие даже не слышали.

Но давайте по порядку, что же вообще может дать прием трапов или информов такого, чего не может дать опрос?

Сразу начну с интересного а потом перейдем к подробностям.

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

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

Конечно, можно посмотреть логи на устройстве, но это не одно и то же.

Или другой пример, у вас происходит кратковременное событие, ну к примеру, загрузка ЦПУ растет до 100% и затем снижается, но происходит это между опросами.
Можно конечно уменьшить интервал опроса но это тоже может быть нежелательно.

Можно настроить syslog с транспортом TCP но на большинстве устройств это никак делу не поможет, так как после восстановления связи сессия установится новая, и туда будут отправлены новые сообщения, а вот старые придется смотреть в локальном журнале на оборудовании.

Есть еще одна причина, по которой SNMP Trap/Inform предпочтительнее Syslog сообщений в некоторых случаях, и причина эта безопасность.

Большая часть сетевого оборудования, отправляет Syslog сообщения в незашифрованном виде.
Некоторое оборудование позволяет отправлять зашифрованные Syslog сообщения (используется TLS).

SNMP трапы же можно зашифровать если использовать версию 3 протокола, а SNMP версии 3 поддерживается практически повсеместно, в отличие от Syslog over TLS.

Однако в случае использования Trap/Inform сообщений версии 3, резко увеличивается сложность настройки как оборудования (агента) так и сервера.

Так как протокол SNMP версии 3, для формирования ключевого материала для шифрования/расшифровки сообщений использует параметр Engine ID а также пароли шифрования и аутентификации, то для того чтобы сервер мог расшифровать сообщение, он должен знать о том, какие параметры использовать для его расшифровки.

И во многих случаях это нужно заранее указать в файле настройки.

Зачастую нужно обязательно указывать engine id, имя пользователя, протоколы аутентификации и шифрования и пароли.

Рассмотрим случай:

У нас гетерогенная сеть из разных вендоров.
Также есть часть устройств, от которых мы должны принимать сообщения, которые принадлежат сторонней компании/подразделению.

Предположим, у нас есть основная группа коммутаторов и маршрутизаторов, на которых задан SNMP v3 пользователь snmpuser с протоколом аутентификации SHA и протоколом шифрования AES-128.

Также есть группа устаревшего оборудования, которое поддерживает только протоколы MD5 и DES, на нем мы настроили того же пользователя snmpuser, но с протоколами MD5/DES.

Есть оборудование доступное только через внешние каналы, на нем мы настроили пользователя snmpuser256256, с протоколами sha256/aes256a.

И есть стороннее оборудование, администрируемое не нами, нам передали адреса оборудования и имя пользователя, пароли и протоколы.

Что же может пойти не так?

В случае опроса ничего, мы просто настраиваем нужные учетные данные и протоколы для групп устройств, и все.

В случае же приема трапов, если приемник один, то он должен принимать, аутентифицировать и расшифровать тот или иной трап.

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

Многие опираются на уникальный Engine ID но это не очень удобно использовать.

Некоторые реализации приемников трапов, подбирают подходящие данные из тех что заданы администратором, для дешифровки полученного сообщения, что вполне рабочий метод, но не самый эффективный.

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

Теперь поговорим про Inform.

Первая сложность — это настроить его отправку с устройства, но этого мы слегка коснемся чуть позже.

Вторая сложность это если на агенте не указан Engine ID сервера, то некоторые агенты так попросту не работают, а некоторые попробуют определить Engine ID сервера, отправив ему запрос с пустым Engine ID, на что сервер ответит сообщением Report с указанием того, что он получил запрос с неверным Engine ID и заполненным правильным Engine ID а также временем работы и количеством перезагрузок.
Получив такой Report, агент отправит уже валидный Inform и дождется подтверждения от сервера что тот его получил.

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

Теперь перейдем к тому, как я решил большую часть этих проблем:

Приемник трапов/информов, при приеме трапа, сначала разбирает только незашифрованную часть сообщения с именем пользователя, Engine ID и еще некоторой информацией.

Затем ищет есть ли у него все параметры для того, чтоб его расшифровать.

Причем ищет сначала с учетом адреса от кого оно получено, и если такого нет, то только по имени.

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

Если все параметры найдены, производится попытка аутентификации и дешифровки.
Если все успешно, то производится запись данных, например в файл для Zabbix.

Если же это был Inform, то после успешной расшифровки будет отправлено подтверждение приема.

Если же это попытка определить наш Engine ID, то будет отправлен Report с нашим Engine ID.

Я выложил демонстрационный приемник тут: https://github.com/OlegPowerC/zabbixtraps
На нем и продемонстрирую возможности.

Нужно заполнить файл settings.json необходимыми данными.
У меня он выглядит вот так:

    {
    "logfile": "snmptrap.log",
    "timezone": "Europe/Moscow",
    "debugmode": true,
    "users": [
        {
        "username": "snmpuser",
        "authproto": "sha",
        "privproto": "aes",
        "auth": "auth12345",
        "priv": "priv12345"
        },
        {
        "username": "testuser1",
        "authproto": "sha",
        "privproto": "aes",
        "auth": "auth12345",
        "priv": "priv12345"
        },
        {
        "username": "testuser1",
        "authproto": "md5",
        "privproto": "aes256a",
        "auth": "authmd512345",
        "priv": "privdes12345",
        "ipaddr": "192.168.0.106"
        },
        {
        "username": "snmpuser192",
        "authproto": "sha",
        "privproto": "aes192a",
        "auth": "auth12345",
        "priv": "priv19212345"
        },
        {
        "username": "snmpuser256256",
        "authproto": "sha256",
        "privproto": "aes256a",
        "auth": "auth25612345",
        "priv": "priv25612345"
        }
    ]
}

Теперь проведем тест.

В качестве подопытного коммутатора выступит Cisco Catalyst IE-3000-8TC.

Работать мы будем с адресами IPv6.

На ПК настроен адрес 2001:DB8:1::121/64
На тестовом коммутаторе 2001:DB8:1::120/64

Настроим на нем отправку Inform и включим трапы:

Первое что нам нужно это настроить view, группу и пользователя:

snmp-server view SNMPv3-V iso included  
snmp-server group SNMPv3-G v3 priv read SNMPv3-V notify SNMPv3-V  

Теперь важно указать remote engineid с адресом нашего приемника, так как Cisco отправляет inform сразу, не делая discovery процедуру.

snmp-server engineID remote 2001:DB8:1::121 800000090300682C7B370001  

Engine ID 800000090300682C7B370001 взят для примера

И создадим пользователя, для inform необходимо создавать его вот так:

snmp-server user snmpuser SNMPv3-G remote 2001:DB8:1::121 v3 auth sha auth12345 priv aes 128 priv12345  

То есть с указанием удаленного узла на который будут отправлены Trap/Inform сообщения.

Однако традиционным методом, пользователя тоже надо создать, но при этом можно задавать разные параметры аутентификации и шифрования.

Для примера мы намеренно так и сделаем:

snmp-server user snmpuser SNMPv3-G v3 auth md5 authmd12345 priv des privdes12345  

Теперь нужно включить трапы (это относится как к трапам так и сообщениям информ)

snmp-server enable traps  

И указать, куда и от какого пользователя слать inform

snmp-server host 2001:DB8:1::121 informs version 3 priv snmpuser  

А все вместе выглядит так:

snmp-server view SNMPv3-V iso included
snmp-server group SNMPv3-G v3 priv read SNMPv3-V notify SNMPv3-V
snmp-server engineID remote 2001:DB8:1::121 800000090300682C7B370001
snmp-server user snmpuser SNMPv3-G remote 2001:DB8:1::121 v3 auth sha auth12345 priv aes 128 priv12345
snmp-server user snmpuser SNMPv3-G v3 auth md5 authmd12345 priv des privdes12345
snmp-server host 2001:DB8:1::121 informs version 3 priv snmpuser
snmp-server enable traps

Теперь посмотрим пользователей snmp командой show snmp user:

    User name: snmpuser
    Engine ID: 800000090300682C7B370001
    storage-type: nonvolatile        active
    Authentication Protocol: SHA
    Privacy Protocol: AES128
    Group-name: SNMPv3-G

    User name: snmpuser
    Engine ID: 800000090300C07BBCF9BB03
    storage-type: nonvolatile        active
    Authentication Protocol: MD5
    Privacy Protocol: DES
    Group-name: SNMPv3-G

И изменим количество повторных посылок, таймауты и количество сообщений в очереди:

snmp-server inform retries 10 timeout 30 pending 1000

Выходим в exec режим и смотрим что у нас происходило:

show snmp И смотрим самую нижнюю секцию:

SNMP informs: enabled
    Informs in flight 0/1000 (current/max)
    Logging to 2001:DB8:1::121.162
        1 sent, 0 in-flight, 0 retries, 0 failed, 0 dropped

Видим, что пока мы конфигурировали повторы, один inform был успешно отправлен.
Смотрим в консоль приемника и видим:

received trap/inform version: 3 User/Community snmpuser
Source IP: [2001:db8:1::120]:55259
Message Type: INFORM (send ACK)
RequestID:    1
VarBinds:     5
Boots: 0, Time: 0, EngineID 800000090300682c7b370001
Auth protocol: sha
Priv protocol: aes
Authenticated message
Encrypted message
Message to file: 05-26-26 11:21:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
1.3.6.1.2.1.1.3.0 = 31m14.94s : TIMETICKS
1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.9.9.43.2.0.1 : Universal OID
1.3.6.1.4.1.9.9.43.1.1.6.1.3.4 = 1 : Universal INTEGER
1.3.6.1.4.1.9.9.43.1.1.6.1.4.4 = 2 : Universal INTEGER
1.3.6.1.4.1.9.9.43.1.1.6.1.5.4 = 3 : Universal INTEGER

Это сообщение говорит о том, что изменился running конфиг.

А теперь перейдем к тестированию самого интересного, повторных посылок, когда наш приемник по каким-то причинам недоступен.

У меня к тестируемому коммутатору подключен ПК, сейчас порт поднят:

Fa1/7                        connected    1          a-full  a-100 10/100BaseTX

Мы его отключим, когда приемник будет недоступен, и проверим получим ли мы информацию о том, что этот порт упал, после того как приемник восстановится:

Запускаем WireShark, включаем фильтр snmp и останавливаем приемник.

Вынимаем кабель из порта и смотрим в Wireshark а также вводим в консоль команду show snmp pending

Также вводим show snmp и смотрим нижнюю секцию:

SNMP informs: enabled
    Informs in flight 3/1000 (current/max)
    Logging to 2001:DB8:1::121.162
        4 sent, 3 in-flight, 0 retries, 0 failed, 0 dropped

Запускаем приемник и наблюдаем, как приходят сообщения:

    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    10
    VarBinds:     3
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 11:55:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 1h3m41.28s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.2.1.17.0.1 : Universal OID
    1.3.6.1.4.1.9.9.46.1.3.1.1.1.1.1 = 1 : Universal INTEGER

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    11
    VarBinds:     6
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 11:57:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 1h3m7.28s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.3 : Universal OID
    1.3.6.1.2.1.2.2.1.1.10007 = 10007 : Universal INTEGER
    1.3.6.1.2.1.2.2.1.2.10007 = FastEthernet1/7 : Universal OCTET STRING
    1.3.6.1.2.1.2.2.1.3.10007 = 6 : Universal INTEGER
    1.3.6.1.4.1.9.2.2.1.1.20.10007 = down : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    12
    VarBinds:     7
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 11:57:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 1h3m8.28s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.9.9.41.2.0.1 : Universal OID
    1.3.6.1.4.1.9.9.41.1.2.3.1.2.3 = LINK : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.3.3 = 4 : Universal INTEGER
    1.3.6.1.4.1.9.9.41.1.2.3.1.4.3 = UPDOWN : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.5.3 = Interface FastEthernet1/7, changed state to down : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.6.3 = 1h3m8.28s : TIMETICKS

Что же мы наблюдаем в Wireshark:

WireShrkInform1.jpg
WireShrkInform1.jpg

На скриншоте хорошо видны попытки доставить Inform сообщения, и завершение попыток после получения подтверждения о приеме от сервера.

А теперь сделаем более экстремальный тест.
Отключим единственный кабель, который соединяет коммутатор с остальной сетью.
В Wireshark, разумеется, мы уже ничего не увидим до момента восстановления связи.

В консоли коммутатора (разумеется, в тестовой среде мы подключены к нему по серийному порту) видим сообщение:

*Mar  1 07:08:53.924: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan1, changed state to down
*Mar  1 07:08:54.923: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet1/5, changed state to down
*Mar  1 07:08:55.921: %LINK-3-UPDOWN: Interface FastEthernet1/5, changed state to down

посмотрим что коммутатор пытается отправить show snmp pending

req id: 137, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 16 secs
req id: 138, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 16 secs
req id: 139, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 17 secs
req id: 140, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 18 secs

Так же можно посмотреть show snmp:

    SNMP informs: enabled
        Informs in flight 4/1000 (current/max)
        Logging to 2001:DB8:1::121.162
            48 sent, 4 in-flight, 92 retries, 0 failed, 0 dropped

Со временем сообщений которые находятся “в полете” станет немного больше, спустя две с половиной минуты видим такое:

req id: 145, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 13 secs
req id: 146, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 13 secs
req id: 147, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 14 secs
req id: 148, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 15 secs
req id: 151, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 23 secs
req id: 152, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 23 secs
req id: 153, dest: 2001:DB8:1::121.162, V3 user: snmpuser, Expires in 55 secs
    SNMP informs: enabled
    Informs in flight 7/1000 (current/max)
    Logging to 2001:DB8:1::121.162
        52 sent, 7 in-flight, 93 retries, 0 failed, 0 dropped

Подключаем кабель обратно, и спустя некоторое время принимаем информ сообшения с request id со 153 по 161:

WireShrkInform2.jpg
WireShrkInform2.jpg
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [fe80::c27b:bcff:fef9:bb40%Ethernet]:55259
    Message Type: INFORM (send ACK)
    RequestID:    153
    VarBinds:     7
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP fe80::c27b:bcff:fef9:bb40 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h11m35.15s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.9.9.41.2.0.1 : Universal OID
    1.3.6.1.4.1.9.9.41.1.2.3.1.2.15 = LINK : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.3.15 = 4 : Universal INTEGER
    1.3.6.1.4.1.9.9.41.1.2.3.1.4.15 = UPDOWN : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.5.15 = Interface FastEthernet1/5, changed state to up : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.6.15 = 7h11m35.15s : TIMETICKS

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    154
    VarBinds:     6
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h11m36.16s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.4 : Universal OID
    1.3.6.1.2.1.2.2.1.1.10005 = 10005 : Universal INTEGER
    1.3.6.1.2.1.2.2.1.2.10005 = FastEthernet1/5 : Universal OCTET STRING
    1.3.6.1.2.1.2.2.1.3.10005 = 6 : Universal INTEGER
    1.3.6.1.4.1.9.2.2.1.1.20.10005 = up : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    155
    VarBinds:     4
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h8m53.92s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.2.1.17.0.2 : Universal OID
    1.3.6.1.4.1.9.9.46.1.3.1.1.1.1.1 = 1 : Universal INTEGER
    1.3.6.1.2.1.31.1.1.1.1.10005 = Fa1/5 : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    156
    VarBinds:     6
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h8m53.93s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.3 : Universal OID
    1.3.6.1.2.1.2.2.1.1.1 = 1 : Universal INTEGER
    1.3.6.1.2.1.2.2.1.2.1 = Vlan1 : Universal OCTET STRING
    1.3.6.1.2.1.2.2.1.3.1 = 53 : Universal INTEGER
    1.3.6.1.4.1.9.2.2.1.1.20.1 = down : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    157
    VarBinds:     6
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h8m54.92s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.3 : Universal OID
    1.3.6.1.2.1.2.2.1.1.10005 = 10005 : Universal INTEGER
    1.3.6.1.2.1.2.2.1.2.10005 = FastEthernet1/5 : Universal OCTET STRING
    1.3.6.1.2.1.2.2.1.3.10005 = 6 : Universal INTEGER
    1.3.6.1.4.1.9.2.2.1.1.20.10005 = down : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    158
    VarBinds:     7
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h8m55.92s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.9.9.41.2.0.1 : Universal OID
    1.3.6.1.4.1.9.9.41.1.2.3.1.2.14 = LINK : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.3.14 = 4 : Universal INTEGER
    1.3.6.1.4.1.9.9.41.1.2.3.1.4.14 = UPDOWN : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.5.14 = Interface FastEthernet1/5, changed state to down : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.6.14 = 7h8m55.92s : TIMETICKS

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    159
    VarBinds:     4
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h12m3.16s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.2.1.17.0.2 : Universal OID
    1.3.6.1.4.1.9.9.46.1.3.1.1.1.1.1 = 1 : Universal INTEGER
    1.3.6.1.2.1.31.1.1.1.1.10005 = Fa1/5 : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    160
    VarBinds:     6
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:02:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h12m3.17s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.4 : Universal OID
    1.3.6.1.2.1.2.2.1.1.1 = 1 : Universal INTEGER
    1.3.6.1.2.1.2.2.1.2.1 = Vlan1 : Universal OCTET STRING
    1.3.6.1.2.1.2.2.1.3.1 = 53 : Universal INTEGER
    1.3.6.1.4.1.9.2.2.1.1.20.1 = up : Universal OCTET STRING

    ----------------------------------------------------------
    ----------------------------------------------------------
    received trap/inform version: 3 User/Community snmpuser
    Source IP: [2001:db8:1::120]:55259
    Message Type: INFORM (send ACK)
    RequestID:    161
    VarBinds:     7
    Boots: 0, Time: 0, EngineID 800000090300682c7b370001
    Auth protocol: sha
    Priv protocol: aes
    Authenticated message
    Encrypted message
    Message to file: 05-26-26 18:03:05 ZBXTRAP 2001:db8:1::120 VARBINDS:
    1.3.6.1.2.1.1.3.0 = 7h11m35.15s : TIMETICKS
    1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.9.9.41.2.0.1 : Universal OID
    1.3.6.1.4.1.9.9.41.1.2.3.1.2.15 = LINK : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.3.15 = 4 : Universal INTEGER
    1.3.6.1.4.1.9.9.41.1.2.3.1.4.15 = UPDOWN : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.5.15 = Interface FastEthernet1/5, changed state to up : Universal OCTET STRING
    1.3.6.1.4.1.9.9.41.1.2.3.1.6.15 = 7h11m35.15s : TIMETICKS

    ----------------------------------------------------------

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

Коммутатор отправил первое сообщение о том что порт поднялся, еще и с адреса Link Local.
При этом у всех сообщений разные и MsgID и request-id.
Это специфический для нашего лабораторного теста случай, связано это с тем, что на тестовом коммутаторе упали вообще все порты, и соответственно упал интерфейс Vlan 1, на котором был настроен адрес 2001:DB8:1::120/64.
После того как интерфейс поднялся, ему автоматически назначается Link Local адрес, а затем присваивается адрес, назначенный в конфигурации, но за это время он успел отправить с него Inform.

В реальной жизни все порты вряд ли упадут и SVI менеджмент интерфейс скорее всего будет в рабочем состоянии, но я специально не стал повторять тест с непадающим SVI, дабы затронуть вот какой вопрос:

Как понять что произошло раньше а что позже, опираться на порядок пришедших сообщений ненадежно?

Для начала стоит порадоваться, что мы получили лишнее сообщение, а не потеряли что-то, а во-вторых каждый Trap/Inform обязательно содержит данные о времени работы оборудования с момента включения:

    1.3.6.1.2.1.1.3.0 = 7h11m35.15s : TIMETICKS

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

Статья получилась довольно длинная поэтому тут я очень коротко приведу пример настройки Zabbix исключительно для демонстрации.

Демонстрационный пример Host+Items+Trigger в Zabbix

Итак настраиваем Zabbix на обработку трапов, в файле zabbix_server.conf необходимо указать:
StartSNMPTrapper=1

И путь к файлу, из которого траппер будет извлекать новые сообщения:
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log

Файл /var/log/snmptrap/snmptrap.log необходимо создать, а также разрешить заббиксу его читать, а нашему сервису в него писать.

Смотрите лог zabbix_server.log заббикса на предмет сообщений об ошибках доступа к файлу:

cannot open SNMP trapper file "/var/log/snmptrap/snmptrap.log": [13] Permission denied

Поскольку это тестовая ВМ, то сервис принимающий трапы запущен от root что, разумеется, на рабочем сервере делать не желательно, но в моем случае, в тестовом окружении это так, да еще и к тому же selinux отключен.

Права на файл:
-rw-r-----. 1 root zabbix 23K May 27 20:49 snmptrap.log

В качестве тестового коммутатора выступит 2960X с примерно такими же настройками как и выше описаны, за исключением того, что он у меня доступен только по IPv4.

Описывать как создать Host, Item и Trigger я не буду, это широко освещено, а опишу специфичные items для трапов.

Прежде всего надо понимать, что для Zabbix, трап сообщение это просто много текста. Соответственно его нужно распарсить и как-то обработать.

Прежде всего создадим Item типа SNMP trap, дадим ей key snmptrap.fallback а в поле Type of information укажем log.
Сюда будут попадать все трапы, для этого хоста, которые не попадают в другие items.

Можем отключить/подключить что-нибудь подключенное к коммутатору и проверить, появились ли сообщения, на скриншоте мой тестовый пример:

trapfallback.jpg
trapfallback.jpg

Теперь создадим item для того чтобы ловить состояние интерфейса, а именно GigabitEthernet1/0/23.

Тут надо сразу пояснить одну неприятную штуку, а имено то, что Cisco не присылает в трапе ifOperStatus, например, для нашего порта OID для получения состояния порта 1.3.6.1.2.1.2.2.1.8.10123 и было бы чудесно видеть в трапе что-то типа 1.3.6.1.2.1.2.2.1.8.10123 = 2 но увы.
Но мы можем ориентироваться по сообщению с OID 1.3.6.1.4.1.9.2.2.1.1.20 это причина изменения состояния порта, к сожалению это строка.

Итак создаем item для поимки именно таких трапов:
Название дадим например GigabitEthernet1/0/23_Inform
Тип - SNMP trap
А вот в поле Key нужно указать regex:
snmptrap[1\.3\.6\.1\.4\.1\.9\.2\.2\.1\.1\.20\.10123]
Это означает, что в этот item попадет сообщение целиком, в котором будет найдена строка 1.3.6.1.4.1.9.2.2.1.1.20.10123

item02.jpg
item02.jpg

Именно такие сообщения нам и понадобятся, а подсмотреть все сообщение можно в логе, пример:

05-27-26 19:06:05 ZBXTRAP 192.168.0.121 VARBINDS:
1.3.6.1.2.1.1.3.0 = 41h1m44.59s : TIMETICKS
1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.6.3.1.1.5.3 : Universal OID
1.3.6.1.2.1.2.2.1.1.10123 = 10123 : Universal INTEGER
1.3.6.1.2.1.2.2.1.2.10123 = GigabitEthernet1/0/23 : Universal OCTET STRING
1.3.6.1.2.1.2.2.1.3.10123 = 6 : Universal INTEGER
1.3.6.1.4.1.9.2.2.1.1.20.10123 = down : Universal OCTET STRING

Однако нужно из него выбрать только значение OID 1.3.6.1.4.1.9.2.2.1.1.20.10123 и тут на помощь придет Processing.
Создаем в нем регулярное выражение:

.*1\.3\.6\.1\.4\.1\.9\.2\.2\.1\.1\.20\.10123\s*=\s*([a-zA-Z]+)\s*:\s*Universal OCTET STRING.*

Оно выбирает только результат - то есть up или down.
В поле output - \1

item2.jpg
item2.jpg

Нажимаем Test и в поле Value вставляем сообщение из лога, жмем apply и test.
Для выше приведенного сообщения, результат должен быть - down

ir01.jpg
ir01.jpg

Теперь можем подергать интерфейс, History latest data нашего item должна содержать изменение состояния up/down примерно так:

ldata.jpg
ldata.jpg

А теперь дело за триггером, но для того чтоб ориентироваться не только по трапу, я создал еще один item, который опрашивает состояние порта с интервалом 10 минут.
Хотелось, чтобы триггер был один, поэтому настроил его на два item с операцией OR:

last(/2960Xlab/snmp_oid["1.3.6.1.2.1.2.2.1.8.10123"])<>1 or last(/2960Xlab/snmptrap[1\.3\.6\.1\.4\.1\.9\.2\.2\.1\.1\.20\.10123])="down"

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

dsb1.jpg
dsb1.jpg

Заключительное слово

Читатель наверное подумает, зачем такие сложности ради состояния порта и будет прав.
Это всего лишь демонстрация того как можно работать с трапами и информами.
Разумеется и приемник требует доработки и испытаний, и конфигурация Zabbix и выбор объектов к которым применить данный метод, однако же был бы метод, а применение найдется.

За сим позвольте откланяться.

Комментарии (0)