Сенсор netflow keenetic что это
NetFlow, Cisco и мониторинг трафика
Определимся с основными понятиями
NetFlow — проприетарный открытый протокол, разработанный Cisco для мониторинга трафика в сети. Netflow предоставляет возможность анализа сетевого трафика на уровне сеансов, делая запись о каждой транзакции TCP/IP.
Архитектура системы строится на сенсоре, коллекторе и анализаторе:
— Сенсор собирает статистику по проходящему через него трафику. Сенсоры имеет смысл ставить в «узловых точках» сети, например, на граничных маршрутизаторах сегментов сети.
— Коллектор осуществляет сбор информации от сенсоров. Полученные данные он сбрасывает в файл для дальнейшей обработки. Различные коллекторы сохраняют данные в различных форматах.
— Анализатор, или система обработки, считывает эти файлы и генерирует отчеты в форме, более удобной для человека. Эта система должна быть совместима с форматом данных, предоставляемых коллектором [1]. В современных системах коллектор и анализатор часто объединены в одну систему.
Обычно коллектор и анализатор являются частями одного программного комплекса, работающего на сервере. Разновидностей ПО коллектор/анализатор множество, платные и бесплатные, под Windows и Unix-системы.
В статье я не буду затрагивать эту область, рассмотрю только принципы работы NetFlow и настройку сенсора на Cisco.
Нужно сразу уяснить — коллектор и стоящий за ним анализатор являются «пассивными» элементами системы. Сенсор шлет на коллектор отчеты о трафике, коллектор принимает, анализатор анализирует, и заполняет свою базу данных на сервере. По сути, при поднятом сервере, нам не нужно вручную подключать устройства, подпадающие под мониторинг, на сервере. Пока сенсор шлет отчеты, коллектор их принимает, анализатор регистрирует. Если сенсор выключен, он «исчезает» из текущей «он-лайн» статистики.
Описание протокола
Собственно, настройка
Разберем конфигурацию сенсора при настройке на Cisco:
Router_NF# conf t
Router_NF(config)# ip flow-export destination 192.168.0.1 9996
Router_NF(config)# ip flow-export destination 10.10.0.1 9996
Router_NF(config)# ip flow-export version 9
Router_NF(config)# ip flow-cache timeout active 1
Router_NF(config)# ip flow-cache timeout inactive 15
Router_NF(config)# ip flow-export source FastEthernet 0/0
Router_NF(config)# ip flow-export source vlan4
Router_NF(config)# ip flow-export source Port-channel1.2
!
ip access-list standard iacl-snmp
remark ACL for SNMP access to device
permit 192.168.0.1
permit 10.10.0.1
deny any log
!
!
snmp-server group snmp v1 access iacl-snmp
snmp-server group snmp v2c access iacl-snmp
snmp-server community ******** **** iacl-snmp
snmp-server ifindex persist
snmp-server trap-source Loopback0
snmp-server enable traps tty
!
Router_NF(config)# interface FastEthernet 0/0
Router_NF(config-if)# ip flow egress
Router_NF(config-if)# ip flow ingress
Router_NF(config-if)# ip route-cache flow
«ip route-cache flow» может использоваться только для основного интерфейса, а «ip flow ingress» — это расширение для использования для сабинтерфесов. Функционал NetFlow Subinterface Support позволяет включать NetFlow для каждого сабинтерфейса. В сценарии, когда ваша сеть содержит множество сабинтерфейсов, а вам необходимо собирать записи только с некоторых, вы можете тонко настроить сбор информации только с определенных сабинтерфейсов
Что можно посмотреть на сенсоре:
Router_NF# show ip cache verbose flow
Router_NF# show ip flow interface
Router_NF# show ip flow export
Router_NF# show ip flow top-talkers
Информация о чемпионах, представлена категорийно, вплоть до самых посещаемых интернет — ресурсов
По основной настройке все, полезные ссылки для более полного просветления [4], [5] и [6].
Ложка дегтя
Рисунок взят из [7].
Однако с течением времени доля трафика, попадающего в раздел «Other», растет, в связи с ростом числа приложений, использующих динамические, случайно сгенерированные порты.
В документе [8], обозревающем NetFlow, вскользь упоминается проблема, хорошо проиллюстрированная на рисунке
Конечно, хотелось бы, чтобы самый разный трафик четко описывался в отчетах, например:
Категория трафика | Порты | Протокол прикладного уровня |
25, 109, 110, 113, 143 | smtp, pop2, pop3, ident, imap | |
Web | 80, 8080, 443 | http, https |
data | 20, 21, 3306, 66, 1521, 1526, 1524 | ftp, MySQL, sqlnet, Oracle, Ingres |
Network management | 53, 137, 138, 139, 445, 161, 123, 783, 8200 | domain, netbios, snmp, ntp, spamassassin, GoToMyPC |
Interactive | 22, 23, 513, 543 | ssh, telnet, rlogin, klogin |
nntp | 119 | nntp |
Chat | 194, 6891–6901, 1863, 5050, 5190 | irc, msn messenger, yahoo messenger, ICQ |
streaming | 554, 1755, 1220, 8000–8005, 7070, 7071, 6970 | rtsp, ms-streaming, Apple quicktime, internet radio (shoutcast), Real Audio & Video |
Malware & games | 1433, 1434, 666, 1999, 31337, 12345, 12346, 20034, 1024, 1025, 31338, 31339, 3127, 27015, 27016, 26000, 27001, 27960, 3724 | Ms-sql-s, ms-sql-m, backdoor, Back Orifice, NetBus, netspy, myDoom, HalfLife, Quake, QuakeWorld, QuakeIII, WarCraft |
p2p | 411, 412, 1214, 3531, 4111, 4661–4665, 4672, 6346, 6347, 6669,6881–6889, 23302, 32285, 59049, 41170, 57990 | Direct Connect, Fasttrack, Kazaa, eDonkey, Gnutella, Napster, BitTorrent, Ares, Mp2p, Azureus |
Others | — | — |
Прогресс не стоит на месте, технологии идут вперед, и шеф получит полный отчет проблему нераспознанного трафика решают разными интересными способами, например с помощью технологии NBAR.
Во время поисков было найдено обсуждение [11] и интересная презентация [12]. Дальше в дебри не пойду, ибо юн, горяч и неопытен.
NetFlow
Данная статья рассказывает о том, как организовать сбор, обработку и визуализацию информации о сетевом трафике. Она составлена на основе статей [1] и [2], и их переводов на русский язык [3] и [4] соответственно.
Кроме того, добавлены:
Рассматривается случай, когда в качестве основной операционной системы используется FreeBSD. При использовании Linux необходимы небольшие изменения в скриптах и именах конфигурационных файлов.
Содержание
Архитектура NetFlow
Netflow предоставляет возможность анализа сетевого трафика на уровне сеансов, делая запись о каждой транзакции TCP/IP. Информация не столь подробна, как предоставляемая tcpdump’ом, но представляет довольно подробную статистику.
Netflow имеет три основых компонента:
Наконец, система обработки читает эти файлы и генерирует отчеты в форме, более удобной для человека. Эта система должна быть совместима с форматом данных, предоставляемых коллектором.
В качестве каждого из элементов системы может использоваться несколько разных вариантов программ. Список доступного программного обеспечения, предназначенного для работы с NetFlow приведен ниже.
Мы рассмотрим свзяку:
Инсталляция и настройка сенсора
Инсталляция сенсора
В качестве программного обеспечения сенсора будем использовать softflowd [5]. Другое программное обеспечение, которое может использоваться как сенсор, перечислено ниже.
Для работы softlflowd требуется наличие libpcap. В FreeBSD может использоваться ng_netflow, в этом случае libpcap не обязателен.
Запуск сенсора
После того, как softflowd был установлен, необходимо выбрать интерфейс, мониторинг которого будет производиться, указать IP адрес и UDP порт коллектора. Например, для интерфейса em0 и коллектора 172.16.13.5:8818 запуск softflowd будет выглядеть следующим образом:
Сенсор немедленно начнет слушать сеть и посылать информацию на коллектор.
Для того чтобы программа работала после перезагрузки, необходимо убедиться, что она стартует на этапе начальной загрузки!
Проверка
Softflowd включает в себя программу контроля softflowctl, с помощью которой можно проверить работоспособность softflow:
Для того чтобы посмотреть информацию о самих потоках, дайте команду:
В этом выводе нас будет интересовать число активных потоков (2298) и строка «exported», сообщающая о количестве экспортированных потоков в коллектор.
Проверить, действительно ли данные отправляются и достигают коллектора можно с помощью ethereal, tcpdump или другого анализатора трафика. В случае каких-либо проблем можно использовать флаг -D демона softflowd. Softflowd посылает информацию о потоке после того, как тот будет завершен, например, прекратится FTP-сессия или загрузится web-страница. Это означает, что в любой момент времени у softflowd имеется некий кэш открытых потоков, в связи с чем остановку демона необходимо выполнять командой softflowctl shutdown. В противном случае вы потеряете данные активных потоков, которые еще не были завершены и отправлены на коллектор.
Стартовый скрипт
Для того чтобы softflowd стартовал при загрузке автоматически, необходимо создать скрипт запуска и добавить его в загрузку системы. К сожалению, пока что в порт softflowd такой скрипт не входит, поэтому его прийдётся создать самостоятельно:
После того как скрипт создан, необходимо:
Для запуска скрипта в файле /etc/rc.conf следует установить переменные:
Запуск и останов скрипта выполняются командами:
Инсталляция и настройка коллектора
Коллектор NetFlow предназначен для сбора данных, предоставляемых сенсором и сохранения их на диск для дальнейшего хранения и обработки.
Инсталляция коллектора
В качестве Netflow-коллектора будем использовать flow-capture, очень популярный коллектор Netflow, входящий в состав пакета flow-tools.
В FreeBSD порт flow-tools располагается в каталоге /usr/ports/net-mgmt/flow-tools. Установите его обычным «make all install.» Не делайте «make clean», так как, возможно, вам придется устанавливать некоторые компоненты вручную. По этой самой причине не рекомендуется использовать прекомпилированный пакет.
Создайте каталог в котором flow-capture будет хранить свои данные. Пусть это будет /var/netflow. Убедитесь, что на дисковом разделе, в котором создается каталог, достаточно свободного места: на скоростной сети данные Netflow могут составить несколько гигабайт в неделю.
Для работы системы отображения, необходимо создать каталог saved.
Запуск коллектора
Теперь нам необходимо выполнить стартовый скрипт flow-capture. Выглядит он следующим образом:
Большинство параметров можно оставить без изменеия. Флаг -w указывает каталог данных, заключительный аргумент обозначает локальный IP, удаленый IP и прослушиваемый UDP порт. В этом случае, значение 0/0/8818 указывает коллектору слушать на всех локальных IP адресах, принимать данные с любых удаленных хостов, порт 8818. В случае, если вы опасаетесь принимать чужие данне, то жестко задайте адрес сенсора.
Параметр -n указывает, сколько раз flow-capture должен создавать новый файл. Параметр -N задает глубину иерархии каталогов, в которых будут храниться файлы с данными NetFlow. Параметр -S указывает размер интервала в минутах, в течение которого flow-capture будет записывать информацию о счетчиках пакетов в файл.
Проверка
Для того, чтобы убедиться, что данные собираются, посмотрите, во-первых, появились ли файлы в каталоге netflow, а во-вторых, увеличивается ли размер временного файла.
Стартовый скрипт
Точно также как и для softflowd, для того чтобы коллектор стартовал автоматически, необходимо создать скрипт запуска и добавить его в загрузку системы. В порт flow-tools такой скрипт не входит, поэтому его прийдётся создать самостоятельно:
После того как скрипт создан, необходимо:
Для запуска скрипта в файле /etc/rc.conf следует установить переменные:
Если нужно запустить несколько копий flow-capture, необходимо задать несколько каталогов для записи данных в переменной flowcapture_dir. Прослушиваемый порт, в этом случае, будет автоматически увеличиваться на 1 для каждой копии flow-capture. Например, пусть:
Запуск и останов скрипта выполняются командами:
Инсталляция модуля Cflow.pm
Информация в этих файлах находится в бинарном формате, требующем для просмотра специальных инструментальных средств. Многие из тех инструментальных средств используют модуль Cflow.pm.
Cflow это perl-модуль, предоставляющий API для чтения двоичнх файлов данных NetFlow-коллекторов, таких как argus, cflowd, flow-tools и lfapd.
Большое количество программ составления отчетов Netflow используют perl модуль Cflow.pm для чтения файлов Netflow. Этот модуль включает в себя библиотеки и утилиты командной строки, необходимые для просмотра и редактирования файлов данных. Каждый коллектор имеет собственный формат хранения файлов и хотя Cflow.pm изначально создавался для чтения файлов cflowd(8), сейчас он способен обрабатывать и другие форматы.
В последних версиях FreeBSD /usr/ports/net-mgmt/p5-Cflow автоматически обнаруживает библиотеки flow-tools. Cflow вызывает их как -lnsl и в случае ошибки выдается предупреждение.
Если предупреждения не появилось, необходимо выполнить проверку работоспособности. Cflow включает в себя утилиту flowdumper(1), которая читает файлы данных из командной строки. Воспользуемся ей.
Если инсталляция прошла успешно, можно перейти к следующему разделу. В противном случае необходимо выполнить действия, описанные ниже.
Установка Cflow из flow-tools/contribs
В случае некорректной установки, flowdumper выведет ошибку или ничего не выведет.
Если такая ситуация произошла, продолжать работу не получится. Необходимо деинсталлировать p5-Cflow и попытаться установить его другим способом.
В каталоге исходных текстов flow-tools должен находиться каталог contrib. В подкаталоге contrib у нас усть другой архив Cflow. Распакуем его:
Cflow часто собирает правильную библиотеку, когда устанавливается flow-tools. Выполним сборку модуля:
Пробуйте flowdumper снова, все должно работать.
В противном случае, применим решение «в лоб». Flow-tools устанавливает libft.a в каталог /usr/local/lib. Отредактируем Makefile.PL модуля Cflow.pm в части, касающейся библиотек flow-tools:
После выполнения make и make install чего мы работоспособный flow-tools должен быть установлен.
С помощью CFlow можно написать множество разнообразных скриптов, решающих самые разные задачи обработки и визуализации.
Обработка и визуализация данных NetFlow
FlowScan является скриптом, написанным на Perl и, анализируя записи NetFlow, сохраняет их в базе данных RRD, Round Robin Database. RRD предназначен для хранения постоянно изменяющихся данных, наиболее важными из которых являются последние данные, а более старые имеют не такое важное значение, и поэтому могут храниться не целиком, а в усреднённом виде. За счёт этого RRD не требует много дискового пространства даже для хранения информации о больших промежутках времени.
Установка FlowScan
Установку flowscan мы будем делать из системы портов, каталог программы находится в /usr/ports/net-mgmt/flowscan. Таже будут установлениы несколько модулей Perl в качестве зависимостей. Весь инструментарий FlowScan будет по умолчанию установлен в /usr/local/var/db/flows/bin. Учтите, что сразу после установки FlowScan не работоспособен!
Сначала, нам необходимо обновить модуль FlowScan, так как официальный дистрибутив долгое время не обновлялся и не способен обрабатывать записи потока. Автор написал обновленный модуль flowscan.pm, но не включил его в состав дистрибутива. Получите FlowScan.pm версии [6] и скопируйте ее в каталог /usr/local/var/db/flows/bin, перезаписав модуль версии 1.5.
В Этом же самом каталоге находится образцовый файл конфигурации FlowScan flowscan.cf.sample. В первую очередь необходимо указать FlowScan, где искать файлы потока. FlowScan будет пытаться обработать каждый файл в каталоге, если вы не укажите регулярное выражение, описывающее необходимые файлы, включая временные файли и вложенные каталоги. В следующем примере мы обрабатываем только завершенные файлы потока, хранящиеся в каталоге /var/netflows:
В ReportClasses перечисляются все используемые для вывода отчетов модули. FlowScan поставляется с двумя модулями: CampusIO и SubNetIO. Возможно, они впоследтсвии окажутся кому-то полезными, но сейчас будет использоваться CUFlow.
Параметр WaitSeconds задает интервал ожидания между попытками FlowScan проверить каталог. Довольно много инструментальных средств используют пятиминутный интервал и могут некорректно работать с меньшим значением.
В заключение, включим отладку для проверки правильности установки:
Конфигурирование FlowScan закончено, но нам все еще необходимо настроить модуль отчетов для правильного отображения информации.
Конфигурирование CUFlow
Скачайте [7], распакуйте и скопируйте CUFlow.pm и CUFlow.cf в /usr/local/var/db/flows/bin. Сам модуль можно оставить без изменений, но необходимо отредактировать cuflow.cf, чтобы он соответствовал вашим настройкам Perl.
Инструкция Subnet указывает принадлежащие вам сети. На основании этих данных CUFlow будет различать входящий и исходящий трафик.
Инструкция Network описывает сети, которые вы хотите обрабатывать отдельно друг от друга. Каждая инструкция будет отображаться как вариант в CGI скрипте. Как вы видите в этом примере, диапазоны могут перекрываться:
Директивой OutputDir указывается, где сохранять отчеты. Не храните их в доступном по сети месте или в каталоге flow-capture.
CUFlow также вычисляет самые активные сайты и строит «хит-парад» IP адресов, передавших большее количество трафика в течении 5 минут. За этот параметр отвечает опция Scoreboard. Эта опция использует три аргумента: число IP в «хит-параде», имя каталога для хранения старых списков и имя файла текущего списка. В следующем примере указывается вести «Top 10» IP адресов, сохранять отчеты в /usr/local/www/data/scoreboard и текущим считать файл /usr/local/www/data/scoreboard/topten.html:
В то время как список самых больших потребителей/генераторов трафика в данный пятиминутный период полезен для предотвращения проблем, так же был бы полезен список самых активных хостов. Опция AggregateScore позволяет вам сделать это:
Если у вас довольно сложная сеть, то может возникнуть необходимость в нескольких сенсорах Netflow. CUFlow может отделять данные от разных сенсоров, при этом различные маршрутизаторы буду доступны в CUFlow CGI.
Директива Services предназначена для указания TCP/IP портов, которые вы хотите отслеживать отдельно. Эта директива позволяет вам делать такие выводы как «80% нашего трафика приходится на HTTP» и тому подобное. Учтите, что это повышает нагрузку на сервер, поэтому не стоит здесь указывать весь /etc/services. Не стоит указывать сервисы, которые заблокированы, например Gnutella, Edonkey и т.д:
Директива Protocol очень похожа на Services, только вместо Layer 4 используется Layer 4 модели OSI. Я рекомендую указывать Protocol 1 (ICMP), Protocol 6 (UDP) и Protocol 17 (TCP) в качестве базового минимума. Если есть много пользователей VPN то стоит отслеживать IPSec и GRE.
Так как Netflow был разработан в Cisco, то неудивительно, что много Netflow датчиков включают информацию BGP. CUFlow может отображать информацию о трафике к/от различных AS, используя для этого номер AS (опция ASNumber), softflowd не предосталяет информацию о номере автономной системы. В случае использования softflowd закомментируйте опцию ASNumber.
Сохранение записей Netflow из FlowScan
По умолчанию, FlowScan удаляет записи после обработки. Можно сохранять эти записи в течении нескольких месяцев или пока позволяет дисковое пространство. Создайте подкаталог saved в директории Netflow и тогда FlowScan автоматически будет сохранять там обработанные файлы. Даже если вы не планируете хранение старых файлов потока, я рекомендую делать это хотябы первое время, пока вы не убедитесь, что FlowScan работает правильно. В случае, если что-то пойдет не так, наличие этих данны облегчит поиск и устранение неисправности.
Запуск FlowScan
Теоретически у нас все готово к запуску:
FlowScan должен запуститься, выводя подобные сообщения:
FlowScan анализирует все старые файлы потока, при этом процесс можеть занять довольно продолжительное время, все зависит от того, сколько файлов накопилось в системе. Достойной упоминания вещью здесь является «flow hit ratio», котороя указывает на количество файлов, не соответствующих формату FlowScan и это очень хороший показатель. Если этот параметр равен 0, то скорее всего вы неправильно указали параметр Subnet.
Если FlowScan выдает ошибку «ERROR updating /var/netflow/. unknown option», необходимо внести исправления в файл FlowScan.pm, описанные в [8].
Стартовый скрипт flowscan.sh:
Построение графиков
Теперь перейдем на URL и выберем, для примера, сеть. Вы должны будете увидеть массив раскрывающихся меню. Выберете любой и нажмите «Generate graph».
Реализация NetFlow сенсора на FPGA + CPU — гибко и быстро
Как вы поняли из названия, вас ждет очередная статья про NetFlow, но на этот раз с необычной стороны — со стороны реализации NetFlow сенсора на FPGA.
Введение
Да, на хабре много статей по теме NetFlow: начиная с подробного разбора и HOWTO по настройке, до прикладного применения в отлове вирусной атаки и учете трафика.
Но это статья не о том, как NetFlow пользоваться, она о том, как его реализовать.
Задача создания NetFlow сенсора интересна в том плане, что вам одновременно необходима гибкость, чтобы поддерживать изменяемые в реальном времени шаблоны NetFlow и в то-же время очень высокая производительность, чтобы эффективно обрабатывать трафик и работать с памятью.
Там, где я работаю (я FPGA программист в НТЦ Метротек), мы используем платформы, которые позволяют делать выбор между программными и аппаратными реализациями.
Но в большей части наших задач, программная часть занимается в основном управлением, а основную работу принимает на себя FPGA. Именно поэтому создание NetFlow сенсора, как чего-то более интересного в плане Software Hardware Co-design, показалось нам подходящим поводом поделиться нашей работой с Вами, написав эту статью.
О NetFlow
Чтобы не терять нить повествования и определиться с терминами, расскажу про NetFlow, пусть и очень кратко, потому что эта информация есть везде.
NetFlow это протокол, который придумали Cisco Systems.
Зачем? Чтобы можно было удаленно следить за трафиком в сети.
То есть в локальной сети есть некоторый L3-свитч с функцией NetFlow сенсора и где-то в другом месте коллектор, который знает все о том, что в сети происходит.
При этом не должно создаваться лишней нагрузки на сеть данными, которые мы пересылаем в коллектор, то есть простое зеркалирование трафика на анализатор не подходит.
Элементы в NetFlow:
Сенсор (он же Exporter) — устройство, которое собирает информацию о потоках в сети.
Обычно это L3-коммутатор или маршрутизатор, который достаточно редко (обычно раз в секунду) отправляет информацию о потоках в коллектор.
Что еще нужно знать про NetFlow:
Export пакеты — это те пакеты, которые отправляет сенсор на коллектор.
В них вся суть NetFlow. Вы, наверное, слышали про то, что NetFlow бывает разных версий — так вот, формат этих export пакетов — главное различие между версиями.
Версии NetFlow: v1, v5, v8, v9. v9 — самая распространённая, остальные или дают ограниченную функциональность (v1, v5), или излишне сложные (v8).
В версии v9 сенсором определяется, какую информацию он может отдать, а коллектор под это подстраивается. Сенсор вместе с данными отправляет шаблон, по которому понятно, как с этими данными работать. Шаблоны очень гибкие. Подробнее можно почитать рекомендацию по NetFlow v9 в RFC 3954.
Есть еще IPFIX — на данный момент функционально тот же NetFlow v9.
Только NetFlow курируется Cisco, а IPFIX стандартизован RFC.
Из этих полей делаем вывод:
И не забываем — данное определение потока не задано жестко стандартом. По мере наших нужд можно изменять понятие потока, например сагрегировав потоки по направлениям.
Проектно-изыскательские работы
Теперь, когда про NetFlow все известно, сформулируем ТЗ:
Нужен NetFlow сенсор, такой, чтобы:
Целевые платформы обе гетерогенные: CPU + FPGA.
Зонды основаны на Altera SoC (Cyclone V) ARM процессор + небольшая FPGA. Все это на одном кристалле.
В B100 это мощный процессор (Intel Core I7) + большая FPGA (Stratix V). Между ними PCIe.
Поэтому свободы в плане Hardware/Software Co-design у нас много.
Но начнем с объяснения, почему очевидные варианты реализации не подходят.
SW Only
Мы не используем FPGA совсем. Используем программное решение для NetFlow.
Получаем очень большую гибкость, но что с производительностью?
Таким образом можно сделать вывод — да, такая реализация возможна, но:
Но кое-что полезное из рассмотрения программной реализации мы все-таки вынесли — проекты в которых можно подсмотреть нюансы реализации NetFlow сенсора:
FPGA only
Теперь перейдем к другой крайности — все на FPGA:
Но встает очень важный вопрос насчет гибкости создания NetFlow пакетов.
Вариант 1 — мы отказываемся от возможности изменять шаблоны NetFlow v9. Мы пишем генератор на FPGA, который может отправлять данные только по одному шаблону.
Если мы захотим сменить шаблон — придется переписывать этот FPGA модуль. Такой подход нас не устраивает, потому что разные коллекторы могут по-разному работать с NetFlow и иногда не совсем хорошо воспринимают различные поля: например некоторые поля NetFlow v9 пакета имеют размер, который может быть переопределен шаблоном, но не все коллекторы к этому готовы, они ждут, что это поле будет константного размера.
Вариант 2 — мы реализуем динамическое изменение шаблонов в FPGA. Это возможно, но такой модуль будет занимать очень много ресурсов. Помимо этого его разработка займет очень много времени как на сам модуль, так и на его отладку.
И еще один минус такой реализации: в стандарте говорится, что для транспорта NetFlow export пакетов может быть использован не только UDP, но SCTP. А это значит, что если мы захотим поддержку такой функциональности — мы должны будем реализовать половину сетевого стека на FPGA.
SW + HW
Теперь, когда мы убедились, что только FPGA или только програмные реализации для данной задачи не подходят, перейдем к совместному решению.
Функциональные блоки
Чтобы было удобнее искать решение, сделаем следующее:
На этой схеме представлены основные функциональные блоки NetFlow сенсора:
Что нам дало такое разбиение:
Теперь, имея в виду эту схемку, перейдем к вариантам:
Вариант 1
Пока мы точно знаем следующее:
Вся часть аккумуляции от приема пакета до записи в память должна происходить на FPGA.
Предположим, на этом вся работа FPGA заканчивается: память, где хранятся потоки — общая. К ней имеет доступ soft и он сам производит проверку потоков в памяти и их вычитывание.
В этом случае у нас остается проблема большой нагрузки на CPU при большом числе потоков, но и вдобавок к этому, появляется новая проблема — коллизии доступа к памяти: FPGA может захотеть обновить информацию о потоке, который soft собрался вычитывать, в этом случае будет очень просто потерять часть сведений о потоке.
У данной проблемы есть решения, но они потребуют дополнительного усложнения архитектуры.
Вариант 2
Тогда идем чуть дальше — память остается общей, но проверкой потоков занимается FPGA (регулярно вычитывает и проверяет таймеры потоков). Как только поток необходимо экспортировать — FPGA сообщает в soft указатель на этот поток. Нагрузку с CPU мы сняли, но проблема коллизий не решилась.
Вариант 3
Идем еще дальше — когда FPGA вычитало поток из памяти и поняло, что это поток на экспорт — оно само удаляет поток из памяти и отправляет его в soft (используя любой доступный интерфейс).
В таком случае память больше не должна быть общей, коллизии мы можем решать внутри FPGA на этапе разрешения доступа к памяти.
А формированием export пакетов NetFlow занимается программная часть, которая может быть изменена на работу с любым протоколом.
Последний вариант нас нас устроил. Можно переходить к созданию proof of concept на базе SoC платформы.
Реализация
Перед реализацией предъявим к ней некоторые требования:
Все это привело нас к следующей реализации:
Avalon Streaming Interface — интерфейс для передачи потоков данных внутри FPGA. Используется в IP-core от Altera. Может быть использован в варианте непрерывного потока данных или пакетной передачи данных (используются сигналы начала/конца пакета). Подробнее можно почитать тут: Avalon Interface Specifications.pdf
NetDMA — тоже наша IP-core — DMA контроллер, который принимает Avalon-ST пакеты и пишет их в память по дескрипторам. Для того, чтобы снабжать этот DMA дескрипторами, у нас уже есть драйвер. Сейчас этот DMA и драйвер используются в нашем сетевом стеке.
Simple NetFlow Accumulator — та самая IP-core NetFlow сенсора. Она занимается детектированием потока. Чтением и обновлением информации в памяти по каждому принятому пакету, постоянной проверкой памяти на наличие потоков на экспорт и арбитражем запросов к памяти при добавлении и проверки.
Структура хранения данных потоков
Для хранения данных используется самая простая структура — хеш-таблица без механизма решения коллизий.
Результат вычисления хэш-функции потока мы рассматриваем как сдвиг в памяти, по которому надо расположить соответственные сведения.
При добавлении нового потока мы считаем от него хеш, вычитываем из памяти по нужному индексу и проверяем, что это действительно он. Если мы ошиблись (случилась коллизия хеш-функции), то заставляем ядро проверки NetFlow вычитать этот поток из памяти. Да, его таймеры еще не истекли и он еще должен бы храниться в памяти, но таков наш самый простой метод борьбы с коллизиями. Минусы такого подхода:
Первая проблема решаемая: чем ниже вероятность коллизий, тем меньше возможный всплеск нагрузки.
Вторая проблема может быть решена в программной части, если там будет реализован свой небольшой буфер для хранения таких преждевременных отправок.
Выбираем хеш
В качестве хеш-функции в данный момент используется CRC32 от полинома 0x04C11DB7 (это тот, который используется в Ethernet). Конечно у нас была идея подобрать более интересную хеш-функцию, которая давала бы меньше коллизий. Но моделирование показало, что с CRC32 все в порядке.
Для моделирования мы сделали простейшую хеш таблицу на python, которая содержит позиций (такой размер показался нам наиболее подходящим для первой реализации, потому на нем и тестируем хеш-функции). То есть от полученного значения хеш-функции используется только 20 бит, чтобы определить позицию в таблице.
Мы также написали скрипт-генератор, который создает уникальных слова по 17 байт (именно столько получается данных из полей, уникальных для потока).
Эти данные мы добавляем в нашу таблицу, с разными хеш-функциями:
Полиномы CRC32 0xEDB88321 и 0x82608EDB — это преобразования полинома 0x04C11DB7. В одном из прошлых проектов мы использовали такие CRC функции для быстрой генерации большого числа разных хешей. Решили их проверить заодно и здесь.
LookUp3 была выбрана потому, что это функция специально создана для хеш-таблиц и содержит в себе она вполне терпимые для FPGA опрерации — сложение и сдвиг.
MurMurHash3 была выбрана не только из-за классного названия, но и как пример мультипликативной функции, которую будет достаточно дорого реализовывать в FPGA, но которая должна, в теории, дать лучшее заполнение таблицы.
После добавления каждого нового слова в каждую из таблиц мы сохраняли уровень заполненности таблицы, чтобы построить такой график:
Как видно из графика — на наших данных никаких значимых различия нет.
Так что CRC32 вполне подходит нам, пока мы не решим изменить размер данных, от которых считаем хеш, или пока не захотим защититься от умышленной атаки на заполенение нашей таблицы.
Для тестовой платформы была выбран одина из платформ с SoC’ом на борту и двумя сетевыми интерфейсами, смотрящими в FPGA.
Пакеты, которые попадут в NetFlow, берутся из транзита — когда пакет отправляется с одного порта на другой через FPGA. Включение и выключение траниза уже реализовано на этой платформе.
Таким образом, можно создавать нагрузку до 2 Гб/c и при этом контролировать число отправленных на NetFlow пакетов.
На выбранной платформе у FPGA и CPU общая память. Чтобы отделить ту память, с которой будет работать только FPGA (для хранения пакетов), ядру Linux при загрузке ограничивается видимая область памяти, так, чтобы нам хватило оставшейся для хранения 1 миллиона потоков
Для создания самих export пакетов написали свою простую python утилиту, которая с помощью библиотеки scapy слушает сетевой интерфейс, по которому приходят данные о потоках. С помощью этой же библиотеки она формирует NetFlow Export пакеты и отправляет их.
Заключение
Производительность
Данная реализация NetFlow, в теории, «упирается» только в пропускную способность памяти (в одной из статей мой коллега Des333 производил практический расчет этой пропускной способности на SoC платформе и получил цифры в 20 Гб/c, подробнее можно почитать в его статье тут)
Хватит ли нам 20 Гб/c?
Добавление каждого пакета для нас — это чтение 45 байт из памяти и запись 76.
В худшем случае Ethernet трафик на 1G интерфейсе может создавать нагрузку в 1488095 пакетов в секунду (пакеты по 64 байта на line rate).
Таким образом, мы создадим нагрузку на память в 1.44 Гб/c. Остальную пропускную способность можем отдать на проверку потоков.
Но в текущей реализации производительность намного меньше: на практике мы не справляемся с худшим случаем line rate (пакеты по 64 байта) и часть пакетов не попадает в статистику. Оценить проблему в цифрах можно в симуляции, где придельная, при текущих настройках памяти, нагрузка без потерь
1420000 пакетов в секунду. Это соответствует line rate в случае пакетов размером 69 байт.
Связано это с тем, что аккумулятор работает последовательно — он сначала полностью обрабатывает каждый пакет, а только потом берется за следующий.
Помимо этого, задержка DDR3-памяти получилась достаточно большой (интерконнект, автоматически сгенерированный средой разработки + использование IP-core Stream SDRAM Ctrl дало
15 тактов задержки
между запросом на чтение и получением данных на частоте 62.5 МГц).
Решением данной проблемы является использование конвейера при добавлении данных в память. То есть мы запрашиваем данные на чтение, и, пока ждем ответа, запрашиваем чтение для следующего потока (и так до 15 раз).
Также можно увеличить частоту, на которой работает Simple NetFlow IP-core и весь доступ к памяти.
Known Issues
Это только PoC и в связи с этим имеется ряд ограничений, таких как:
Мы не следим за концом потока по IP флагам (только по таймерам), хотя NetFlow подразумевает, что это наша задача;
На этом, в общем-то и все. Спасибо, что дочитали до конца.
Буду рад ответить на возникшие вопросы в комментариях.
Кстати, мои коллеги из системной группы успели преобразовать те наброски из python утилиты для тестирования в приличный драйвер для Linux и демон на Rust’е, который занимается формированием пакетов для NetFlow.
Возможно когда-нибдуь они об этом что-нибудь напишут. Но пока они отдыхают после статьи про другую нашу совместную работу — ускорение AES шифрования. Если интересно, можно почитать тут.