Мониторинг Событий Portsecurity Коммутаторов Cisco В Zabbix

Здравствуйте, уважаемое хабро-сообщество! Решил выплеснуться в онлайн.

собственный решения, которые облегчают деятельность сетевых специалистов и других ИТ-собратьев.

В этой статье мы поговорим о мониторинге событий стандартного (для многих производителей) механизма защиты от несанкционированного подключения устройств к сети - механизма ПортБезопасность .

Решение изначально создавалось для коммутаторов от компании Циско , но при желании его легко можно добавить к любому коммутатору и к любым событиям на основе SNMP-ловушек.

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

Технологии ПортБезопасность работает на основе MAC-адресов.

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

Существует три типа режима блокировки:

  1. неисправность - выключить порт + snmp-ловушка
  2. ограничивать — ограничение входящего трафика с неизвестного Mac+ snmp-ловушка
  3. защищенный — ограничение входящего трафика с неизвестного Mac молча, без ловушка -А.

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

Система мониторинга, как следует из названия – Заббикс .

Поддержка трапа Заббикс Вроде есть, но я так и не научился им пользоваться.

В итоге я принял свое решение, которое меня полностью устраивает. Собственно, всё решение представляет собой довольно простой обработчик скриптов ( обработчик ловушек ) для пары конкретных SNMP - лестницы Обработчик написан, естественно, на питон и вызывается стандартным демоном snmptrapd .

Код обработчика размещен по адресу github .

Краткий теоретический экскурс окончен, перейдем к конкретике.

Механизм мониторинга построен и работает по следующей цепочке:

[1. Коммутатор Cisco] → [2. демон snmptrapd] → [3. сценарий] → [4. Забфикс]
Остальная часть истории будет следовать в том же порядке.



1. Циско

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

snmp-server enable traps port-security snmp-server enable traps errdisable snmp-server host 10.1.0.1 version 2c public

Здесь настраиваем его отдельно для каждого порта ПортБезопасность .

В примере ниже ПортБезопасность настроен в режиме гибридного порта компьютер+телефон .

Поэтому максимальное количество указанных маков – два.

Режим блокировки ограниченный

switchport port-security maximum 2 switchport port-security switchport port-security violation restrict switchport port-security mac-address sticky switchport port-security mac-address sticky 1111.11co.ffee vlan access switchport port-security mac-address sticky 0000.0000.beef vlan voice

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

Если причина не исчезла, после каждой попытки автовосстановления будет отправляться новая ловушка.



errdisable recovery cause psecure-violation errdisable recovery interval 300

Вот и все, что касается переключателя.

Подробнее о том, как настроить PortSecutity, вы можете прочитать по ссылкам



2. снмптрапд

snmptrapd стандартная услуга по обработке SNMP - лестницы.

В Ubuntu устанавливается командой

> sudo apt install snmptrapd

конфигурация настраивается в файле /etc/snmp/snmptrapd.conf Каждый тип ловушки уникален как для разных вендоров, так и для разных типов блокировки (restricted|shutdown).

Мы остановимся на двух конкретных:

  1. CISCO-ERR-DISABLE-MIB::cErrDisableInterfaceEvent (1.3.6.1.4.1.9.9.548.0.1.1) — ловушка отправляется в режиме завершения работы
  2. ciscoPortSecurityMIB::cpsSecureMacAddrViolation (1.3.6.1.4.1.9.9.315.0.0.1) — ловушка отправляется в ограниченном режиме
В файле конфигурации демона snmptrapd /etc/snmp/snmptrapd.conf напишем следующие строки:

authCommunity log,execute,net public traphandle .

1.3.6.1.4.1.9.9.315.0.0.1 /etc/zabbix/externalscripts/traphandlers/cisco-psec-traphandler.py traphandle .

1.3.6.1.4.1.9.9.548.0.1.1 /etc/zabbix/externalscripts/traphandlers/cisco-psec-traphandler.py

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

315 И 548 .



3. сценарий

Здесь я последовательно опишу логику написания скрипта, руководствуясь которым можно будет по аналогии написать другие обработчики (трафандлеры) для других типов ловушек и/или устройств.

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

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

config.ini .

Кстати, начнём, наверное, с Configuration.ini. Для простоты сразу представлю его содержание

[snmp] community = public [api] zabbix_url = https://zabbix.acme.loc zabbix_user = api_ro zabbix_passwd = neskazhu [zabbix] server = 10.1.1.1 port = 10051 zabbix_sender = /usr/bin/zabbix_sender #the predefined keyname of an item that has to be created for a given host in Zabbix trapkeyname_disable = ErrDisable trapkeyname_restrict = ErrRestrict [logging] logfile = /var/log/cisco-errdisable-traphandler.log loglevel = INFO

Мне кажется, конфиг достаточно прозрачен для понимания.

Здесь мы устанавливаем snmp-community, уровень логирования и параметры доступа к серверу.

Заббикс через Забфикс_API И zabbix_sender .

Единственный, пожалуй, непонятный момент – это параметры Trapskeyname_disable И Trapskeyname_restrict .

Значит эти параметры соответствуют лестницам 548 И 315 и определите ключевые имена для Предметы (элементы данных) в Заббикс .

Вперед, продолжать.

Как уже говорилось выше, наш обработчик принимает на вход два типа ловушек: 315 И 548 .

В коде они отличаются вот этим элементарным условием:

if "548.0.1.1" in trapstr: mode = "disable" trapkeyname = "trapkeyname_disable" elif "315.0.0.1" in trapstr: mode = "restrict" trapkeyname = "trapkeyname_restrict" else: logging.error("Unknown trap. Discarding .

") exit(1)

Далее скрипт переходит к Заббикс с использованием Забфикс_API чтобы по названию или адресу свитча узнать, ведем ли мы в принципе мониторинг трапов с этого свитча.

Здесь используется модуль ЗабфиксAPI и еще пара способов хост.get И элемент.получить .

Ничего сложного.

Перейдем к разбору ловушек.

Интересно, что структура наших двух лестниц радикально отличается.

Смотри сюда Пример лестницы 548:

switch-20 UDP: [0.0.0.0]->[192.168.99.20]:-2039 DISMAN-EVENT-MIB::sysUpTimeInstance 338:5:51:38.08 SNMPv2-MIB::snmpTrapOID.0 CISCO-ERR-DISABLE-MIB::cErrDisableInterfaceEvent cErrDisableIfStatusCause.10640.0 9

А это типичная лестница 315:

switch-27 UDP: [0.0.0.0]->[192.168.99.27]:-13209 DISMAN-EVENT-MIB::sysUpTimeInstance 342:22:17:16.63 SNMPv2-MIB::snmpTrapOID.0 CISCO-PORT-SECURITY-MIB::cpsSecureMacAddrViolation IF-MIB::ifIndex.10028 10028 IF-MIB::ifName.10028 FastEthernet0/28 CISCO-PORT-SECURITY-MIB::cpsIfSecureLastMacAddress.10028 0:22:55:88:ee:dd

Кстати, вышеприведенные лестницы я изобразил в человекочитаемом формате.

Фактически ловушки поступают на вход скрипта в формате АСН.

1 , который выглядит совершенно иначе.

И именно с этим сырым форматом мы и будем работать.

Вот как выглядят те же лестницы в необработанном виде: Лестница 548:

iso.3.6.1.2.1.1.3.0 21:19:06.72 iso.3.6.1.6.3.1.1.4.1.0 iso.3.6.1.4.1.9.9.548.0.1.1 iso.3.6.1.4.1.9.9.548.1.3.1.1.2.10640.0 9

Лестница 315:

iso.3.6.1.2.1.1.3.0 342:22:17:16.63 iso.3.6.1.6.3.1.1.4.1.0 iso.3.6.1.4.1.9.9.315.0.0.1 iso.3.6.1.2.1.2.2.1.1.10028 10028 iso.3.6.1.2.1.31.1.1.1.1.10028 "FastEthernet0/28" iso.3.6.1.4.1.9.9.315.1.2.1.1.10.10028 "00 22 55 88 EE DD "

Формат АСН.

1 , хотя он и относится к структурированным, работать с ним далеко не так удобно, как с JSON или xml .

Просто так с помощью ключа вытащить нужную информацию не получится.

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

Не очень современно конечно, ну да ладно SNMP это долгое наследие.

Может быть гНМИ спасет нас всех.

Тогда мы сделаем это красиво.

Вернемся к нашим овцам.

Из приведенных лестниц видно, что в случае лестницы 315 мы легко можем узнать номер порта и даже MAC-адрес, вызвавший триггер безопасность порта .

И мы, конечно, это сделаем.

Но с 548 - все сложнее.

Здесь нам доступно только имя свитча (switch-20) (кстати, оно не сохранится, если пробросить лестницу на другой хост по инструкции вперед В snmptrapd ), и вместо имени заблокированного интерфейса мы имеем только его индекс — SNMP еслииндекс .

Индекс содержится в последней строке нашей лестницы iso.3.6.1.4.1.9.9.548.1.3.1.1.2.10640.0 9 и равен числу 10640 Чтобы из еслииндекс чтобы получить имя порта свитча, нужно обратиться к самому свитчу с помощью SNMP .

За это отвечает отдельная функция в скрипте.

find_ifDesc_from_ifIndex() .

И, конечно же, коммутатор должен быть настроен на прием SNMP с нашего хоста и с тем snmp-сообществом, которое прописано там же config.ini .

Окончательный код анализа наших ловушек выглядит так:

if mode is "disable": trapvalue = traplist[-2] ifIndex = trapvalue.split(".

")[-2] ifName = find_ifDesc_from_ifIndex(ip, ifIndex, snmp_config['community']) elif mode is "restrict": ifName = traplist[7].

strip('"') mac = ':'.

join(traplist[-7:-1]).

strip('"')

В результате мы имеем один из двух наборов данных

  1. (имя переключателя, имя интерфейса, тип ловушки)
  2. (имя коммутатора, имя интерфейса, MAC-адрес, тип релейной схемы)
И эти данные необходимо передать Заббикс -у.

Почему-то архитекторы Заббикс не разрешать внедрение данных в систему с помощью API .

Единственный (на момент написания скрипта, но я его написал уже давно) способ поместить туда произвольные данные - использовать zabbix_sender .

zabbix_sender для необходимого имя хоста передает ключ:значение пара где ценить — это те же данные, которые мы подготовили, и в качестве ключа необходимо указать заранее заданное имя ключа для элементов данных в Заббикс .

И именно это самое имя нужно написать в config.ini для параметров ловушка_имя_х .

Как ценить передается имя интерфейса или строка, состоящая из имени интерфейса и MAC-адреса.



Установка скрипта
Скрипт может быть где угодно.

Он запускается демоном snmptrapd и чтобы Заббикс никак не привязан.

Но лично я держу это в себе.

/etc/zabbix/external-скрипты просто потому, что «почему бы и нет».

Для работы скрипта необходим ряд модулей, которые указаны в файле require.txt. Чтобы установить необходимые модули, достаточно выполнить команду:

sudo -H pip install -r requirements.txt

Также необходимо иметь утилиту zabbix_sender .

В моем любимом Убунту он поставляется в отдельной упаковке, которая называется zabbix-отправитель , но с дефисом вместо подчеркивания.

Ну, это так.

sudo apt установить zabbix-sender

4. Забфикс

В Заббикс для каждого коммутатора, от которого мы хотим получать ловушки, нам необходимо создать элементы данных (Items) и по одному триггеру для каждого ловушки.

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

Но вам не о чем беспокоиться.

Готовый шаблон с этими компонентами уже есть в репозитории вместе с кодом.

Также в Zabbix нужно создать специального пользователя, от имени которого будет взаимодействовать скрипт. Заббикс через API .

Подойдет простой пользователь с правами только чтения для группы с переключателями и без доступа к Frontend. Результат будет выглядеть примерно так:

Мониторинг событий PortSecurity коммутаторов Cisco в Zabbix

те.

хорошо видно, что на переключателе с именем катализатор100 порт заблокирован Фа0/2 левый mac-адрес 00:22:55:Д4:3Ф:51 Здесь, кстати, пригодится один грязный хак.

По неизвестной причине в интерфейсе Заббикс , в виджете «Проблемы» для одноименного поля установлено ограничение в 20 символов на длину строки значения триггера.

Но один только мак-адрес занимает 17 символов, а с именем интерфейса минимум 23. В общем, для полной красоты это ограничение нужно изменить.

Он находится в файле:

$ZABBIX_FRONTEND_HOME/include/items.inc.php

Найдите этот фрагмент:

switch ($item['value_type']) { case ITEM_VALUE_TYPE_STR: $mapping = getMappedValue($value, $item['valuemapid']); // break; is not missing here case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_LOG: if ($trim && mb_strlen($value) > 20) { $value = mb_substr($value, 0, 20).

'.

'; }

А затем настройте обе 20-ки.

Я установил значение 30. Теперь оно выглядит красиво.

Вот, пожалуй, и все.

Готов ответить на вопросы в комментариях.

п.

с.

Я хочу поделиться одной особенностью Zabbix, которая называется теги .

Наверное многие в курсе, но многим просто не интересно, поэтому скрыл: теги забфикса Посмотрите, как я настраиваю Действия:

Мониторинг событий PortSecurity коммутаторов Cisco в Zabbix

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

Или два.

Самое удобное, чего мне очень не хватало раньше.

п.

п.

с.

Вторая часть статьи готова.

Разблокировка заблокированных портов из интерфейса Zabbix Теги: #*nix #cisco #cisco #python #Системное администрирование #zabbix

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.