четверг, 31 декабря 2015 г.

Итоги 2015

Ну, что же, год закончен, значит надо подвести кое-какие итоги. Всегда было интересно, какие из заметок этого блога наиболее популярны. Вот ТОП-15 самых читаемых статей:

Полезные OID для получения информации о состоянии портов по SNMP
Проблема "конфликт hash" на сетевых коммутаторах
Последствия конфликта MAC-адресов
Перезагрузка коммутаторов по SNMP
Некоторые факты о диагностике кабеля
Сброс пароля и загрузочное меню
Планирование перезагрузки DES-3200-28/C1 по SNMP
Работа с конфигурацией и лог-файлами коммутатора по SNMP
Сохранение конфигурации коммутаторов по SNMP
Значения счетчиков ошибок
Разработка ACL для DES-3200-28/C1
Чтение информации о VLAN по SNMP
Примеры ACL для DES-3200-28/C1
Ingress Checking и LLDP
SWToolz - 5 лет!

Пусть статистика не совсем объективна, т.к. при подсчете не учитывалось "время жизни" статьи, но общие тенденции ясны. Можно выделить самые популярные темы:
  • Поиск OID для самых разных случаев
  • Проблема конфликта MAC-адресов
  • Сброс пароля и получение доступа к коммутатору
  • Перезагрузка и сохранение конфигурации по SNMP
  • Примеры ACL для ревизии C1
Интересное получается наблюдение - чем проще задача, тем более востребовано ее решение. А вот QoS, извращения с ACL, автоматизация массовых операций и прочие хитрые трюки интересны значительно меньшему количеству читателей. Но посмотрим, что покажет следующий год. :)

p.s. Приятно видеть, что swtoolz таки попал в топ, пусть и на последнее место. Кстати, в следующем месяце он вернется к нам, правда уже в несколько ином качестве. :)

четверг, 24 декабря 2015 г.

Дополнение к заметкам про QoS

За последние полгода понафлудил где мог своими соображениями насчет QoS в D-Link. Предыдущие заметки можно прочитать тут, тут и тут, а также на нескольких профильных форумах (пример). В связи с вновь открывшимися обстоятельствами я приблизился к просветлению еще на один шаг, и потому обновил свою заметку про QoS и iperf. Кому лень перечитывать, в нескольких словах суть такова:
  • Iperf не способен забить канал также легко и непринужденно, как это делает торрент. Поэтому QoS надо проверять совместно с торрентом. Проще всего это сделать на MPEG TS, отлавливая нарушения последовательности continuity counter.
  • На DGS-3100-24TG QoS работает как задумано, по крайней мере на небольших нагрузках. По умолчанию коммутатор "смотрит" на раскраску DSCP.
  • На DES-3200-xx/C1 QoS также работает прекрасно. Есть некоторые интересные особенности, которые описал в конце статьи.
В общем, на данный момент со всем разобрались. Это радует. :)


пятница, 11 декабря 2015 г.

Работа scheduling mechanism на разных моделях

Проверили на стенде работу scheduling mechanism. Результаты достаточно интересные. Если в двух словах, то настройки QoS позволяют распределять трафик по разным очередям (подробнее см. тут). Scheduling mechanism определяет, как коммутатор будет эти очереди опустошать:
При использовании строгого режима (Strict mode) обработки очередей пакеты из очереди высшего приоритета всегда обслуживаются первыми. Опустошение очередей происходит, строго следуя их приоритетам. Только тогда, когда очередь более высокого приоритета пуста, обслуживаются пакеты с более низким приоритетом.

В случае использовании взвешенного кругового режима обработки очередей (weighted round robin, WRR) количество пакетов, отправленное из каждой очереди, определяется присвоенным ей взвешенным коэффициентом.


Стенд представлял из себя ноутбук, подключенный на скорости 10 full к коммутатору DES-3200-28/B1, на который поступал мультикаст-поток с битрейтом больше 10 мбит/сек. Параллельно был запущен ping до ya.ru. Scheduling mechanism был настроен в режиме strict. Изображение в плеере ожидаемо рассыпалось, потери ICMP-пакетов составляли около 50%.

При переключении scheduling mechanism в режим weight_fair изображение по прежнему "разваливалось", но ICMP-пакеты теряться перестали.

Затем коммутатор был заменен на DES-3200-28/C1 и проведен тот же тест в тех же режимах. С остальными настройками по умолчанию при переходе из режима strict в режим weight_fair ничего не изменилось -  ICMP-пакеты по-прежнему терялись. Это говорит о том, что мы не до конца понимаем поведение ревизии C1. :)

Последним был проверен коммутатор DES-3028. В режиме strict он работает только для очереди с высшим приоритетом (3). Остальные очереди работают в режиме WRR. Коммутатор сообщаем нам об этом сам:
Note: The strict mode is only supported at the highest queue
and the other lower queues will still work at WRR mode.


Чем в теории это принципиально отличается от поведения на других моделях я затрудняюсь сказать, но на практике 100% трафика, не попавшего в очередь №3 было заблокировано. Ноутбук даже не смог разрешить имя ya.ru при помощи DNS. ICMP-пакеты не проходили совсем. При переключении scheduling mechanism в режим weight_fair поведение стало аналогичным DES-3200-28/B1.

В итоге в очередной раз видим, что к каждой железке нужен особый подход. Подумываю теперь чтобы включить режим WRR на моделях DES-3028 и DES-3200/B1.

вторник, 1 декабря 2015 г.

QoS и iperf

На работе на стенде были проведены тесты QoS на коммутаторах DES-3200-28 старой и новой ревизии. Результаты достаточно странные. Но сначала пару слов о самом стенде. На коммутатор поступал мультикаст трафик с DSCP меткой 48 и в этом же направлении шел трафик, сгенерированный iperf. В порты последнего были включены потребитель мультикаста и хост, нагружающий канал паразитным трафиком. Иногда потребитель и второй хост находились за одним портом. Собственно, данные тесты явились продолжением вот этого эксперимента.
Схема примерно такая. Только в этот раз вместо DGS-3100 проверялись коммутаторы DES-3200-28.

Удалось выяснить вот что:
Для коммутатора DES-3200-28/B1 включение/отключение приоритизации сказывается на телевидении (мультикаст) самым непосредственным образом. Когда командой «config dscp_mapping dscp_value 48 class 0» мультикаст определялся в нулевую очередь, то трафик iperf попадал в очередь №1 (см. раздел "Advantages of QoS" в документации), т.е. имел приоритет над телевидением. В результате телевидение ожидаемо "рассыпалось", а TS Reader фиксировал ошибки CC.

Дополнительно было выяснено, то мэппинг трафика с помощью ACL отрабатывает раньше DSCP Mapping, то есть команда: «config dscp_mapping dscp_value 48 class 0» не играет роли, если ACL уже смэппил трафик в очередь, например вот таким профилем:
create access_profile ip destination_ip_mask 255.255.248.0 profile_id 7
config access_profile profile_id 7 add access_id auto_assign ip destination_ip 239.1.8.0 port [up] permit priority 6


Для коммутатора DES-3200-28/C1 все несколько сложнее. Даже при отключенной приоритизации мультикаст с iperf делят пропускную способность таким образом, что сначала проходит мультикаст*, а затем iperf. Незначительного числа ошибок в потоке удалось добиться только увеличением числа потоков iperf. Причем на другой рабочей станции это поведение не воспроизвелось.

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

*Добавлено 23.12.2015:
После того, как вместо iperf был задействован торрент-клиент, все встало на свои места. Мультикаст на DES-3200-28/C1 перестал проходить без ошибок, телевидение "посыпалось". Таким образом, мультикаст не имеет приоритета перед другим трафиком, просто данная модель обладает то ли большим буфером для данных, то ли более производительной коммутационной матрицей. В результате, в случаях, когда на коммутаторах старой ревизии ошибки уже есть, новая ревизия еще справляется с трафиком.

Про сам механизм QoS на DES-3200-28/C1 можно сказать что он работает как надо. Есть у него, правда, одна интересная особенность - настройки 802.1p на C1 играют роль даже при только DSCP покраске (без 802.1p). Если на ревизии B1 если предпочтение отдано IP DSCP, то настройки 802.1p не важны, но в случае C1 они тоже учитываются.

Поведение коммутатора при получении трафика с ToS (DSCP)=32 и CoS (802.1p)=7:
1. Если trust dscp выключен, то пакет полетит в очередь, определенную для CoS=7 в 802.1p user_priority. По умолчанию это 7-я очередь.
2. Если trust dscp включен, то на основе DSCP map dscp_priority определится CoS. В данном случае для DSCP 32-39 будет определен CoS, равный 4. Затем на основе 802.1p user_priority определится очередь, соответствующая CoS=4. В данном случае это 4-я очередь.

Иными словами, на C1 цепочка сопоставлений на 1 шаг длиннее:
DSCP-->CoS-->queue при включенном dscp trust и
CoS-->queue при выключенном.

А на B1 логика такая:
DSCP-->queue при включенном cos mapping ip dscp
CoS-->queue при выключенном ip dscp и включенном ethernet 802.1p.

P.S. С DGS-3100-24TG (см. ссылку в начале статьи) также все прояснилось после тестов, где нагрузку создавал торрент-клиент. Поведение коммутатора вполне предсказуемое.

воскресенье, 29 ноября 2015 г.

Работа Traffic Control на разных ревизиях

Проверили на стенде работу Traffic Control в коммутаторах DES-3028 и DES-3200-28 всех ревизий. Исходили мы из этого:

Режим Shutdown:
При обнаружении шторма на порту, когда превышено значение Threshold, свич блокирует на этом порту весь входящий трафик на период Count Down (кроме STP-трафика). Через каждый интервал Time Interval производится проверка на наличие шторма, превышающего Threshold. Если по истечении времени Count Down трафик еще присутствует, тогда порт переводится в режим Shutdown Rest. Через 5 минут порт автоматически вернется в нормальное состояние. Если же при следующей проверке до истечения Count Down шторм не обнаруживается, тогда свич переводит порт в нормальный режим, разрешая входящий трафик на нем.

В режиме Shutdown значение Threshold представлено в пакетах в секунду.


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

При тестах было замечено, что DES-3200-28/C1 при работе в режиме drop сообщает в лог о шторме, а остальные коммутаторы из списка выше - нет. Причем фильтрация в этом режиме у /C1 работает намного качественнее, в то время как при использовании /B1 второй хост получает часть пакетов от "флудящего" хоста. В режиме shutdown коммутаторы работают, вроде бы, одинаково.

Пришлось снова открывать инструкции. Судя по ним, для модели DES-3028 значение параметра threshold представлено в килобитах в секунду (не указано для обоих режимов или для одного); на DES-3200-28/A1/B1 — в килобитах в секунду в режиме drop и пакетах в секунду в режиме shutdown; на DES-3200-28/C1 — в пакетах в секунду в обоих режимах.

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

Ограничение по PPS намного точнее, чем по Kbit/sec. При этом режим drop удобнее тем, что трафик обрабатывается аппаратно, а порт клиента не блокируется.

Итоговые результаты такие:
  1. DES-3200-28/C1 - лучше всего справляется со штормом в сети. В режиме drop он будет ограничивать шторм аппаратными средствами, сообщая в лог о начале и окончании шторма. Порт при этом отключаться не будет, а клиент будет получать услугу.
  2. DES-3200-28/A1/B1 - для этой модели предстоит выбирать между: а) ограничивать лишний трафик по максимуму, блокируя порт и сообщая об этом в логе; б) не блокировать порт, пропускать больше лишнего трафика и ничего не сообщать в лог.
  3. DES-3028 - аналогично как в предыдущем случае. Про режим shutdown пояснений в инструкции не нашлось, но, скорее всего, дело обстоит точно так же, как у DES-3200-* первых ревизий.
p.s. Помню как несколько лет в все плевались от ревизии C1, выгребая со складов остатки B1. И это было оправдано, т.к. софт был очень сырым. Между тем, все больше убеждаюсь, что ревизия C1 на порядок лучше старых моделей. Это совершенно другой коммутатор.


пятница, 27 ноября 2015 г.

Взаимоисключающие ACL и PCF ACL правила

Не так давно в нашем полку админов прибыло и новоиспеченному коллеге было поручено провести ряд опытов на тестовом стенде. Для более глубокого погружения в процесс, так сказать. Таким образом появился материал для новых заметок. Сегодня пару слов о принципах обработки взаимоисключающих ACL и PCF ACL правил.

Суть проблемы: Когда один и тот же кадр/пакет попадает одновременно и под ACL правило и под PCF ACL правило, содержащее offset, то приоритетным будет запрещающее правило, независимо от порядка их следования.

Вот и вот посты на эту тему от сотрудника D-Link.

Кроме того, есть интересная серия DES-3200-xx/C1, логика ACL для которой несколько раз переделывалась. Потому стало интересно, как обрабатывается подобная ситуация на этой серии. Заодно перепроверили и DES-3028.

Результаты тестов:
  1. Для коммутаторов DES-3028 и DES-3200-28/C1 приоритетным является вышестоящее правило, то есть правила обрабатываются по принципу первого соответствия.
  2. Для коммутаторов DES-3200-28/A1/B1 приоритетным является запрещающее правило независимо от порядка следования правил.

суббота, 17 октября 2015 г.

maXys - сборщик MAC-notify и Syslog-сообщений

Прошел ровно год с момента написания статьи про Macsys - системную службу для сбора Syslog и MAC-notify сообщений с коммутаторов D-Link. В той статье я мельком упоминал про его продолжение - Unix-демона, написанного на Python. Это один из моих первых экспериментов с Python, поэтому перед публикацией исходного кода последний требовалось хотя бы по минимуму "причесать". Время для этого я смог отыскать только недавно. Новый (хотя уже не совсем :) ) сервис называется maXys и его отличия от старого Macsys таковы:
  • maXys, в отличие от Macsys, предназначен для работы под FreeBSD, а не под Windows.
  • maXys имеет открытый исходный код под лицензией GPL2 или какой то там, не сильно этим заморачиваюсь. :)
  • новый сервис умеет отправлять в Jabber-конференцию сообщения Syslog, содержащие определенный текст.
  • новый сервис умеет отправлять данные в Oracle через Apex.
В остальном все без изменений: основная задача - сервиса собирать сообщения Syslog и MAC-notify (SNMP-trap) и помещать их в базу данных или log-файл. Документацию и инструкцию по установке можно найти на официальной страничке сервиса - https://github.com/xcme/maXys.

Если вдруг кому-то интересно, зачем вообще в maXys нужна поддержка Jabber, отвечу, что такое решение удобно использовать для отлова специфичных событий. Сейчас у меня сервис сообщает в конференцию о неправильных попытках входа и о выполняемых командах на коммутаторах. Таким образом, видно кто, что и где настраивает в данный момент. :)

среда, 23 сентября 2015 г.

SnmpB - MIB-браузер

Потратив не один час на поиски нашел неплохой MIB-браузер под Windows - SnmpB. Он слегка подзаброшен (не обновляется с 2013 года), но при этом неплох. Отличительная особенность программы в том, что она не требует Java. Большинство других, в т.ч. iReasoning MIB Browser требуют Java для работы.

Небольшой баг программы - она не умеет работать с очень длинными путями к каталогам с файлами с MIB. Добавив несколько каталогов с путями вида ..\usr\share\snmp\mibs\DES-3200_R4.39_MIB_20150306\proprietaryMIB\Dlink-common-mgmt\ долго не мог понять почему программа не видит MIB'ы в основном дереве. Когда уменьшил путь все стало нормально.


По сравнению с браузером от iReasoning браузер SnmpB не имеет ограничения в 10 одновременно подключаемых MIB-файлов. В первом это ограничение очень чувствовалось. Но и минус тоже есть - все пути нужно прописывать явно, диалогового окна выбора нет.

Тем не менее, на данный момент это мой выбор для работы с MIB-файлами под Windows.

понедельник, 31 августа 2015 г.

Несколько слов о QoS в D-Link

Есть некоторая путаница в этих терминах - QoS, CoS, ToS. По-видимому, это связано с историческими причинами, по большей части. Поэтому имеет смысл пояснить термины в двух словах.

QoS (Quality of Service — качество обслуживания) - общие соглашения об качестве трафика, которое в QoS определяется полосой пропусканий, задержкой при передаче, отклонениями при передаче (джиттер) и потерей пакетов. То есть это некое обобщенное название.

CoS (Class of Service) — поле из 3 бит в теге 802.1q Ethernet-кадра. Метод указания приоритета этими битами описывается в стандарте 802.1p.

ToS (Type of Service) — поле в IP-заголовке (1 байт). Предназначено для маркировки трафика на сетевом уровне.
Байт ToS состоит из 6 бит DSCP (Differentiated Services Code Point) и двух бит ECN (Explicit Congestion Notification). При этом ECN занимает младшие два бита и предназначено для явного уведомления о перезгрузке канала, а DSCP занимает старшие 6 бит и определяет приоритет пакета.

Коммутаторы DES-3028/DES-3200-xx (и не только) поддерживают управление трафиком на основе меток 802.1p и DSCP и позволяют выделить нужную полосу пропускания для приложений, критичных к задержке трафика, за счет меньшей скорости передачи остального трафика. Для этой цели используются "очереди". Коммутаторы DES-3028 имеют 4 очереди (от 0 до 3), а последние коммутаторы DES-3200-xx/C1 - 8 очередей (от 0 до 7). Каждый пакет, а, вернее, фрейм, попадает в одну из этих очередей по следующей схеме:
  • В случае наличия метки 802.1p - на основе этой метки.
  • В случае отсутствия метки 802.1p - на основе 802.1p default_priority для каждого порта.
  • В случае включения dscp trust - согласно dscp map .. dscp_priority (при этом метка 802.1p игнорируется).

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

Так или иначе, в "очереди" попадает любой трафик, а не только "покрашенный". Дальше коммутатор должен этот трафик передать дальше при помощи одного из двух механизмов. Ниже приведена небольшая выдержка из официальной документации D-Link:
 
При использовании строго режима (Strict mode) обработки очередей пакеты из очереди высшего приоритета всегда обслуживаются первыми. Опустошение очередей происходит, строго следуя их приоритетам. Только тогда, когда очередь более высокого приоритета пуста, обслуживаются пакеты с более низким приоритетом.

В случае использовании взвешенного кругового режима обработки очередей (weighted round robin, WRR) количество пакетов, отправленное из каждой очереди, определяется присвоенным ей взвешенным коэффициентом.


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

Пример настройки DES-3200-28/C1:
config scheduling_mechanism strict
config dscp trust 1-28 state disable
config dscp trust 25 state  enable


Первая строка включает механизм strict, вторая - выключает приоритизацию DSCP на всех портах (переключает на 802.1p), а третья - включает ее на 25-м порту (предполагается, что это uplink-порт).

вторник, 21 июля 2015 г.

Uplink без метки 802.1q и неверный PVID

Данная заметка содержит описание проблемы «нетегированного» аплинка и потери доступа к коммутатору при загрузке конфигурации, где меняется PVID на магистральных портах. Описан способ, которым можно попытаться вернуть доступ к устройству.
 
(Заметка является адаптированной под блог статьей из корпоративной wiki)

Суть проблемы


Чтобы пользователи не могли генерировать фреймы с меткой 802.1q на коммутаторах включается функционал Ingress Checking, который проверяет поступающие фреймы на «попадание» в допустимый vlan. При этом, правда, перестает работать LLDP, т.к. Ingress Checking проверяет и такие пакетики. Чтобы LLDP заработал, на порту должен быть PVID реально существующего VLAN. Поскольку настраивать каждый коммутатор с учетом его собственных VLAN неудобно и, поскольку в моей сети есть multicast vlan, который одинаковый на всех устройствах, то PVID на магистральных портах приравнивается к ID мультикаст-vlan'а. Этим зайцем убиваются все выстрелы (или наоборот) и все работает как задумано.

Проблема появляется тогда, когда сеть управления на стыковочных портах отдается без метки 802.1q, то есть «антегом» (в моей сети такая ситуация - результат ошибки при настройке; при правильной настройке стыки всегда «тегированные»). В этом случае на порту коммутатора PVID равен ID управляющего VLAN. После загрузки новой конфигурации он становится равен 50 (ID моего мультикаст-vlan'а). Доступ к коммутатору при этом пропадает.
 

"Куда нажать?"


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

Так, например, нас интересуют строчки:

enable pvid auto_assign
config vlan default delete 1-28
config vlan default add untagged 25
...
config ipif System vlan default ipaddress 10.99.91.13/25 state enable


Нетрудно догадаться, что при применении к ним команды из нового конфига:

config gvrp 25-28 pvid 50

Доступ к коммутатору будет потерян.

Как выйти из этой ситуации?

Подсказка: Несмотря на неправильную настройку VLAN, порт 25 по прежнему member в default vlan! Этим и надо воспользоваться! 

Необходимые условия


Чтобы получить доступ нужно кое-что перенастроить:
  • На вышестоящем устройстве получить интерфейс из сети проблемного коммутатора и в таком же VLAN.
  • Настроить управляющий VLAN недоступного коммутатора на стыковочном порту вышестоящего коммутатора как tagged.
  • Проверить, чтобы PVID на стыковочном порту был равен ID управляющего VLAN недоступного коммутатора.
Теперь можно попробовать обратиться с доступного интерфейса на «потерянный» коммутатор. Он должен быть доступен.

Шта?


Как все это работает?
  • Фрейм с доступного хоста в управляющей сети недоступного коммутатора отдается в стыковочный порт с меткой 802.1q.
  • Поскольку на недоступном коммутаторе порт все еще является member данного VLAN, то фрейм попадает в управляющий VLAN и неправильный PVID здесь не помеха, т.к. он оказывает влияние только на фреймы без метки 802.1q.
  • Обратный фрейм с недоступного коммутатора отдается в стыковочный порт без метки 802.1q, т.к. изначально данный порт был настроен как untagged для управляющего VLAN.
  • На доступный коммутатор этот фрейм заворачивается в управляющий VLAN благодаря заранее установленному PVID.

Таким вот способом можно «достать» недоступный коммутатор без его перезагрузки ремонтником.

Подсказка: При манипуляциях с интерфейсом System на вышестоящем коммутаторе желательно запланировать перезагрузку через 5-10 минут и постоянно сдвигать ее. Это поможет получить доступ к данному коммутатору, когда вы ошибетесь. :) 

суббота, 11 июля 2015 г.

Небольшие обновления Briseis и Dracon

Немного отвлекся от монстров в Diablo и обновил свои проекты Briseis и Dracon.

Dracon теперь умеет выгружать последний бекап из базы MongoDB. Если с коммутатора запросить у сервиса файл с именем backup, то будет выгружена последняя конфигурация для данного устройства (если она, конечно, ранее выгружалась в базу).

Еще удобно использовать переменную {$target}, которая будет заменена на IP-адрес коммутатора. Я добавил этот шаблон в конфиг:
config snmp system_name {$target}
И теперь по LLDP вижу не только MAC соседнего коммутатора, но и его IP (т.к. по LLDP передается system name)

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

Я сделал такую последовательность SNMP-команд:
  1. Сохраняем конфигурацию в памяти коммутатора.
  2. Выгружаем конфигурацию на сервис Dracon.
  3. Получаем новую конфигурацию с сервиса Dracon.
Между каждой командой проходит 5 секунд, чтобы дать коммутатору время сделать свои дела и не получить ошибку с сообщением, что файловая система занята. Затем пишем в статистику, завершаем цикл и 2-3 секунды ждем до начала нового. Итого общее время на проход я выставил в 20 секунд. За раз из базы выбирается 10 коммутаторов. Получается в минуту сохраняются, бекапятся и обновляются 30 коммутаторов.

Как буду уверен, что новый конфиг применяется корректно, то обновлю все устройства по всей сети. Сейчас же обновил около трех сотен, для проверки самого механизма обновления через Briseis и Dracon.

пятница, 3 июля 2015 г.

Show log? No entry!

Случайно заметили проблему на коммутаторе DGS-3120-24SC - при попытке посмотреть лог командой show log устройство весело рапортовало No entry! Обновление ПО и перезагрузка не помогли. Решение, впрочем, нашлось довольно быстро при помощи Яндекса. Описано оно тут. Все, что нужно сделать, это выполнить команду clear log. Теме 6 лет, между прочим!

Очередной раз налицо подтверждение тому, что все новое - хорошо забытое старое. Век живи - век учись! :)

пятница, 19 июня 2015 г.

Разработка ACL для DES-3200-28/C1

Недавно наконец-то закончил разбираться с ACL-ками для ревизии C1. Коммутаторы DES-3200-28 этой ревизии являются самыми распространенными в моей сети - их число приближается к 900. Долгое время они не имели вообще никаких ACL - ситуацию спасали сегментация трафика и влан-на-коммутатор - но хотелось дополнительной защиты от потенциального спуфинга.

Итак, задачи, которые должны решать ACL:

  • Блокировка трафика от абонентов к сетям управления.
  • Блокировка определенных портов для предотвращения доступа к общим сетевым ресурсам.
  • Блокировка неправильных ARP-пакетов от абонентов (в целях предотвращения ARP-spoofing'а).
  • Блокировка IP-пакетов с поддельными SRC IP-адресами (IP-Spoofing) в целях предотвращения DDoS-атак и исчерпания пула NAT.
  • Отправка приоритетного трафика (телевидение) в определенную очередь (резервирование полосы пропускания).
  • Блокировка мультикаста от абонентов.
  • Разрешение любого трафика с порта (включается вручную).
На коммутаторах ревизии C1 логика работы ACL менялась в процессе разработки ПО. В результате этого не вся информация, приведенная на форумах и в официальных презентациях, является актуальной.

Сейчас все выглядит так:
  • На коммутаторе может быть всего 4 ACL профиля, причем 2 из них уже созданы - это Ethernet и IP.
  • Можно создать еще два профиля на выбор из набора Ethernet, IP, IPv6 и PCF, причем PCF профиль может быть всего один.
  • Кадр сопоставляется с правилами последовательно, так, как идут правила в профилях. Профили тоже проверяются последовательно. То есть все точно также, как и на других моделях.
  • В PCF правила можно добавлять до 4-х chunk по 4 байта каждый.
Ограничения по количеству профилей накладывают ограничения и на общую структуру правил. То есть, если один чанк уже был использован с одной маской, то именно в эту маску именно в этом профиле и придется уложить все правила, где проверяются соответствующие чанку байты.

Примечание: Соответствие chunk и байт смотри тут.

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

Конкретно замедитировав, я остановился на следующей логике:
  1. Профиль #1 (vip): Безусловно разрешается трафик для нужных портов. Настраивается исключительно вручную и при необходимости.
  2. Профиль #2 (vlandscp): Разрешается трафик для управляющих и служебных сетей (коммутаторы, камеры, wi-fi). Меняется приоритет правильным мультикаст-группам.
  3. Профиль #3 (security): Запрещается мультикаст от абонентов и некоторые не очень хорошие TCP порты
  4. Профиль #4 (pcf): Запрещается трафик к служебным сетям от абонентов. Разрешаются только корректные ARP и source IP. Остальные ARP и IP для абонентов блокируются.

После разбирательств с QoS и идеи вообще не фильтровать трафик на служебных портах профиль №2 потерял свою актуальность. Здесь я оставлю его просто в качестве примера правил.

Профиль vip:
create access_profile profile_id 1 profile_name vip ethernet source_mac 00-00-00-00-00-00
#to manually allow any traffic for port X add following rule:
#config access_profile profile_name vip add access_id auto_assign ethernet source_mac 00-00-00-00-00-00 port X permit


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

create access_profile profile_id 2 profile_name vlandscp ip destination_ip_mask 255.255.248.0 vlan 0xFF0
#allow vlans with tag 0-15, 16-31 (management) 448-463, 464-479 (wi-fi), 576-591 (cams 586)
config access_profile profile_name vlandscp add access_id auto_assign ip vlan_id 1 port all permit
config access_profile profile_name vlandscp add access_id auto_assign ip vlan_id 16 port all permit
config access_profile profile_name vlandscp add access_id auto_assign ip vlan_id 448 port all permit
config access_profile profile_name vlandscp add access_id auto_assign ip vlan_id 464 port all permit
config access_profile profile_name vlandscp add access_id auto_assign ip vlan_id 576 port all permit
 

#replace priority on multicast groups in range 239.1.8.0/21
config access_profile profile_name vlandscp add access_id 64 ip destination_ip 239.1.8.0 port [up] permit priority 6 replace_dscp_with 48
config access_profile profile_name vlandscp add access_id 64 ip destination_ip 239.1.8.0 port [pu] permit priority 6 replace_dscp_with 48


Если профиль vip имел тип ethernet, то vlandscp имеет тип ip (оба эти профиля зарезервированы и уже созданы системой). В последнем случае профиль создан с destination_ip_mask для сетей /21 и диапазона из 16 vlan. Последнее достигается из-за использования бинарной/неполной маски 0xFF0.

Первые 5 правил разрешают трафик в 5 диапазонах из 16 служебных vlan. Следующие два правила отправляют телевидение в 6-ю очередь и переписывают метку dscp.

Повторюсь, от профиля vlandscp я отказался, в данном случае это всего лишь демонстрация правил.

Фактически весь трафик попадает под обработку только двух оставшихся профилей - security и pcf.

Профиль security:

create access_profile profile_id 3 profile_name security ip destination_ip_mask 240.0.0.0 tcp dst_port_mask 0xFFFF
#deny multicast from subscribers
config access_profile profile_name security add access_id auto_assign ip destination_ip 224.0.0.0 port [ss] deny
#deny TCP 135,139,445,2869,3587,5357,5358
config access_profile profile_name security add access_id auto_assign ip tcp dst_port  135 port [ss] deny
config access_profile profile_name security add access_id auto_assign ip tcp dst_port  139 port [ss] deny
config access_profile profile_name security add access_id auto_assign ip tcp dst_port  445 port [ss] deny
config access_profile profile_name security add access_id auto_assign ip tcp dst_port 2869 port [ss] deny
config access_profile profile_name security add access_id auto_assign ip tcp dst_port 3587 port [ss] deny
config access_profile profile_name security add access_id auto_assign ip tcp dst_port 5357 port [ss] deny
config access_profile profile_name security add access_id auto_assign ip tcp dst_port 5358 port [ss] deny


Сначала блокируется multicast с абонентских портов, после чего блокируются некоторые не очень нужные абоненту TCP-порты. В моем случае блокировка TCP-портов несколько избыточна, но я решил оставить ее на всякий случай. Остальной трафик для обнаружения сетевых ресурсов будет заблокирован из-за сегментации трафика, ACL на маршрутизаторе и vlan, ограничивающегося коммутатором.

Ну и самый интересный профиль - pcf:
create access_profile profile_id 4 profile_name pcf packet_content_mask offset_chunk_1 3 0xFFFF offset_chunk_2 7 0xFFFFFEF8 offset_chunk_3 8 0xFFF80000
#deny networks 172.16.0.0/13 and 10.99.0.0/13 for subscribers
config access_profile profile_name pcf add access_id 8 packet_content offset_chunk_1 0x0800 offset_chunk_3 0xAC100000 port [ss] deny
config access_profile profile_name pcf add access_id 9 packet_content offset_chunk_1 0x0800 offset_chunk_3 0x0A600000 port [ss] deny
#allow specific source network (10.XX.YY.port_N*8 0.0.1.7) for a customer
config access_profile profile_name pcf add access_id
auto_assign packet_content offset_chunk_1 0x0800 offset_chunk_2 0x0A(fn_2oct#custom1)(fn_3oct#custom1)08 port  [ss#1] permit
config access_profile profile_name pcf add access_id
auto_assign packet_content offset_chunk_1 0x0800 offset_chunk_2 0x0A(fn_2oct#custom1)(fn_3oct#custom1)10 port  [ss#2] permit
...
#permit ARP with correct 4th octet (between port_N*8 and port_N*8+7)
config access_profile profile_name pcf add access_id
auto_assign packet_content offset_chunk_1 0x0806 offset_chunk_3 0x(fn_3oct#custom1)080000 port  [ss#1] permit
config access_profile profile_name pcf add access_id auto_assign packet_content offset_chunk_1 0x0806 offset_chunk_3 0x(fn_3oct_p1#custom1)080000 port  [ss#1] permit
config access_profile profile_name pcf add access_id auto_assign packet_content offset_chunk_1 0x0806 offset_chunk_3 0x(fn_3oct#custom1)100000 port  [ss#2] permit
config access_profile profile_name pcf add access_id auto_assign packet_content offset_chunk_1 0x0806 offset_chunk_3 0x(fn_3oct_p1#custom1)100000 port  [ss#2] permit

...
#deny IP
config access_profile profile_name pcf add access_id 254 packet_content offset_chunk_1 0x0800 port [ss] deny
#deny ARP
config access_profile profile_name pcf add access_id 255 packet_content offset_chunk_1 0x0806 port [ss] deny


Обратите внимание на используемые чанки и их маски: offset_chunk_1 3 0xFFFF, offset_chunk_2 7 0xFFFFFEF8 и offset_chunk_3 8 0xFFF80000.

В этом профиле мы фильтруем ethertype, ip src, ip dst, arp src. Посмотрим на расположение этих данных в структуре кадра:
ethertype - байты 12  и 13
arp src ip - байты 28, 29, 30 и 31
ip src - байты 26, 27, 28  и 29
ip dst - байты 30, 31, 32 и 33

Поэтому согласно приведенной выше таблице нас интересуют чанки №3, №7 и №8, которые включают в себя все нужные нам байты. Самое забавное в нашей ситуации то, что arp src ip находится "между" чанками 7 и 8, т.е. захватывает вторую половину 7 чанка и первую половину 8-го чанка. При этом, как я уже упоминал выше, мы можем использовать каждый чанк только 1 раз. Поэтому придется строить правила с учетом этого нюанса.

Разберем что именно нам надо описать в правилах:
В сети каждому абоненту выдается диапазон адресов /29, основанный на номере порта. При этом первый бит третьего октета IP-адреса может меняться на единичку. Исторически это использовалось для блокирования должников. При этом сама сеть, в которую попадают абоненты одного коммутатора, имеет маску /23.

Это будет лучше понятно на примере:
Если абонент подключен в порт №1 и для абонентов этого коммутатора выделена сеть 10.128.4.0/23, то правильными адресами для абонента будут 10.128.4.8/29  и 10.128.5.8/29.
Аналогично для 10-го порта и сети 10.133.56.0/23 - соответственно 10.133.56.80/29 и 10.133.57.80/29.

Как нетрудно догадаться, такая схема описывается маской 0xFFFFFEF8. В бинарном представлении последние два байта здесь будут выглядеть как 0b11111110 и 0b11111000. Если кто забыл, это, фактически, инверсия cisco wildcard mask, где биты, соответствующие нулевым битам маски, игнорирутся.

Таким образом мы разобрались с одной маской для IP SRC (чанк 7) - это 0xFFFFFEF8. Теперь аналогичным образом нужно описать ARP. Но ARP SRC IP смещен на 2 байта по отношение к IP SRC и самые интересный нам байты попадают уже в чанк 8. Это байты с номерами 30 и 31. А вот остальные 2 байта нам уже не нужны. Отсюда наша маска для чанка 8 должна была бы быть 0xFEF80000. Однако, согласно техзаданию нам надо блокировать еще доступ и к сетям управления, которые в нашем случае описываются как 172.16.0.0/15 и 10.99.0.0/16. Как видно, 172 и 10 - это байт №30, а 16 и 99 - байт №31, т.е. те же самые байты, которые мы пытаемся описать для ARP SRC IP. И если для байта №31 мы еще можем позволить себе забрать дополнительные 8 адресов (т.к. это локальные адреса), то забирать по 1 дополнительному адресу для байта №30 было бы слишком роскошно. Отсюда вывод: использовать маску 0xFFFFFFF8 и описывать ARP двумя правилами - с жестко заданными третьим октетом X и X+1.*

Ну и чтобы отделять мух от котлет ARP от IP нам потребуется знать ethertype. Его задаем жестко, поэтому используем маску 0xFFFF (0x0000FFFF).

* Эту "мелочь" я обнаружил уже в процессе написания заметки. Изначально я забыл про "нечетный" третий октет для ARP. Все-таки полезно иногда писать такие статьи и заново все разбирать. :)

Итак, первые два правила запрещают доступ к 172.16.0.0/13 и 10.99.0.0/13. Такая избыточная маска получается из-за упомянутых выше ограничений. С этим придется мириться, ага.

Потом одним правилом разрешаем абонентский блок 10.XX.YY.port_N*8 0.0.1.7 (и YY+1).

Далее двумя правилами разрешаем валидные ARP-пакеты.

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

Ну и в конце классика жанра:
enable cpu_interface_filtering

create cpu access_profile profile_id 1 ip destination_ip_mask 255.255.255.255
config cpu access_profile profile_id 1 add access_id 1 ip destination_ip 224.0.0.2 port all permit

create cpu access_profile profile_id 2 ip destination_ip_mask 255.255.248.0
config cpu access_profile profile_id 2 add access_id 1 ip destination_ip 239.1.8.0 port all permit

#deny multicast-query for subscribers
create cpu access_profile profile_id 3 ip destination_ip_mask 240.0.0.0
config cpu access_profile profile_id 3 add access_id 1 ip destination_ip 224.0.0.0 port [ss] deny


И еще:
config cpu_filter l3_control_pkt [all] all state disable
config cpu_filter l3_control_pkt  [ss] all state  enable


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

P.S. Правила в процессе обкатки, пока ни один пользователь не пострадал, но, возможно, я что-то еще поменяю.

P.P.S. О конструкциях типа [ss], [all] и (fn_3oct#custom1) можно прочитать на странице сервиса генерации конфигов Dracon.

среда, 17 июня 2015 г.

Dracon - сервис генерации конфигурационных файлов 'на лету'

Выложил на гитхаб Dracon. Это виртуальный TFTP-сервер, который хранит в своей памяти информацию о коммутаторах и портах и по запросу выдает конфигурацию на основе этих данных и предварительно сгенерированного шаблона.

В самом шаблоне при этом можно писать что-то вроде:
config ports [ss] state enable

Где [ss] при выгрузке заменяется на нужный диапазон портов.

Можно использовать собственные функции, например для подстановки в ACL нужных IP или MAC адресов.

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

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

пятница, 29 мая 2015 г.

Обновлены примеры ACL правил для ревизии C1

Обновил примеры правил на этой странице.

Хочу сказать что ревизия C1 нравится мне все больше и больше. Просто новые модели коммутаторов D-Link надо использовать через пару лет после их появления, когда все устаканится, а баги будут выпилены.

Неудобно, правда, что в этой ревизии можно использовать только 1 PCF профиль. Ладно бы, если бы можно было использовать большое число чанков, но нет! Текущее ограничение в 4 чанка по 4 байта не позволяет реализовать мои хотелки. Так что придется выкручиваться.

На следующей неделе планирую закончить разработку правил и составить разбор на тему "что как и почему".

понедельник, 25 мая 2015 г.

Конференция в jabber

От скуки зарегистрировал конференцию в джаббере - ccna@conference.jabber.ru.

Собираюсь присутствовать там в рабочее время и, иногда, по вечерам. Заходите, пообщаемся, обсудим нюансы сетестроения. :)

p.s. Из новостей - плотно взялся за PCF ACL на коммутаторах DES-3200-xx/C1. Через пару недель поделюсь результатами.

пятница, 3 апреля 2015 г.

Перезагрузка коммутаторов при помощи Briseis

Продолжим использовать Briseis не по назначению. :) В прошлой заметке мы научились массово обновлять прошивку на коммутаторах, а теперь отправим все перепрошитые коммутаторы в перезагрузку. Будем считать, что мы продолжаем работы, описанные в прошлый раз, так что остановлюсь на самом главном.

В любом месте файла userdict.py определяем списки OID для формирования varbind:

reboot3028 = [
    ['.1.3.6.1.4.1.171.11.63.6.2.1.2.1','0','3','INTEGER']
]

reboot3200 = [
    ['.1.3.6.1.4.1.171.11.113.1.3.2.1.2.1','0','3','INTEGER']
]

reboot3200_c1 = [
    ['.1.3.6.1.4.1.171.12.1.2.19','0','2','INTEGER']
]


reboot_01_04 = [
    ['1.3.6.1.4.1.171.12.1.2.32.1.3','1','\x05\x05','OCTETSTR'],
    ['1.3.6.1.4.1.171.12.1.2.32.1.4','1','\x01\x04\x07\xdf','OCTETSTR'],
    ['1.3.6.1.4.1.171.12.1.2.32.1.5','1','1','INTEGER']
]


Первые 3 списка нужны для мгновенной перезагрузки коммутатора, а 4-й позволяет выполнить отложенную перезагрузку коммутаторов DES-3200-28 ревизии C1.

Теперь в файле bconfig.py исправляем 'PassSetSet' на:
PassSetSet  = {1:['reboot']}

А 'oids_set' на:
oids_set={
    'DES-3200-28':{
       'reboot':reboot3200
    },
    'DES-3200-28/C1':{
        'reboot':reboot3200_c1
    },
    'DES-3028':{
       'reboot':reboot3028
    }
}


Для модели DES-3200-28/C1 при желании можем использовать отложенную перезагрузку, заменив значение 'reboot3200_c1' на 'reboot_01_04'. Поскольку 1-е апреля уже прошло, то есть смысл заменить '\x01\x04' на желаемую дату. Кстати, дата в команде дана скорее для примера оформления hex-значений для net-snmp в Python. На самом деле достаточно указывать только время:
delayed reboot = [
    ['1.3.6.1.4.1.171.12.1.2.32.1.3','1','\x05\x05','OCTETSTR'],
    ['1.3.6.1.4.1.171.12.1.2.32.1.5','1','1','INTEGER']
]

Такой набор позволит планировать перезагрузку в любой день без правки словаря. Перезагрузка произойдет когда часы в следующий раз покажут 5:05.

Закончим это небольшое, но весьма полезное отступление и запустим программу:
./briseis.py start

Не забудем и остановить ее через несколько секунд:
./briseis.py stop

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

вторник, 31 марта 2015 г.

Перепрошивка коммутаторов с помощью Briseis

Briseis - мой проект для сбора метрик с сетевых устройств. Иногда перед чтением метрики требуется предварительно выполнить операцию записи. Такое может понадобиться, например, при диагностики состояния кабельной линии - сначала выполняется инициализация теста, а затем уже сам сбор результатов. Briseis умеет производить операции snmpset и этой возможностью мы воспользуемся для использования программы не совсем по прямому назначению, а именно - для массовой перепрошивки коммутаторов. :) При этом несколько усложним себе задачу и представим, что мы не знаем с какими именно моделями и ревизиями коммутаторов D-Link нам потребуется работать. Будем считать, что нам известен критерий выбора этих устройств из базы MySQL и их write-community.

1. Для начала напишем MySQL-запрос к нашей СУБД для выбора коммутаторов по некоторому критерию. В моей случае это IP-адрес. В вашем случае это может быть что-то другое, поэтому не вижу смысла приводить здесь мой запрос - важен лишь результат. Убедитесь, что имеете доступ к вашему MySQL-серверу с машины, на которой будете запускать Briseis и что сам запрос возвращает табличку вида:
+------+---------------+-------------+
| id   | ip            | wcomm       |
+------+---------------+-------------+
| 6248 | 10.90.90.91   | private     |
| 6249 | 10.90.90.92   | private     |
| 6250 | 10.90.90.93   | private     |
+------+---------------+-------------+


2. Идем далее. Если мы не знаем, какие модели и ревизии коммутаторов присутствуют в этом списке, то мы можем получить эту информацию из статистики Briseis. Создадим на сервере MySQL базу данных с таблицей для размещения статистики и гарантируем пользователю 'briseis' права для работы с этой таблицей.
CREATE DATABASE IF NOT EXISTS `blackhole` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `blackhole`;

CREATE TABLE IF NOT EXISTS `stats` (
  `device_id` int(4) unsigned NOT NULL,
  `host` char(16) NOT NULL,
  `mname` char(16) NOT NULL,
  `set_timestamp` int(4) unsigned NOT NULL,
  `walk_timestamp` int(4) unsigned NOT NULL,
  `avail` int(4) unsigned NOT NULL,
  `not_avail` int(4) unsigned NOT NULL,
  `errors` int(4) unsigned NOT NULL,
  `time` int(4) unsigned NOT NULL,
  PRIMARY KEY (`device_id`),
  KEY `host` (`host`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

GRANT USAGE ON *.* TO 'briseis'@'%' IDENTIFIED BY 'briseis_pass';
GRANT ALL PRIVILEGES ON `blackhole`.`stats` TO 'briseis'@'%' WITH GRANT OPTION;


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

3. Скачиваем Briseis отсюда. При написании этой заметки я проделал этот несложный маневр при помощи простой команды:
wget https://github.com/xcme/briseis/archive/v1.0.2.tar.gz --no-check-certificate

Распаковываем архив и притупаем к правке bconfig.py. Правим настройки для MySQL на нужные нам, т.е. прописываем адреса серверов, логины, пароли и т.п. Исправляем 'useMySQLstat' на 'True' и не забываем вписать в 'mysql_query_p' запрос, который мы разработали на шаге №1. Исправляем 'logfile', указывая желаемый путь для файла журнала.

Меняем 'PassSetSet' и 'PassSetWalk' на словари с одним пустым списком:
PassSetSet = {1:[]}
PassSetWalk = {1:[]}


Задаем 'oids_set' как пустой словарь, а 'oids_walk' как пустой список:
oids_set={}
oids_walk=[]


Значения 'useGraphite' и 'useAttractor' выставляем в 'False'.

При такой настройки Briseis выполнит только проверку устройств на доступность, опросив их по ключу 'oid_ModelName', и запишет результаты в таблицу статистики.

Важно: При написании заметки обнаружил один нюанс. По умолчанию программа использует '/var/run/briseis.pid' в качестве pid-файла. Доступ к этому каталогу для обычного пользователя может быть закрыт. Если вы не хотите запускать программу от root или давать доступ к этому каталогу, исправьте путь в файле 'briseis.py' на нужный вам. В этом случае программа запустится от обычного пользователя.

4. Сохраним настройки и выполним ручной запуск программы:
./briseis.py start
При появлении в логе сообщения об завершении цикла или же просто через несколько секунд останавливаем программу:
./briseis.py stop
При этом в файле журнала мы увидим примерно следующее:
Connection to MySQL Server '*******' established
MySQL Read-Query '*Select devices*' OK. 17 rows found
(+++) Added 17 devices to database
Polling devices from the database. Attempt #1 of 2 completed for 0.6087 sec
Polling devices from the database. Attempt #2 of 2 completed for 0.0000 sec
Sending set-queries for []...
Completed all set-requests. Elapsed time 0.0470 sec. Going to sleep for 3 sec...
Sending get/walk-queries for []...
Completed all walk-requests. Elapsed time 0.0566 sec
Total number of metrics in memory: 0
Connection to MySQL statistics Server '*******' established
Sended 17 entries to statictics server. Elapsed time 0.0632 sec
------- Pass №1 completed for 4.3851 sec -------


Как видим, 17 устройств было добавлено в память программы из базы, все они оказались доступными (нет сообщений о недоступных устройствах) и 17 записей было отправлено в таблицу статистики.

5. Подключимся к нашему серверу с базой статистики и выполним запрос:
SELECT mname,count(mname) FROM blackhole.stats GROUP by mname;

В ответ получаем:
+----------------+--------------+
| mname          | count(mname) |
+----------------+--------------+
| DES-3028       |           13 |
| DES-3200-28    |            1 |
| DES-3200-28/C1 |            3 |
+----------------+--------------+
3 rows in set (0.01 sec)


Прекрасно! Теперь мы знаем с какими устройствами нам предстоит работать.

6. Теперь нам нужно научить Briseis заливать ПО на коммутаторы. Если модели устройств были бы известны нам заранее, этот пункт можно было выполнять сразу после шага №1.

В любом месте файла userdict.py определяем списки OID для формирования varbind:
fw_up3200 = [
    ['1.3.6.1.4.1.171.12.1.2.1.1.3','1','10.90.90.101','IPADDR'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.4','1','2','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.5','1','DES-3200R_1.85.B008.had','OCTETSTR'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.7','1','3','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.8','1','3','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.9','1','2','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.10','1','1','INTEGER'],
]

fw_up3028 = [
    ['1.3.6.1.4.1.171.12.1.2.1.1.3','1','10.90.90.101','IPADDR'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.4','1','2','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.5','1','DES_3028_52_V2.94-B07.had','OCTETSTR'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.7','1','3','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.8','1','3','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.9','1','2','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.1.1.10','1','1','INTEGER'],
]

fw_up3200_c1 = [
    ['1.3.6.1.4.1.171.12.1.2.18.1.1.3','1','10.90.90.101','IPADDR'],
    ['1.3.6.1.4.1.171.12.1.2.18.1.1.5','1','DES3200R_4.39.B008.had','OCTETSTR'],
    ['1.3.6.1.4.1.171.12.1.2.18.1.1.8','1','3','INTEGER'],
    ['1.3.6.1.4.1.171.12.1.2.18.1.1.12','1','3','INTEGER'],
]


TFTP-сервером в нашем примере будет '10.90.90.101'. Значения остальных параметров рекомендую посмотреть тут.

Важно: Пакет net-snmp в какой то из версий имеет баг, не позволяющий работать с типом IPADDR в python-модуле. В этом случае при работе Briseis пакет не будет сформирован и ничего не произойдет. Если вы уверены, что делаете все правильно, но при этом результата нет - обновите пакет net-snmp.

Исправляем 'PassSetSet':
PassSetSet  = {1:['FW_upd']}

Исправляем 'oids_set':
oids_set={
    'DES-3200-28':{
        'FW_upd':fw_up3200
    },
    'DES-3200-28/C1':{
        'FW_upd':fw_up3200_c1
    },
    'DES-3028':{
        'FW_upd':fw_up3028
    }
}


Правим 'snmp_Retries':
snmp_Retries  = 0

Это нужно чтобы запрос отправлялся только 1 раз. При получении первого запроса на обновление ПО коммутатор может быть занят выполнением команды и не успеет отправить подтверждение. Когда мы выставляем 0 дополнительных попыток, то спасаем коммутатор от обновления ПО несколько раз - по 1 на каждую попытку.

Запускаем программу:
./briseis.py start
И через 5 секунд останавливаем:
./briseis.py stop
В логе видим:
Sending set-queries for ['FW_upd']...
Completed all set-requests. Elapsed time 0.2973 sec. Going to sleep for 3 sec...


7. Через 3-5 минут проверяем коммутаторы. Видим, что прошивка успешно загрузилась. Теперь в 'oids_set' комментируем строки:
#    'DES-3200-28/C1':{
#        'FW_upd':fw_up3200_c1
#    },

В файле userdict.py в списках 'fw_up3200' и 'fw_up3028' меняем строку
['1.3.6.1.4.1.171.12.1.2.1.1.10','1','1','INTEGER'],
на
['1.3.6.1.4.1.171.12.1.2.1.1.10','1','2','INTEGER'],

После чего снова запускаем и останавливаем программу
./briseis.py start
./briseis.py stop


Этими действиями мы перепрошили второй образ для DES-3200-28 и DES-3028, исключив при этом из обработки модель DES-3200-28/C1.

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

пятница, 27 марта 2015 г.

Attractor - Анализатор метрик, собираемых с сетевых устройств

В прошлом посте упоминал про анализатор метрик. Теперь он доступен тут: https://github.com/xcme/attractor

Attractor - Анализатор метрик, собираемых Briseis.

Программа может работать только в паре в Briseis, где и собираются сами метрики. Документация прилагается в комплекте.

среда, 11 марта 2015 г.

Briseis - демон для FreeBSD для сбора метрик по SNMP с устройств в сети

Как и обещал, выкладываю свой инструмент для сбора метрик с устройств в сети. Взять его можно тут: https://github.com/xcme/briseis


Briseis - мощный, гибкий и быстрый инструмент для сбора метрик с устройств в сети по протоколу SNMPv2. Написанный на Python и представленный в виде Unix-демона, он позволяет собирать большие объемы данных в несколько потоков и передавать их в Graphite и анализатор метрик Attractor. Этот инструмент будет полезен, прежде всего, сетевым администраторам.

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

понедельник, 9 марта 2015 г.

Мои проекты на GitHub

В конце прошлого года обещал поделиться некоторыми своими наработками, выложив их в открытый доступ. В течении первых двух месяцев этого года я обкатывал в работе и шлифовал сервисы сбора и анализа метрик с коммутаторов D-Link. Теперь, когда они готовы, их надо где-то разместить. Выбор пал на GitHub. Однако, поскольку мой опыт работы с этим сервисом оставляет желать лучшего, я решил сначала потренироваться на "кошках" и сначала разместить свой старый проект SWToolz.

Следующим будет Briseis - многопроцессорный и многопоточный поллер для сбора данных по SNMP, работающий демоном под FreeBSD.

воскресенье, 1 февраля 2015 г.

Ingress Checking и LLDP

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

На моделях DES-3200-XX A1/B1 согласно информации от D-Link "начиная с прошивки 1.52.B004 Ingress Checking действует также и на BPDU пакетики, поэтому PVID магистральных портов должен быть равен VID реально существующего на них влана либо нужно отключать Ingress Checking."

На практике это означает, что для работы LLDP следует либо выключить Ingress Checking совсем, либо для каждого коммутатора подбирать настройки с учетом имеющихся на нем VLAN'ов.

Что же такое Ingress Checking*? Это "проверка попадания" кадра в набор VID, ассоцирированных с портом. Если функционал Ingress Checking включен, то при поступлении в порт коммутатора кадра производится сравнение VID кадра с набором идентификаторов VID, ассоциированных с портом (включая PVID порта). Если нет, то кадр отбрасывается. Если же функционал Ingress Checking выключен, то никакой проверки не производится.

В моем случае получалось, что VLAN на порту отсутствовал, но фрейм с его ID прилетал на коммутатор, который заносил MAC-адрес в таблицу коммутации. Немного подумав, коммутатор выкидывал этот MAC из таблицы коммутации до истечения fdb aging time. Видимо, он сам чувствовал, что здесь что-то не так! Но через несколько секунд MAC появлялся в таблице снова. В результате коммутатор генерировал большое количество MAC-notify трапов, благодаря чему, собственно, и был найден. После включения Ingress Checking безобразия прекращались, но переставал работать LLDP. Происходило так потому, что магистральные порты не настраивались как untagged, поэтому PVID там был равен 1. А после удаления с портов vlan default фреймы LLDP попадали под проверку функционалом Ingress Checking и отбрасывались.

Решение было найдено следующее: прописывать на магистральных портах PVID равный VID multicast-vlan'a. Удобство здесь в том, что данный VLAN присутствует на всех коммутаторах сети и на каждом имеет один и тот же ID. Это позволяет указывать такой PVID одинаковым для любого коммутатора, независимо от имеющихся на нем VLAN. В результате и настройка одинакова для всех коммутаторов и LLDP работает и некорректные фреймы с абонентских портов блокируются.

*Updated 2017.08.23:
Теперь приведено описание Ingress Checking для более общего случая. Раньше описывался вариант для untagged-порта.