FDB-таблицы коммутаторов. Приключения в зоопарке. Часть 1 — SNMP

    В течении многих лет мы, ввиду специфики работы, постоянно сталкиваемся с необходимостью съема FDB-таблиц (Forwarding DataBase) управляемых коммутаторов с данными о коммутации MAC-адресов абонентов и устройств. За это время мимо нас прошли несколько сотен различных моделей устройств многих производителей, а количество версий их прошивок сложно сосчитать. Накопив опыт – можно им и поделиться.

    В данном случае затронем лишь тему съема требуемых данных по SNMP-протоколу.

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

    Итак – SNMP-метод съема информации

    Плюсы:
    • удобство подключения по SNMP – есть библиотеки и стандартные функции под многие языки программирования. Нет нужды греть голову с Telnet-подключением и авторизацией (отдельная тема);
    • некоторые модели бюджетных коммутаторов вообще не имеют возможности Telnet-подключений;
    • в большинстве случаев используются стандартные OID для получения требуемой информации.

    Минусы:
    • скорость получения информации. Достаточно медленно на объемах (съем 2000 MAC-адресов через snmpwalk займет, в лучшем случае, около 40 секунд, в то время как Telnet их выдаст моментально);
    • SNMP сильнее нагружает процессор коммутатора – в некоторых случаях под 100% при съеме больших объемов на бюджетных моделях;
    • для каждого VLAN (а их могут быть сотни) часто требуется отдельное подключение (об этом ниже);
    • иногда различаются особенности реализации функционала у разных вендоров и моделей.

    Отдельный момент – подключение по разным протоколам SNMP – v.1 или v.2. Вторая версия более быстра, но некоторые (устаревшие) модели её не поддерживают, либо могут отдать лишь часть данных.

    Немного теории

    В FDB-таблице коммутатора содержатся записи о том какой MAC-адрес на каком интерфейсе коммутатора находится. Важное уточнение – интерфейсе это не порт. Это МОЖЕТ быть порт, а может быть – номер VLAN или прочий логический объект. А так как нам требуется именно знать номер порта, то, собственно, вся дальнейшая процедура и затевается.

    Порядок получения информации

    1. Получаем список VLAN
      • для большинства коммутаторов:
        snmpwalk -v2c -c public 192.168.0.1 .1.3.6.1.2.1.17.7.1.4.3.1.1
        

      • для Cisco и подобных
        snmpwalk -v2c -c public 192.168.0.1 .1.3.6.1.4.1.9.9.46.1.3.1.1.2
        


      При этом некоторые модели (FoxGate S6224-S4) могут ругаться и ничего так и не дать:
      iso.3.6.1.4.1.9.9.46.1.3.1.1.2 = No Such Object available on this agent at this OID
      iso.3.6.1.2.1.17.7.1.4.3.1.1 = No Such Instance currently exists at this OID
      

    2. Подключаемся к каждому VLAN и запрашиваем индексы «порт-интерфейс» для каждого VLAN. Напоминаю, что подключение по-умолчанию через SNMP выполняется к VLAN default, а чтобы подключиться к конкретному VLAN – требуется указать его после community через @, например:

      snmpwalk -v2c -c public@999 192.168.0.1 .1.3.6.1.2.1.17.1.4.1.2
      

      выдаст соотношение «порт-интерфейс» для VLAN ID: 999

      Дело в том, что в некоторые VLAN может быть отдана часть портов, в другие VLAN – другая часть и т.д. И только опросив все VLAN можно сложить общую картину по устройству. Пример по Cisco WS-C3550-48 – записи первого VLAN:

      iso.3.6.1.2.1.17.1.4.1.2.1 = INTEGER: 1
      iso.3.6.1.2.1.17.1.4.1.2.6 = INTEGER: 6
      iso.3.6.1.2.1.17.1.4.1.2.8 = INTEGER: 8
      iso.3.6.1.2.1.17.1.4.1.2.9 = INTEGER: 9
      iso.3.6.1.2.1.17.1.4.1.2.10 = INTEGER: 10
      

      В него отдано только 5 портов. В данном случае номера интерфейсов совпадают с номерами портов.

    3. Запрашиваем FDB таблицу по VLAN default:
      snmpwalk -v2c -c public 192.168.0.1 .1.3.6.1.2.1.17.4.3.1
      

      iso.3.6.1.2.1.17.4.3.1.1.0.12.66.164.241.225 = Hex-STRING: 00 0C 42 A4 F1 E1
      iso.3.6.1.2.1.17.4.3.1.2.0.12.66.164.241.225 = INTEGER: 25
      iso.3.6.1.2.1.17.4.3.1.3.0.12.66.164.241.225 = INTEGER: 3
      

      Возвращаемые данные состоят из трех логических частей — собственно MAC-адрес, номер интерфейса и тип записи, а именно:

      1 - other - запись, полученная не одним из перечисленных ниже способов
      2 - invalid - неправильная запись, неактивная в данный момент
      3 - learned - запись, изученная динамически
      4 - self – это MAC-адрес коммутатора
      5 - mgmt - запись, созданная статически
      

      Записи отличаются одиннадцатым (в данном примере) разрядом (1, 2, 3) и характеризуют какой именно параметр содержится в значении.

      Однако дьявол в деталях — иногда данные возвращаются испорченными

      iso.3.6.1.2.1.17.4.3.1.1.40.16.123.134.116.160 = Hex-STRING: 28 10 7B 86 74 A0 
      iso.3.6.1.2.1.17.4.3.1.1.44.171.37.96.118.116 = STRING: ",<%`vt"
      iso.3.6.1.2.1.17.4.3.1.1.48.133.169.66.201.219 = STRING: "0:cBЙЫ"
      iso.3.6.1.2.1.17.4.3.1.1.64.97.134.11.180.236 = STRING: "@a┼_м"
      iso.3.6.1.2.1.17.4.3.1.1.64.97.134.24.59.113 = Hex-STRING: 40 61 86 18 3B 71
      

      Поэтому не мешает выполнять проверку на валидность MAC-адреса.

      А иногда для MAC-адреса может не найтись второй и третьей записи (номер интерфейса и тип записи). SNMP такой SNMP….

    4. Запрашиваем FDB таблицу по прочим VLAN (default VLAN там тоже будет, но об этом позже)
      snmpwalk -v2c -c public 192.168.0.1 .1.3.6.1.2.1.17.7.1.2
      

      iso.3.6.1.2.1.17.7.1.2.1.1.2.1 = Counter32: 8
      iso.3.6.1.2.1.17.7.1.2.1.1.2.888 = Counter32: 1
      iso.3.6.1.2.1.17.7.1.2.2.1.2.888.0.12.66.164.241.225 = INTEGER: 25
      iso.3.6.1.2.1.17.7.1.2.2.1.2.1.0.21.153.136.45.223 = INTEGER: 2
      iso.3.6.1.2.1.17.7.1.2.2.1.2.1.0.33.133.202.27.110 = INTEGER: 1
      

      В начале – поступит информация о количестве записей в каждом из VLAN. К сожалению она иногда не соответствует действительности.

      К примеру в FoxGate S6224-S4 показало:

      iso.3.6.1.2.1.17.7.1.2.1.1.2.1 = Counter32: 21
      iso.3.6.1.2.1.17.7.1.2.1.1.2.888 = Counter32: 114
      

      А в реальности (далее в списке) записей было:
      • VLAN 1: 22
      • VLAN 82: 1
      • VLAN 130: 4
      • VLAN 888: 115
      • VLAN 2085: 4

      И идут сами записи, которые имеют особую структуру:
      iso.3.6.1.2.1.17.7.1.2.2.1.2.888.0.12.66.164.241.225 = INTEGER: 25
      

      С конца:
      • 6 блоков (0.12.66.164.241.225) – MAC-адрес в десятичной форме
      • 1 блок (888) – номер VLAN

      Ну а интерфейс, как видно из значения, номер 25.

      Однако Cisco может и не выдать таблицу по всем OID

      iso.3.6.1.2.1.17.7.1.2 = No Such Object available on this agent at this OID
      

      И тогда начинается увлекательное занятие – подключение к каждому VLAN и съем с него таблицы, указанной пунктом выше.

    5. Получив все необходимые данные – совмещаем и получаем сначала
      MAC – Интерфейс – Порт
      А потом:
      MAC – Порт
      Наконец-то.

    Важные моменты

    • если на коммутаторе много VLAN (сотня-другая) – то можно даже не пытаться снимать FDB-таблицу по нему. Никаких вменяемых таймаутов не хватит – обходить их все. Это будет очень долго.
    • индивидуальные решения под разные модели. Тут речь о местном допиливании итоговых данных. Alcatel OmniStack LS 6224 и Allied Telesyn AT-8000S/24 – хоть возвращаются номера портов 49-52, но в реальности у коммутаторов портов меньше и тут используется прошивка со старших моделей. Требуется заменить 49 порт на 25, 50 на 26 и т.д.
    • в некоторых случаях таблица соответствия ИНТЕРФЕЙС-ПОРТ даёт противоречивые данные. Huawei S2326TP-EI-AC хоть и даёт таблицу соответствия, но при этом в FDB выводятся данные с номерами ПОРТОВ, а не интерфейсов и стандартные приёмы преобразования номеров интерфейсов ведут к неправильным данным (двойное преобразование)
    • у стекируемых коммутаторов и у шасси будут особые номера интерфейсов
    • часть бюджетных моделей коммутаторов вообще не выдаст информацию о FDB-таблице по всем VLAN. Не предусмотрено производителем. Пример: D-Link DES-21XX

    Итог

    Несмотря на все вышеуказанные «особенности», SNMP-протокол остаётся самым востребованным и удобным методом получения FDB-таблицы. В большинстве случаев нет необходимостей указанных танцев с бубном и обычный годный D-Link, имеющий единственный VLAN, сходу выдаст красивый список с MAC-адресами, и номера портов будут совпадать с интерфейсами, но как знать…

    Если статья будет востребована – в следующий раз расскажу особенности съема по Telnet.

    В процессе написания статьи под рукой оказались следующие аппараты
    1. Cisco WS-C3550-48 Cisco IOS Software, C3550 Software (C3550-IPSERVICESK9-M), Version 12.2(35)SE5, RELEASE SOFTWARE (fc1) Copyright 1986-2007 by Cisco Systems, Inc. Compiled Fri 20-Jul-07 02:23 by nachen
    2. D-Link DES-3028G Fast Ethernet Switch 2.00.B2700.B27
    3. D-Link DES-3200-18/C1 Fast Ethernet Switch Build 4.36.B009
    4. Edge-Core FE L2 Switch ES3528M
    5. Foxgate S6224-S2 Device, May 24 2008 14:57:13 HardWare version is V1.00 SoftWare version is S6224-S2_1.6.7.0 OS version is 5.1.35.48 MiniRom version is S6224-S2_1.6.3 BootRom version is S6224-S2_1.6.3 Copyright 2001-2008 by Foxgate, Inc.
    6. Huawei S2326TP-EI Versatile Routing Platform Software VRP software,Version 5.70 (S2300 V100R006C05) Copyright 2003-2013 Huawei Technologies Co., Ltd.

    Метки:
    Поделиться публикацией
    Похожие публикации
    Комментарии 27
    • 0
      Всегда думал, что SNMP будет работать быстрее, чем telnet.
      надо провести сравнительное тестирование.

      и да. DES-2108 у меня вроде как снимает FDB по SNMP.
    • 0
      Спасибо, интересная статья, жду продолжение.
      По поводу скорости SNMP — видимо запросы синхронные?
      • 0
        а разве бывает асинхронный SNMP?
        тут пока список vlan не получишь, запрос по ним не сделаешь.
        • 0
          Согласен, с номерами vlan-ов засада
      • +2
        Номер влана в комьюнити — это пять!
        • 0
          У того же DES-3028 точно все несколько хитрее, так с одного OIU бралась FDB для дефлтного VLAN-а, а с другого — куда более обширная таблица, один из индексов в OID которой и было номером VLAN-а, и содержавшая FDB по всех VLAN-ам.

          Навскидку нагуглил этоу доку: www.dlink.ru/ru/faq/59/262.html. Она повествует, что по 1.3.6.1.2.1.17.7.1.2.2 живет таблица на все VLAN-ы, по 1.3.6.1.2.1.17.4.3 — на дефолтный. Первый — логичнее использовать, но не у всех железок он есть.

          А уж скорость опроса — это тема больная. Тупо перечитывать некисло напрягает железку (а если два чтения параллельно запустить, то и 100% проца скушать можно запросто, вплоть до полной неотзывчивости коммутатора, притом проходит она (забывчивость) не скоро, когда оба процесса дойдут до конца). Есть, как вариант, решение не постоянно дергать SNMP, а дергать его редко, и полагаться на SNMP Trap-ы по подключению/отключению портов.

          Правда, неприятным моментом будет не сильная освещенность такого рода вопросов в документации на многие устройства, даже и умеющие что-то подобное делать. Брать саппорт вендора и вперед ))
          • 0
            Трапы портов — далеко не выход. Что если на порту висит какой-нибудь хаб, за которым 5 абонентов? Получается порт поднят всегда, а маки то появляются, то пропадают. А вдруг порт флапает, будете собирать таблицу постоянно и уроните свич. И даже если брать трапы не на дерганье порта, а на появление маков (mac-tracking, mac-notifucation), редко какие железки такое могут. Если брать L2 dlink'и, то почти никто и не умеет.

            И да, верно подмечено, с трапами работать будет сложнее, и сервер нужно будет писать асинхронный.
            • 0
              Увы, да.

              Вот и получаем странную ситуацию: опрос свича занимает много времени, за это время таблица может мало что оказаться неактуальной, но и просто измениться (это уж от железки зависит, что она отдаст — старый «слепок» таблицы или актуальные данные), опрос этот чреват риском свич вообще завалить, а процессор тратится на преобразование из внутреннеого представления FDB в красивый (и требующий парсинга) формат OID-ов. В то же время, точно, telnet отдает то же быстрее и с меньшим напрягом. Грубо — ищем путь сбора на каждом свиче FDB максимально быстрым способом )
              • 0
                Это хорошо, когда железка отдает по снмп «слепок», а не в реальном времени, проблема только в том, что приходится считывать сразу весь слепок. Но чтобы не напрягать сильно свитч, я считывал таблицы по полям с небольшим интервалом времени, а не всю сразу. В результате сталкиваемся с проблемой синхронизации полей: пока считываем первое-второе поле таблицы, в нее добавляется строка, и когда доходим до скажем пятого-седьмого поля, в них уже новые записи. Приходилось после этого таблицу склеивать самостоятельно, вычеркивая битые записи.

                Имхо: SNMP хорош только с точки зрения универсальности, ибо не только серверы, но и свичи могут общаться на одном языке. Но как все-таки там все ущербно, эти таблицы скучные с неудобными индексами. Как все-таки не хватает SELECT `mac` WHERE `port`=1 или наоборот. В снмп-таблицах все строго и однобоко.
                • 0
                  У меня точно те же ощущения: пока прочтешь одним проходом одно поле, второе «убегает». Тут, конечно, идеально бы было трап получать при изменении FDB, но далее «область драконов» — либо по трапу мы перечитываем опять ее всю, либо из трапа инфу берем, и в нашей копии FDB вносим изменения. И то, и то свои моменты имеет.

                  Так что да, telnet (если есть) и радуемся.
                  • 0
                    В следующей статье расскажу про радость от Telnet — то ещё удовольствие.
                    На самом деле лучший вариант — это когда в наличии есть максимум инструментов и уже по месту выбираешь с чем лучше подступиться к той или иной железке.
            • +1
              Поэтому не надо использовать snmp. Telnet универсальнее и может решить все задачи, даже те, для которых не написали MIB'ов.
              Правда очень печалит что в telnet нет flow control. Окончание вывода свитча можно узнать только по промпту, а это нетривиально.
              • 0
                Тельнет был бы универсальным, если бы во всех железяках была одна и та же CLI, а тут вы напляшетесь с парсингом и написанием «языка» для каждого вендора/прошивки. Прошивку обновили, добавилась функция, добавилось поле/пробел/разделитель, к черту весь порядок парсинга под эту прошивку. Одно только command promt чего стоит, везде разное. Либо будете ждать по таймауту, что тоже криво.
                • 0
                  Других вариантов нет.
                • 0
                  Не везде есть Telnet. И как сказано ниже — при изменениях прошивок — иногда SNMP остаётся последней возможность хоть что-то получить.
              • 0
                Неужто это такая малораспространённая информация?
                • 0
                  Нормальные люди просто по snmp в fdb не лазят, нет такой задачи.
                  • 0
                    А как нормальные люди лазят в fdb? Когда нужно делать статистику или управление авторизацией по маку/порту.
                    • 0
                      dot1x, для статистики сами значения не нужны, достаточно общего количества.
                      • 0
                        dot1x хорош, когда вы управляете клиентами, и клиенты умеют dot1x. А когда у вас в сети тыща свичей, 20 тыщ компов, роутеров, теплосчетчиков, лифтов, некоторые из которых даже о DHCP не слышали, то сбор маков очень помогает в поиске проблем
                        • +1
                          В таком случае проблему не надо искать, она у вас перед глазами. Это ваша сеть. Целиком.
                          • 0
                            точно, отличная маркетинговая политика. Как в анекдоте: нет ножек, нет мультиков
              • 0
                Для сбора больших массивов данных по SNMP, попробуйте snmpbulk.

                Разница примерна в 10 раз (в лучшую сторону).
                • 0
                  Разумеется это удобнее, но упираемся в то, что она реализована на уровне системы и из-под того же PHP вызывать через SHELL прийдется.
                  И SNMP v1 она не поддерживает.
                  • 0
                    Булк — отличное решение в плане снижения пиковых нагрузок на железку в момент сбора. Но остается проблема синхронизации полей, о которой я писал выше
                  • 0
                    Раз уж говорите о цисках — mac notification разве не лучший вариант? Поллить такого рода информацию действительно несколько странно.

                    Это МОЖЕТ быть порт, а может быть – номер VLAN или прочий логический объект.

                    Ну про логические интерфейсы все понятно — а у кого такого дается лишь номер VLAN?

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