Как написать свой анализатор для netflow
Перейти к содержимому

Как написать свой анализатор для netflow

  • автор:

What is Netflow, and Why Would I Want It?

Netflow is a network traffic summary mechanism originally developed by Cisco for the purpose of monitoring network traffic loads for billing. In its simplest form, Netflow summarizes all of the “flows” — roughly the equivalent of a TCP/IP session — seen at a router and summarizes them by source and destination address and port and the layer 3 or 4 protocol. The summary metrics typically count both packets and bytes contained. Unlike PCAP, Netflow does not contain any content, and is not nearly as voluminous as unsampled PCAP, but it can still be massive when collected even on a moderate-sized network.

Netflow serves several important network and security monitoring purposes. It can tell all the IP addresses present on the network and which ports and protocols they’re using. Expanded versions of Netflow also expose the network interfaces and subnets in use. And the byte counts can give estimates of network traffic loads at specific points in the network.

For a data scientist serving a network or security operations center, Netflow is a fanstastic source of data that lends itself especially well to graph analytics and time series modeling.

Where can I get Netflow?

I’ve supported a few projects where we anticipated getting Netflow data, and wanted to get our data pipeline and analytic tool stack in place ahead of time. But finding decent Netflow samples has turned out to be pretty hard. I suppose this makes sense; if an organization made its Netflow data public, it could pose a significant security risk. It gives the layout of the active addresses, ports and protocols on your network, which is like a poor man’s version of open nmap against your network, which any good system administrator or SOC operator would not allow. So from this author’s vantage point, there isn’t much out good Netflow data on the web.

However, there are a few ways to get your own. The rest of this post will walk through one of the easiest and safest ways to do it.

Setting Up a Netflow Generator

For our purposes, a Netflow data pipeline has three basic components: the Netflow daemon running on the router, an nfcapd process elsewhere listening for and configured to receive the raw Netflow datagrams, and an nfdump batch job that converts the raw Netflow binaries from nfcapd into human-readable .csv files. However, because we don’t want to share our real Netflow with the world, we are going to use a sythetic Netflow generator that will replace the Netflow daemon. This generator comes complements of the nflow-generator project on Github.

Netflow Generator

The project’s installation instructions list two possible methods of use: via Docker or by local installation and execution. Here we will go through the latter, which first requires installing the Go language on your machine if not already installed. It can be downloaded and installed from https://golang.org/dl/, after which, you might need to update your PATH variable (e.g. in your .bashrc or .bash_profile file) by adding /usr/local/go/bin to it. Then, from the command line,

Once you have Go installed, you can proceed to install nflow-generator in a directory of your choosing:

We will come back shortly to actually run the generator once we have the receiving tools in place.


Both nfcapd and nfdump must be loaded onto your system from a repository. On a Mac system, this is as easy as

Once that’s done, you need to turn on the nfcapd processor to listen for Netflow on a specific port, and tell it where and how to write the output. I opted to use a subdirectory structure of year/month/day/hour, specified by the -S 2 option, and to bind on host using the -b flag, but otherwise left the default settings intact.

Now, with nfcapd listening, we can turn on the Netflow generator, going back to the directory where we’ve installed it. In a Linux or Mac environment, if you’re running both the generator and nfcapd on the same machine, just kick off the two processes in separate terminal windows.

When you’re done collecting the Netflow samples, you can just kill the generator process in the terminal window, and do the same for nfcapd.


In a production setting, nfdump works well as a crontab job on the same machine as nfcapd set at regular intervals, typically at least five minutes apart. But the Netflow generator we’re using is not going to generate so much traffic that you can’t read several hours of it into a standard Python or R session, so you can do something as simple as run nfdump on an hour or two of the generated Netflow.

As I mentioned before, there are many options for formatting the output files. You can read all about them at the man page. Here, we’ll use the default format in .csv files, with no reporting or summary statistics added (only source/dest IP and ports, plus protocol, and the byte and packet counts, for each flow).

Next Steps

Conducting analysis on Netflow is great fun, but beyond the scope of this post. I will say that I’ve found Apache Spark to be a natural choice for doing any analysis on Netflow at scale. I also highly recommend Michael Collins’ book, Network Security Through Data Analysis, which devotes an entire chapter to the topic.

I hope this was useful for getting started on Netflow setup and analysis. I’d love any feedback you have!

NFStats — анализ netflow данных для ISP «на коленке»

Приветствую! Продолжая рубрику «на коленке» (написал два года назад одну статью и уже рубрика), наконец у меня появилось время рассказать еще об одном проекте (а заодно и привести его в порядок), который используется у нас на сети небольшого транзитного провайдера для сбора и анализа статистики сетевого трафика .

Как и при анализе Ddos атак (link) проект использует в своей основе набор утилит flow-tools для сбора Netflow данных с сетевого оборудования. NFStats позволяет просматривать статистику в разрезе BGP автономных систем, IP-адресов, интерфейсов через web-интерфейс, что весьма полезно при балансировке трафика и общего понимания какой трафик проходит через/в/из вашу/ей AS. По описанию можно заметить сходство с Ntopng, однако NFStats предоставляет несколько иную статистику, более подходящую ISP.

Проект написан на python3 с использованием фреймворка django. Для отображения статистики используются google charts. Проект на Github



Чтобы развернуть NFStats, как ранее было сказано, для начала нужно установить пакет утилит flow-tools. Во FreeBSD он доступен как пакет и из портов. В прошлой статье (link) я немного останавливался на описании и настройке flow-tools во FreeBSD и на оборудовании.

Для GNU/Linux его можно собрать только из исходников. Поэтому здесь можно разобрать это подробнее на примере Ubuntu.

Установка Flow-tools в Ubuntu

Папка для данных netflow

Далее нужно создать сервис flow-tools в systemd. Информацию по поводу флагов можно почитать в мануале flow-capture. Важно здесь -n 1439, что заставляет flow-capture создавать каждую минуту новый файл с данными.

Перегружаем и включаем сервис

Кроме FreeBSD или GNU/Linux со flow-tools нам понадобятся:

SNMP клиент и настроенный протокол snmpv2c на сетевом оборудовании

Python 3.6 или выше (Для GNU/Linux также нужен пакет соответственно python3.6-venv или выше для виртуального окружения)

PostgreSQL 9.6 или выше

MySQL 5.7 или выше

Oracle Database Server 12.2 или выше. Version 6.0 or higher of the cx_Oracle Python driver is required.

WSGI сервер (Apache с mod-wsgi-py3, Nginx с uwsgi, Gunicorn и т.п)

Перейдем непосредственно к установке приложения

Загружаем проект и подготавливаем виртуальное окружение.

Далее, в активированном виртуальном окружении! необходимо установить адаптер для используемой вами СУБД. Например для Postgres:

Создаем файл настроек для Django

Вносим в него необходимые изменения

Далее необходимо провернуть небольшой финт ушами для инициализации БД.

Сначала комментируем в URL диспетчере Django /var/www/nfstats/nfstats/nfstats/urls.py подключение url’ов приложения

Затем запускаем миграцию БД (Также в активированном виртуальном окружении)

И снова подключаем url в /var/www/nfstats/nfstats/nfstats/urls.py

Создаем файл /var/log/nfstats.log с правами на чтение для пользователя под которым будет запущено web приложение (например www-data для Apache). Соответственно он должен иметь также права на чтение для папки /var/www/nfstats


Проверяем также, чтобы к /var/www/nfstats/nfstats/flow-tools доступ на чтение имел пользователь flow-tools.

Добавляем проект в настройки web-сервера. Пример для Apapche:

Cкрипт /var/www/nfstats/nfstats/bin/interface_speed.py необходимо добавить в CRON на ежеминутное исполнение

Данный скрипт записывает скорости интерфейсов, на которых настроен съем статистики netflow (так называемый sampling) в базу данных. Эти значения используется для пересчета данных собранных flow-tools, что позволяет отображать правдивые данные относительно скорости даже при условии, что семплинг на оборудовании настроен не один к одному, а к примеру 1:2000 (то есть анализируется один из 2000 пакетов). Так, к примеру, советует Juniper для 10G интерфейсов. Это позволяет экономить ресурсы оборудования и место на диске.

На этом разворачивание приложения закончено.

Можно переходить к nfstats.example.com

При первом открытии вас перенаправит на страницу настроек, где нужно будет добавить сетевое оборудование на котором настроен netflow с указанием где лежат данные, собранные flow-tools.

На вкладке «System» можно отредактировать настройки связанные с SNMP, директориями, логированием. History — количество дней, которые будут храниться данные о скоростях (зависит от настроек flow-capture и объема собираемых данных)

Далее, на вкладке «Interfaces» необходимо пополнить базу интерфейсов с оборудования. Жмем на «Read SNMP» и добавляем необходимые интерфейсы (обычно все). Тут надо отметить, что в списке появятся только те интерфейсы, на которых настроен «description» на оборудовании

Отмечаем среди них те, на которых включен sampling (т.е. те, с которых снимается netflow). Обычно это будут Uplink интерфейсы, т.е будут собираться данные о трафике, который поступает и который уходит из нашей автономной системы.

Ну, и наконец использование.

Переходим на nfstats.example.com. На вкладке «Common Stats» отображается статистика по автономным системам. Так называемые pie-charts интерактивны, при нажатии на номер AS отобразится ее имя в базе Ripe. Direction меняет направление трафика. Input — входящий в интерфейс трафик, Output — соответственно исходящий.

«BGP AS» — показывает распределение трафика по интерфейсам для конкретной source и/или destination AS.

«Interface» отображает похожее распределение только для определенного интерфейса. Здесь можно выбрать или ввести snmpid только тех интерфейсов, для которых НЕ! включен сэмплинг.

И «IP» — топ статистика по ip-адресам с возможностью различной фильтрации. При клике на отдельный «bar» также выводится информация о названии сети и кнопка «show traffic», которая позволяет просмотреть подробный вывод netflow данных для выбранного ip-адреса

Стоит отметить основной недостаток этого проекта, он вытекает из недостатка flow-tools — отсутствие поддержки netflow 9й версии. Что влечет за собой отсутствие поддержки 32 битных номеров AS. Все «длинные» ASN будут отображаться как AS23456. Что весьма прискорбно. Поэтому в будущем планы на написание собственного netflow коллектора.

Как видите, я постарался как можно подробнее описать процесс установки и использования (что было в моих силах). Кое-какую документацию я положил и в репозиторий на Github.

Разбор пакетов NetFlow v.9 на C#

NetFlow это сетевой протокол, созданный компанией Cisco Systems для учёта сетевого трафика. Наиболее распространёнными версиями данного протокола являются 5 и 9. Девятая версия более гибкая так как используются шаблоны, согласно которым присылаются данные. В пятой версии данные присылаются согласно спецификации.

  • Сенсор. Устройство (маршрутизатор, L3-коммутатор) собирающее статистику по проходящему через него трафику;
  • Коллектор. Занимается сбором данных от сенсора и помещает их в хранилище;
  • Анализатор. Анализирует данные, которые собрал коллектор и формирует отчёты.

О разработки части функций анализатора на C#, а точнее разбор пакетов NetFlow я и расскажу

В качестве сенсора был использован MikroTik маршрутизатор.

Включаем на нем NetFlow для ether1 интерфейса:
/ip traffic-flow set enabled=yes interfaces=ether1

И добавляем коллектор (как правило, коллектор слушает порт 2055, 9555 или 9995):
/ip traffic-flow target add disabled=no version=9 address=

Или тоже самое но через WinBox:

Теперь на компьютер с IP адресом на 9995 порт по UDP (или SCTP) будут приходить пакеты NetFlow 9 версии. Пакеты приходят и есть с чем работать.

Разбор приходящих пакетов
  1. Packet Header (20 байт) — заголовок пакета, в единственном экземпляре с полями:
    • Version Number (UInt16 — 2 байта) — номер версии NetFlow, у нас всегда 9;
    • Count (UInt16 — 2 байта) — общее количество записей. Далее по тексту статей с этим полем было приключение;
    • sysUpTime (UInt32 — 4 байта) — время в миллисекундах со старта устройства — UpTime;
    • UNIX Secs (UInt32 — 4 байта) — время в секундах с 0000 UTC 1970, при котором отправили пакет;
    • Sequence Number (UInt32 — 4 байта) — счетчик переданных пакетов, он постоянно увеличивается от пакета к пакету, тем самым можно проверить потерялись ли пакеты между ними;
    • Source ID (UInt32 — 4 байта) — номер потока данных, деле в том, что со стороны сенсора могут идти несколько потоков данных.

  2. FlowSet (N-20 байт) — шаблоны, данные… FlowSet`ов может быть несколько или один. В каждом FlowSet`е есть два неизменных от типа передаваемых данных (шаблон, данные) поля:
    • FlowSet ID (UInt16 2 байта) — для шаблона это всегда 0, для опционального шаблона 1, для данных он равен Template ID и следовательно больше 255 (от 256 до 65535);
    • Length (UInt16 2 байта) — размер всего FlowSet вместе с полями FlowSet ID и Length;
    • Другие поля в зависимости от типа передаваемых данных.

  • Template ID (UInt16 2 байта) — уникальный ID для каждого шаблона по которому передаются данные. Число от 256 до 65535;
  • Field Count (UInt16 2 байта) — количество полей в шаблоне. Далее идут поочередно тип поля (Field Type) и размер (Field Length);
  • Field Type (UInt16 2 байта) — число определяющее тип поля. Все типы есть в спецификации протокола;
  • Field Length — длинна поля в байтах.
  • Данных… данных которые соответствуют полям и их размерам;
  • Padding — нули заполняющие до границы в 4 байта.

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

Составил UML диаграмму классов (с помощью NClass):
или в pdf
И написал библиотеку для разбора приходящих пакетов.
Основной класс с которого все начинается, это Packet. Его единственный конструктор принимает входящий пакет NetFlow в байтах и объект класса Templates, представляющий из себя список текущих Template (шаблонов).

Далее в конструкторе класса Packet вызывается функция Parse, которая принимает объект класса Templates.
В этой функции идет разбивка пакета на заголовок — 20 байт и дальнейшая работа с ним через класс Header; на FlowSet`ы и передача каждого FlowSet`а на обработка соответствующему классу FlowSet.

Ввиду того, что FlowSet`ов может быть несколько, приходится вторую часть пакета (без 20 байт заголовка), анализировать и разбивать на разные FlowSet`ы. Примечательно что в MikroTikFlowSet`ы в единственном экземпляре в пакете, а вот пользуясь Netflow Simulator in C# удалось поработать с пакетами с несколькими FlowSet`ами в пакете. Кроме того благодаря ему был найден забавный баг в реализации NetFlow v9 на MikroTik`е, о чем подробнее тут.

Netflow Simulator in C#:

Вот участок кода разбивающий часть пакета на FlowSet`ы:

В классе Header идет разбор заголовка пакета на его поля. Прежде чем это сделать, выполняется реверсия заголовка:

Далее конвертируем биты в тот тип поля, которым он является, например поле version:

Да в Header поля sysUpTime имеет тип TimeSpan, приводим к этому типу:

и поле UNIX Secs имеет тип DateTime:

Перейдем к обработке FlowSet`ов. После получения полей FlowSet ID и Length идет разбор остальных полей в зависимости от FlowSet ID. Если он равен 0 или 1 то это шаблон, а если это число от 256 до 65535 то это данные.

Если это шаблон то передаем его обработку классу Template после чего проверяем наше хранилище шаблонов (объект класса Templates) на наличие шаблона с таким же ID и заменяем его, иначе просто добавляем шаблон.

Если это данные то проверяем есть ли в хранилище (объект класса Templates) такой шаблон (FlowSet ID == Template ID) и если есть то копируем этот шаблон функцией DeepClone и заполняем его поля — Field, иначе ничего не делаем, ведь без шаблона это просто набор байтов.

функция DeepClone:

  • Type — тип;
  • Length — размер;
  • Value — значение.

Причем Field в Template в хранилище находятся без параметров Value т.е. Value пусты, а вот при обработке пакетов Template в FlowSet в объекте Packet уже содержит поля Value.

Кроме всего этого есть еще перечисление FieldType — перечисление в котором имени типа соответствует номер данного типа. (параметр Type в Field)

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

Создаем сокет и слушаем по UDP 9995 порт на нашем ПК. _templates — это наше хранилище шаблонов. Каждый приходящий пакет мы скармливаем объекту packet класса Packet передавая еще и наше хранилище шаблонов. А далее выполняем packet.ToString() Это перегруженная функция выводит нам содержание пакета и нужна только для проверки, что у нас все получается.

На этом с библиотекой все, теперь ее можно использовать для дальнейшего написания Анализатора трафика по NetFlow протоколу.

Пример с MikroTik:

Получили пакет без наличия шаблона в хранилище:

Получили шаблон от сенсора:

Получили данные, для которых есть шаблон в хранилище:

Ошибка реализации NetFlow v9 в MikroTik

т.е. содержит все записи, во всех FlowSet`ах, а в MikroTik`е данное поле всегда равно 1 (см. скрины выше), даже если передается несколько шаблонов или данных. т.е. по логике MikroTik`а поле Count = количеству FlowSet`ов (о чем они мне и написали в письме и видно по скринам), а должно быть равно общему количеству всех шаблонов и данных, как звучит в спецификации. По этой причине использовать в разборе пакетов поле Count чревато.

Вот же пример от Netflow Simulator in C# (Хотелось бы получить данные и от Cisco, но у меня нет такой возможности, может кто из читателей проверит это):

Получили пакет без наличия шаблона в хранилище (обратите внимание на Count):

Получили шаблон от сенсора (тут одновременно два FlowSet`а пришло, что в MikroTik`е не бывает. Обратите внимание на Count он равен 7 = 1 шаблон и 6 записей с данными. По логике MikroTikCount должен был бы равен 2 = 2 FlowSet`а):

Получили данные, для которых есть шаблон в хранилище (обратите внимание на Count):

Ну и еще раз пакет в Wireshark Помечено поле Count:

Еще раз: буду очень благодарен всем кто пришлет скрин с Wireshark`ом от Cisco. Вставлю его сюда.

Исходный код доступен здесь.

Сегодня (19:05 30/07/2013)

MikroTik ответил:

MikroTik support [Dzintars] support@mikrotik.com

Thank you for reporting a problem (the author of the article correctly pointed out
that count value in netflow packet header not always is set correctly). The
problem will be fixed in the next version of RouterOS.

Name already in use

Work fast with our official CLI. Learn more about the CLI.

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats


Failed to load latest commit information.


Python NetFlow Collector

This script is able to parse incoming UDP NetFlow packets of NetFlow v9 and v5. It used [NetFlow v9 Collector] (https://github.com/bitkeks/python-netflow-v9-softflowd) script of Dominik Pataky (dev@bitkeks.eu) as a basis.

Using the collector and analyzer

In this repo you also find main.py and analyze_json.py .

To start an example collector run python3 main.py -p 9000 -D . This will run a collector at port 9000 in debug mode. Point your flow exporter to this port on your host and after some time the first ExportPackets should appear (the flows need to expire first).

After you collected some data, main.py exports them into JSON files, simply named <timestamp>.json .

To analyze the saved traffic, run analyze_json.py <json file> . In my example script this will look like the following, with resolved hostnames and services, transfered bytes and connection duration:

Feel free to customize the analyzing script, e.g. make it print some nice graphs or calculate broader statistics.

I have specifically written this script in combination with NetFlow exports from softflowd v0.9.9 — it should work with every correct NetFlow v9 implementation though.


NetFlow v9 parser, collector and analyzer implemented in Python 3. Developed to be used with softflowd v0.9.9

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *