Packages

Simple netflow to prometheus converter and pre-analyzer

Current section

Files

Jump to
erlflow README_RU.md
Raw

README_RU.md

Обзор
=====
erlflow предназначен не столько для сбора статистики по всем сетевым соединениям (хотя и это возможно), сколько для
отслеживания определенных сетевых взаимодействий и группировки информации от множества netflow потоков в конкретные
метрики по определенному правилу.
Постановка задачи
=====
В протоколе netflow (здесь и далее имеется в виду netflow v5) поток является короткоживущей сущностью, которая однозначно
идентифицируется по следующим параметрам:
- адрес источника
- адрес назначения
- порт источника
- порт назначения
- протокол, инкапсулированный в IP
- тип сервиса
- штамп времени первого пакета в потоке
Очевидно, что при регулярном взаимодействии одних и тех же сетевых сущностей (например сервисов) будет всегда меняться
штамп времени первого пакета, а также, как правило, один из портов взаимодействия. Даже если опустить штамп времени и
просто отобразить остальные параметры потока в метки метрики, то будет создаваться множество временных рядов, что создает
неудобства при дальнейшей обработке информации. Гораздо более удобным представляется введение понятия
"направление взаимодействия", которое, в зависимости от задачи, может расширять понятие "потока". Например, можно считать
все пакеты/байты, переданные между хостами, без учета остальных параметров, или учесть пакеты/байты переданные одним
приложением в одной метрике, а остальные учесть в другой или вообще не учитывать.
Пример:
Допустим имеется сеть из нескольких инстансов SIP-серверов. Сервера взаимодействую по "внутренней" сети 100.127.0.0/24,
для установления связи между собой используют протокол TCP и порт 5080, а для медиа-трафика UDP и диапазон портов
40000-41900. Клиенты устанавливают соединения на "внешние" адреса (например 88.127.127.0/24) и UDP порт 5060, для
медиа-трафика используется диапазон портов 40000-40100. Задача: отслеживать нагрузку на сеть по всем межсерверным
соединениям попарно, нагрузку от клиентов суммировать по каждому серверу отдельно.
![scheme](https://codeberg.org/ttt161/erlflow/raw/branch/master/pic/scheme.png)
Решение
=====
Для решения задачи нам нужно описать правила фильтрации (группировки) потоков, а также правила формирования меток для метрик.
Фильтр для межсерверного взаимодействие описывается следующим набором условий:
```
src_addr=100.127.0.0/24 dst_addr=100.127.0.0/24 proto=tcp port=5080 (параметр port описан ниже)
src_addr=100.127.0.0/24 dst_addr=100.127.0.0/24 proto=udp src_port=40000-41900 dst_port=40000-41900
```
Для попадания статистики переданных пакетов/байт в одну метрику мы должны оставить значимые параметры
(src_addr, dst_addr, так как задача учесть все взаимодействия попарно) и исключить динамически меняющиеся
(proto, port, src_port, dst_port, tos). Вместо исключенных параметров необходимо добавить дополнительную метку (или метки),
которые позволят идентифицировать метрику, как взаимодействие SIP серверов, например, application="SIP",direction="service-service"
Фильтр для взаимодействия клиент -> сервер:
```
src_addr!=88.127.127.0/24 dst_addr=88.127.127.0/24 proto=udp dst_port=5060
src_addr!=88.127.127.0/24 dst_addr=88.127.127.0/24 proto=udp src_port=40000-41900 dst_port=40000-41900
```
Значимые параметры: dst_addr. Дополнительные метки: application="SIP",direction="client-service"
Фильтр для взаимодействия сервер -> клиент:
```
src_addr=88.127.127.0/24 dst_addr!=88.127.127.0/24 proto=udp src_port=5060
src_addr=88.127.127.0/24 dst_addr!=88.127.127.0/24 proto=udp src_port=40000-41900 dst_port=40000-41900
```
Значимые параметры: src_addr. Дополнительные метки: application="SIP",direction="service-client"
Реализация
=====
Правила фильтрации и тегирования задаются в файле config/config.yml (путь может быть переопределен в sys.config через
параметр config_path, подробное описание конфигурационного файла см. ниже). Для примера выше config.yml выглядит так:
```yml
- src_addr:
match: 100.127.0.0/24
dst_addr:
match: 100.127.0.0/24
proto:
match: 6
port:
match: 5080
action:
key_suffix: _sip_srv
attributes:
- src_addr
- dst_addr
ext_attributes:
application: SIP
direction: service-service
- src_addr:
match: 100.127.0.0/24
dst_addr:
match: 100.127.0.0/24
proto:
match: 17
src_port:
match: 40000-41900
dst_port:
match: 40000-41900
action:
key_suffix: _sip_srv
attributes:
- src_addr
- dst_addr
ext_attributes:
application: SIP
direction: service-service
- src_addr:
dismatch: 88.127.127.0/24
dst_addr:
match: 88.127.127.0/24
proto:
match: 6
port:
match: 5060
action:
key_suffix: _sip_upstream
attributes:
- dst_addr
ext_attributes:
application: SIP
direction: client-service
- src_addr:
dismatch: 88.127.127.0/24
dst_addr:
match: 88.127.127.0/24
proto:
match: 17
src_port:
match: 40000-41900
dst_port:
match: 40000-41900
action:
key_suffix: _sip_upstream
attributes:
- dst_addr
ext_attributes:
application: SIP
direction: client-service
- src_addr:
match: 88.127.127.0/24
dst_addr:
dismatch: 88.127.127.0/24
proto:
match: 6
src_port:
match: 5060
action:
key_suffix: _sip_downstream
attributes:
- src_addr
ext_attributes:
application: SIP
direction: service-client
- src_addr:
match: 88.127.127.0/24
dst_addr:
dismatch: 88.127.127.0/24
proto:
match: 17
src_port:
match: 40000-41900
dst_port:
match: 40000-41900
action:
key_suffix: _sip_downstream
attributes:
- src_addr
ext_attributes:
application: SIP
direction: service-client
```
Таким образом, для нашего примера независимо от того, сколько параллельных соединений установят сервера между собой и
сколько бы ни было клиентских соединений мы получим 12 временных рядов (и еще 12 с ключом netflow_packets_sent_):
````
netflow_bytes_sent_sip_srv{src_addr="100.127.0.1",dst_addr="100.127.0.2",application="SIP",direction="service-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_srv{src_addr="100.127.0.1",dst_addr="100.127.0.3",application="SIP",direction="service-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_srv{src_addr="100.127.0.2",dst_addr="100.127.0.1",application="SIP",direction="service-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_srv{src_addr="100.127.0.2",dst_addr="100.127.0.3",application="SIP",direction="service-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_srv{src_addr="100.127.0.3",dst_addr="100.127.0.1",application="SIP",direction="service-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_srv{src_addr="100.127.0.3",dst_addr="100.127.0.2",application="SIP",direction="service-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_upstream{dst_addr="88.127.127.1",application="SIP",direction="client-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_upstream{dst_addr="88.127.127.2",application="SIP",direction="client-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_upstream{dst_addr="88.127.127.3",application="SIP",direction="client-service",sensor="127.0.0.1"}
netflow_bytes_sent_sip_downstream{src_addr="88.127.127.1",application="SIP",direction="service-client",sensor="127.0.0.1"}
netflow_bytes_sent_sip_downstream{src_addr="88.127.127.2",application="SIP",direction="service-client",sensor="127.0.0.1"}
netflow_bytes_sent_sip_downstream{src_addr="88.127.127.3",application="SIP",direction="service-client",sensor="127.0.0.1"}
````
![metrics](https://codeberg.org/ttt161/erlflow/raw/branch/master/pic/metrics.png)
При добавлении новых серверов, если они будут функционировать в тех же сетях, не потребуется правка конфигурационного
файла, метрики будут появляться автоматически (хорошая практика, когда планирование сети и мониторинга идут рука об руку)))
Описание конфигурационного файла
=====
Конфигурационный файл по умолчанию config/config.yml (путь может быть переопределен в sys.config через параметр config_path).
Он состоит из списка правил для обработки потоков. netflow пакет сравнивается с каждым правилом по порядку от первого к
последнему и обрабатывается в соответствии с первым совпавшим правилом. Если параметры потока не совпали ни с одним
правилом, то поток игнорируется.
Правило содержит имена параметров потока с условиями для сравнения и описание действия, если параметры потока
соответствуют заданным условиям.
````
ParamName:
Operator: Value
````
Operator определяет как нужно сравнивать значение параметра потока с заданным Value. Для сравнения на совпадение Operator
match, для сравнения на несовпадение - dismatch.
Обрабатываемые параметры потока:
- src_addr, адрес источника, в условии можно сравнить адрес на совпадение или несовпадение с ipv4 префиксом
Пример:
````
src_addr:
match: 10.0.0.0/24
````
- dst_addr, адрес назначения, условие задается аналогично src_addr
- src_port, порт источника, условие может принимать одно значение или диапазон, значение должно быть в диапазоне 1-65535
- dst_port, порт назначения, аналогично src_port
Пример:
````
src_port:
match: 10080
dst_port:
dismatch: 10010-10020
````
- port, альтернативный способ проверки номера порта для одноранговых взаимодействий, когда целевой порт может принадлежать не только
серверу, а любой из взаимодействующих сторон. Вычисляется следующим образом: если min(src_port, dst_port) < min(ephemeral_ports),
то port=min(src_port, dst_port) иначе (то есть если оба порта динамические) port=0. Диапазон динамических (ephemeral) портов
по умолчанию 49152-65535, но может быть переопределен в sys.config в параметре ephemeral_range ({ephemeral_range, {49152, 65535}}).
Условие задается аналогично src_port, dst_port
- proto, номер протокола, инкапсулируемого в IP, может принимать значения 1-252
- tos, тип сервиса, может принимать значения 0-255
Важно! В правиле обязательно должно быть задано условие хотя бы для одного параметра потока!
Действие определяет в какой метрике будет учитываться количество байт/пакетов, переданных в потоке. Для этого необходимо
задать суффикс для ключа метрики, определить список параметров потока, которые будут отображены в метки метрики, а также
указать дополнительны метки. Обязательным является только суффикс для ключа метрики.
Пример:
````
action:
key_suffix: _some_string
attributes:
- src_addr
- dst_addr
ext_attributes:
label: value
````
Если attributes не определены, то по умолчанию будут использованы: src_addr, dst_addr, proto, port, tos.
Важно!!! Если вы задаете одинаковый key_suffix для нескольких правил, то значения attributes и ext_attributes в этих правилах
не должны отличаться. Если этого не сделать, то библиотека prometheus не сможет корректно обработать такие метрики.
Также action может принимать значение reject:
````
action: reject
````
В этом случае информация о потоке будет проигнорирована.