- GeoIP
- Автономные системы
- Обновление баз без перезапуска коллектора
- Утилита xegeoq
- Визуализация GeoIP-данных и названий AS с помощью Grafana
- Классификация трафика
- sFlow
- Дополнительный анализ данных с помощью sFlow: DNS и SNI
- Вложенные/иерархические объекты мониторинга
- Классификация интерфейсов
- Падение трафика ниже порога
- Изменение порогов скользящих средних без перезапуска коллектора
Небольшое общее замечание: несмотря на то, что гео-информацией часто пользуются для разных отчетов, слишком доверять этим данным не стоит. Гео-базы не всегда точны, они не покрывают все адреса, при сетевых атаках часто используют поддельные IP адреса. Используйте GeoIP с разумной осторожностью.
Коллектор рассчитан на использоание GeoIP-баз в формате https://ipapi.is/geolocation.html
Для работы GeoIP нужно скачать эти данные, сконвертировать их во внутренний формат и и поместить в специальный каталог для коллектора.
Как это сделать, по пунктам:
Получаем и распаковываем CSV-файлы с данными:
$ mkdir geo && cd geo
$ wget https://ipapi.is/data/geolocationDatabaseIPv4.csv.zip
$ wget https://ipapi.is/data/geolocationDatabaseIPv6.csv.zip
$ unzip geolocationDatabaseIPv4.csv.zip
$ unzip geolocationDatabaseIPv6.csv.zip
$ cd ..
Строим из CSV-файлов базы во внутреннем формате. Для этого используется утилита xemkgeodb
:
$ mkdir geodb
$ ./xemkgeodb -o geodb -v -t geo geo/geolocationDatabaseIPv4.csv geo/geolocationDatabaseIPv6.csv
После этого в каталоге geodb
должны появиться файлы geo4.db
и geo6.db
.
Нужно поместить эти файлы в специальный каталог коллектора. Он задается в глобальном конфиге xenoeye.conf
"geodb": "/var/lib/xenoeye/geoip"
$ cp geodb/geo* /var/lib/xenoeye/geoip/
При перезапуске коллектора (или если послать процессу коллектора сигнал -HUP
) он загрузит эти базы данных и начнут работать функции GeoIP.
Данные GeoIP можно использовать в фильтрах (создавать географические объекты мониторинга) или в полях, которые экспортируются в PostgreSQL
Это делается с помощью функций:
continent()
- двухбуквенный код континента в нижнем регистре (eu
,as
, ...)country_code()
- двухбуквенный код страны в нижнем регистре (es
,ru
,cn
, ...)country()
- полное название страныstate()
- штат (область)city()
- городzip()
- индексlat()
- широтаlong()
- долгота
Все функции принимают в качестве аргумента netflow-поле с IP-адресом.
Например, для того чтобы создать объект мониторинга, в котором будет трафик, входящий в нашу сеть и только из России, нужно сделать такой фильтр:
ingress_ru/mo.conf
:
{
"filter": "dst host our-net and country(src host) 'ru'"
/* ... */
}
Коллектор будет преобразовывать country(src host)
каждого флова в двухбуквенный код страны и сравнивать его с ru
Для того, чтобы экспортировать гео-информацию в СУБД, нужно в качестве поля использовать функцию из списка выше.
Примеры:
Объект мониторинга ingress
, в него попадает весь входящий в наши сети трафик, src-адрес преобразовывается в название страны, по каждой стране суммируются октеты и экспортируются в СУБД:
ingress/mo.conf
{
"filter": "dst net our-net",
/* ... */
"fwm": [
/* ... */
{
"name": "country",
"fields": ["octets desc", "country(src host)"]
}
]
}
Данные по странам будут экспортироваться в СУБД в таком виде:
=> select * from ingress_country limit 10;
time | octets | country_src_host_
------------------------+-------------+-------------------
2023-10-12 11:02:45+03 | 17561134000 | Russia
2023-10-12 11:02:45+03 | 3002667000 | ?
2023-10-12 11:02:45+03 | 2094074500 | United States
2023-10-12 11:02:45+03 | 2030411000 | Netherlands
2023-10-12 11:02:45+03 | 403552000 | Germany
2023-10-12 11:02:45+03 | 376779000 | Finland
2023-10-12 11:02:45+03 | 144323000 | France
2023-10-12 11:02:45+03 | 128383500 | Japan
2023-10-12 11:02:45+03 | 124174500 | Hungary
2023-10-12 11:02:45+03 | 61062500 | United Kingdom
?
означает что для этих адресов нет записей в базе GeoIP
Еще один пример. Объект мониторинга ingress_ru
, трафик в наши сети только из России. src-адреса преобразовываются в название областей, городов, по каждому элементу суммируются октеты и экспортируются в СУБД.
ingress_ru/mo.conf
:
{
"filter": "dst net our-net and country_code(src host) 'ru'",
/* ... */
"fwm": [
{
"name": "city",
"fields": ["octets desc", "city(src host)"]
}
,
{
"name": "state",
"fields": ["octets desc", "state(src host)"]
}
/* ... */
]
}
Данные, которые экспортируются в СУБД:
=> select * from ingress_ru_state;
time | octets | state_src_host_
------------------------+------------+-----------------------
2023-10-12 22:06:34+03 | 6571390500 | Москва
2023-10-12 22:06:34+03 | 2879552500 | Санкт-Петербург
2023-10-12 22:06:34+03 | 2359202000 | Ленинградская Область
2023-10-12 22:06:34+03 | 665152000 | Архангельская Область
2023-10-12 22:06:34+03 | 374177500 | Тюменская Область
2023-10-12 22:06:34+03 | 354527500 | Владимирская Область
2023-10-12 22:06:34+03 | 321759000 | Костромская Область
2023-10-12 22:06:34+03 | 131455000 | Калужская Область
2023-10-12 22:06:34+03 | 29730000 | Рязанская Область
...
=> select * from ingress_ru_city;
time | octets | city_src_host_
------------------------+------------+------------------
2023-10-12 22:06:34+03 | 6569109000 | Moscow
2023-10-12 22:06:34+03 | 2879552500 | Saint Petersburg
...
Даже если роутер не может экспортировать номера AS, их можно получить в коллекторе из IP адресов с помощью внешних баз. Кроме номеров, можно получить и названия AS.
Мы используем базы данных проекта https://github.com/sapics/ip-location-db
Это работает приблизительно так же, как и c GeoIP базами.
Нужно скачать csv-файлы с данными:
$ cd geo
$ wget https://raw.githubusercontent.com/sapics/ip-location-db/main/asn/asn-ipv4.csv
$ wget https://raw.githubusercontent.com/sapics/ip-location-db/main/asn/asn-ipv6.csv
$ cd ..
Сконвертировать во внутренний формат:
$ ./xemkgeodb -o geodb -t as geo/asn-ipv4.csv geo/asn-ipv6.csv
Если все прошло без ошибок, скопировать базы в каталог коллектора:
$ cp geodb/as* /var/lib/xenoeye/geoip/
После перезапуска коллектора (или если послать процессу коллектора сигнал -HUP), базой можно будет пользоваться.
asn()
- номер автономной системыasd()
- текстовое описание автономной системы
Так же, как и GeoIP-функции, они принимают в качестве аргумента netflow-поле с IP-адресом.
Пример, разбиваем весь входящий трафик по названиям автономных систем:
ingress/mo.conf
:
{
"filter": "dst net our-net",
/* ... */
"fwm": [
/* ... */
{
"name": "as",
"fields": ["octets desc", "asd(src host)"],
"limit": 30
}
]
}
=> select * from ingress_as;
time | octets | asd_src_host_
------------------------+------------+--------------------------
2023-10-13 11:40:46+03 | 7260510500 | PJSC MegaFon
2023-10-13 11:40:46+03 | 3816886000 | T2 Mobile LLC
2023-10-13 11:40:46+03 | 2124086000 | PJSC Rostelecom
2023-10-13 11:40:46+03 | 1551007000 | Google LLC
2023-10-13 11:40:46+03 | 1361819000 | LLC VK
2023-10-13 11:40:46+03 | 777337000 | CJSC RASCOM
2023-10-13 11:40:46+03 | 761207000 | Global DC Oy
2023-10-13 11:40:46+03 | 753907500 | Hetzner Online GmbH
2023-10-13 11:40:46+03 | 592446000 | MEGASVYAZ LLC
...
GeoIP базы и базы AS обновляются достаточно часто. Будьте внимательны: владельцы этих баз могут молча изменить формат CSV-файлов и тогда коллектор не сможет их прочитать.
Лучше обновлять GeoIP базы вручную, или как-то контролировать процесс обновления. Алгоритм обновления приблизительно такой же, как и для первого использования.
- Нужно скачать CSV-файлы
- Сгенерировать .db-файлы из CVS-файлов
- Посмотреть, все ли прошло нормально, нет ли ошибок
- Поместить новые .db-файлы в geoip-каталог коллектора
- Послать процессу коллектора сигнал -HUP, он перечитает базу
Для тестировании GeoIP и AS мы сделали утилиту xegeoq
.
Ее можно использовать для получения GeoIP-информации и информации об AS.
Утилита принимает на вход путь к базам (во внутреннем формате) и IP-адрес или список IP-адресов. Адреса могут быть как IPv4, так и IPv6
./xegeoq -i /var/lib/xenoeye/geoip 1.1.1.1 2A03:2880:10FF:0008:0000:0000:FACE:B00C
1.1.1.1 geo: oc, au, Australia, Victoria, Research, 3095, -37.7, 145.18333
1.1.1.1 as: 13335, Cloudflare, Inc.
2A03:2880:10FF:0008:0000:0000:FACE:B00C geo: ?
2A03:2880:10FF:0008:0000:0000:FACE:B00C as: 32934, Facebook, Inc.
Для того, чтобы было проще делать отчеты в Графане, мы написали такую PL/PGSQL функцию:
CREATE OR REPLACE FUNCTION xe_rep(
src TEXT,
fld TEXT,
aggr_fld TEXT,
k TEXT,
cond TEXT,
ntop INT DEFAULT 20,
unk TEXT DEFAULT '?'
) RETURNS TABLE (
tm TIMESTAMPTZ,
val BIGINT,
name TEXT
) AS $$
DECLARE
query TEXT;
select_top TEXT;
fld_t TEXT;
BEGIN
fld_t := fld || '::text';
select_top := 'SELECT
sum('|| aggr_fld || ') AS val, COALESCE (' || fld_t || ', ''Other'') AS name
FROM ' || src ||
' WHERE ' || cond || ' GROUP BY name ORDER BY val desc limit ' || ntop;
query := 'SELECT time, (sum(' || aggr_fld || ')' || k || ')::bigint AS val, COALESCE(NULLIF(name, ''''), ''' || unk || ''')
FROM (
WITH topval AS (' || select_top || ')
SELECT time, ' || aggr_fld || ', COALESCE (' || fld_t || ', ''Other'') AS name
FROM ' || src || ' WHERE ' || cond || ' AND ' || fld_t || ' IN (SELECT name from topval)
UNION ALL
SELECT time, ' || aggr_fld || ', ''Other'' AS name
FROM ' || src || '
WHERE ' || cond || ' AND ' || fld_t || ' NOT IN (SELECT name from topval)
UNION ALL
SELECT time, ' || aggr_fld || ', ''Other'' AS name
FROM ' || src || '
WHERE ' || cond || ' AND ' || fld_t || ' IS NULL
) AS report
GROUP BY time, name ORDER BY time';
RETURN QUERY EXECUTE query;
END;
$$ LANGUAGE plpgsql;
Если при создании функции не хватает прав (ERROR: permission denied for schema public
), выполните:
$ sudo su - postgres -c "psql -d xenoeyedb -c 'ALTER DATABASE xenoeyedb OWNER TO xenoeye;'"
Функция строит топ-N сущностей (стран, городов, IP-адресов и т.п.) за период и отбирает только их. Те, кто не попал в топ, группируются под названием 'Other'.
При создании панели в Графане в поле для SQL запроса можно написать вызов этой функции:
select tm as time, val as city, name from xe_rep('ingress_ru_city', 'city_src_host_', 'octets', '*8/30', $$ $__timeFilter(time) $$, 20);
ingress_ru_city
- таблица с трафиком по городамcity_src_host_
- название поля с городами в таблицеoctets
- отчет по байтам (не по пакетам)*8/30
- коэффициент, в таблицу добавляются данные каждые 30 секунд, чтобы получить биты в секунду, уможаем байты на 8 и делим на 30 секунд.$$ $__timeFilter(time) $$
- макрос Графаны, фильтрует данные только за нужный период- 20 - отбирается топ-20 городов по количеству трафика, остальные будут в отчете как 'Other'
Входящий трафик с разбивкой по автономным системам:
Входящий трафик по странам:
Входящий трафик только из России по регионам:
Входящий трафик только из России по городам:
Часто сетевым инженерам бывает нужно понять хотя бы в общих чертах, трафик каких типов доминирует в сети. Это делают с помощью "классификации по приложениям".
Данные из netflow достаточно сложно классифицировать именно "по приложениям" и этому есть несколько причин:
- Даже обычные пользователи (не злоумышленники) запускают сервисы на нестандартных и высоких портах для того чтобы их не заметили сканирующие роботы и системы мониторинга
- В одном флове могут передаваться данные о нескольких сетевых пакетах, мы можем посчитать только средний размер пакета
- Поле TCP-flags - это на самом деле комбинация (логическое ИЛИ) TCP-флагов нескольких пакетов TCP-сессии, которые увидел роутер
- Netflow данные в большинстве случаев семплированные
То есть классификация "по приложениям" в случае с netflow/IPFIX это скорее классификация по некоторым netflow-полям.
Обычно для классификации используют порты, протоколы, TCP-флаги и размеры пакетов.
Классификация в xenoeye работает так: пользователь выбирает поля, по которым хочет классифицировать трафик.
Коллектор некоторое время собирает фловы, агрегирует их, потом сортирует по убыванию пакетов/октетов, отбирает верхние X процентов (число задается пользователем) и разбивает этот трафик на "классы".
После этого к каждому флову добавляется метка - название класса.
Коллектор пытается назвать классы человеко-читаемо, например преобразовывает номера портов в названия, комбинации TCP флагов в текстовый вид ("ACK+PSH+SYN", "ACK+RST" и т.д.).
Названия классов хранятся в файлах (/var/lib/xenoeye/clsf/<название объекта>/<номер классификатора>/<клаcc>/name
), можно переименовать любой класс. Скажем, назвать UDP трафик на 443 порту как "QUIC/VPN".
Классификация происходит постоянно при работе коллектора. Так как сетевой трафик может сильно изменяться с течением времени, периодически могут добавляться новые классы.
Делая этот модуль, планировалось решить несколько задач:
- видеть, что происходит в сети в разрезе сервисов
- иметь возможность объединять под общим названием некторые виды трафика
- иметь возможность видеть раздельно некоторые виды трафика (например, трафик по одним портам/протоколам, но с разными размерами пакетов)
- так как классы создаются автоматически из топ-трафика, после некоторого периода "обучения" появление нового класса можно рассматривать как сетевую аномалию
Для классификации в коллекторе есть такие вспомогательные функции:
min(port1, port2)
- выбирает минимальное значение из port1 и port2mfreq(port1, port2)
- выбирает более часто используемый портdiv(aggr1, aggr2)
- обычное деление, используется для определения среднего размера пакетаdivr(aggr1, aggr2, N)
- деление c округлениемdivl(aggr1, aggr2, N)
- деление c округлением вниз к целой степени N
min(src port, dst port)
- минимальное значение из двух портов. Если сервисы работают на небольших номерах портов, эта функция вернет "серверный" порт, по которому можно угадать тип трафика
mfreq(src port, dst port)
- возвращает порт, который используется чаще (статистика собирается только для текущего объекта мониторинга). Если сервис находится на очень высоком порту, но он часто попадается в фловах, то функция вернет этот более часто используемый высокий порт
Функции div*
предназначены для классификации по средним размерам пакетов
divr(octets,packets,N)
- деление с округлением. Делит количество байт в флове на количество пакетов и округляет
divr(octets,packets,100)
для размеров пакетов из диапазона 0-99 будет возвращать 0, из диапазона 100-199 -> 100, 200-299 -> 200 и т.д.
divl(octets,packets,N)
- деление с окpуглением вниз к целой степени N. Если нужно грубо классифицировать по размеру пакетов, например как "маленькие", "средние", "большие" - можно использовать эту функцию.
divl(octets,packets,10)
для размеров пакетов из диапазона 10-99 будет возвращать 10, из диапазона 100-999 -> 100, 1000-9999 -> 1000
Один объект мониторинга можно классифицировать с разными наборами полей. Названия классов добавляются к набору полей фловов как "class0", "class1" и т.д.
Ниже приведен пример для классификации всего входящего трафика, но можно классифицировать произвольные объекты мониторинга. Например DNS-трафик по протоколам (UDP/TCP) и размеру пакетов или отдельно HTTPS по протоколам и TCP-флагам.
ingress/mo.conf
:
{
"filter": "dst net our-net", // весь входящий трафик
"classification": [{
// class0
"fields": ["proto", "mfreq(src port,dst port)"], // нас интересуют протоколы и порты
"top-percents": 90, // классифицируем верхние 90% трафика
"val": "octets desc" // 90% отбираются по количеству октетов
}
,
{
// class1
"fields": ["proto", "div_r(octets,packets,100)"], // протокол + размер пакетов
"top-percents": 90,
"val": "packets desc" // 90% отбираются по количеству пакетов
}
,
{
"fields": ["proto", "tcp-flags"], // протокол + tcp флаги (для не-tcp поле флагов == 0)
"top-percents": 90,
"val": "octets desc"
}
],
/* ... */
"fwm": [
/* ... */
/* экспортируем в PostgreSQL классифицированный по разным полям трафик */
{
"name": "clsf_port",
"fields": ["octets desc", "class0"],
"limit": 30
}
,
{
"name": "clsf_size",
"fields": ["packets desc", "class1"]
}
,
{
"name": "clsf_flags",
"fields": ["octets desc", "class2"]
}
}
}
Для построения временных рядов с классификацией можно воспользоваться функцией xe_rep
, которая показана выше:
Параметры вызова те же - название таблицы, поле и т.д.
По умолчанию неклассифицированный трафик будет показан с названием ?
. Чтобы это изменить, нужно добавить опциональный параметр:
select tm as time, val as class, name from xe_rep('ingress_clsf_port', 'class0', 'octets', '*8/30', $$ $__timeFilter(time) $$, 20, 'Unclassified');
Классификация по портам:
По размеру пакетов:
Классификация отдельно HTTP/HTTPS трафика по протоколам и TCP флагам
Коллектор собирает и обрабатывает sFlow, если в главном конфигурационном файле есть секция "sflow-capture"
:
"sflow-capture": [
//{"pcap": {"interface": "eth0", "filter": "udp and port 6343"}},
{"socket": {"listen-on": "*", "port": "6343"}}
]
Так же, как и для Netflow, можно использовать обычные сокеты или собирать с интерфейса с помощью libpcap.
После того, как коллектор начнет собирать sFlow, его можно обрабатывать точно так же, как и Netflow. Можно создавать объекты мониторинга, описывать фильтр, таблицы для экспорта данных и скользящие средние.
Если коллектор не понимает пакет sFlow, то он его молча отбрасывает. Чтобы понимать, как коллектор видит sFlow-трафик, в комплекте есть утилита xesflow
. Она захватывает трафик с помощью pcap и показывает известные ей sFlow-поля.
# ./xesflow -i eth1 -f "udp and port 6343"
version: 5 [sflow-impl.h, line 198, function sflow_process()]
agent address type: 1 [sflow-impl.h, line 205, function sflow_process()]
agent address (IPv4): 172.16.2.2 [sflow-impl.h, line 214, function sflow_process()]
agent id: 16 [sflow-impl.h, line 232, function sflow_process()]
sequence: 15690 [sflow-impl.h, line 235, function sflow_process()]
uptime: 2858088699 [sflow-impl.h, line 238, function sflow_process()]
samples: 7 [sflow-impl.h, line 241, function sflow_process()]
sample #0 [sflow-impl.h, line 245, function sflow_process()]
sample type: 1 (SF5_SAMPLE_FLOW) [sflow-impl.h, line 249, function sflow_process()]
length: 144 [sflow-impl.h, line 61, function sf5_flow()]
sequence: 53379644 [sflow-impl.h, line 64, function sf5_flow()]
src id: 518 [sflow-impl.h, line 67, function sf5_flow()]
sampling rate: 400 [sflow-impl.h, line 70, function sf5_flow()]
sample pool: 1956205512 [sflow-impl.h, line 74, function sf5_flow()]
drop events: 0 [sflow-impl.h, line 76, function sf5_flow()]
input interface: 0 [sflow-impl.h, line 80, function sf5_flow()]
output interface: 518 [sflow-impl.h, line 88, function sf5_flow()]
number of elements: 2 [sflow-impl.h, line 95, function sf5_flow()]
element #0 [sflow-impl.h, line 100, function sf5_flow()]
tag: 1 [sflow-impl.h, line 102, function sf5_flow()]
element length: 80 bytes [sflow-impl.h, line 105, function sf5_flow()]
header protocol: 1 [sflow-impl.h, line 126, function sf5_flow()]
header len: 64 [sflow-impl.h, line 127, function sf5_flow()]
sampled size: 68 [sflow-impl.h, line 129, function sf5_flow()]
Ethernet src: 54:4b:8c:ef:23:c0 [rawparse.h, line 116, function rawpacket_parse()]
Ethernet dst: 00:25:90:7c:41:8f [rawparse.h, line 116, function rawpacket_parse()]
Ethernet proto: 0x8100 [rawparse.h, line 116, function rawpacket_parse()]
VLAN 607 [rawparse.h, line 129, function rawpacket_parse()]
IPv4 src: 91.32.91.80 [rawparse.h, line 179, function rawpacket_parse()]
IPv4 dst: 121.101.245.97 [rawparse.h, line 179, function rawpacket_parse()]
TOS: 0x0 [rawparse.h, line 179, function rawpacket_parse()]
ID: 16183 [rawparse.h, line 179, function rawpacket_parse()]
TTL: 118 [rawparse.h, line 179, function rawpacket_parse()]
IP protocol: 6 [rawparse.h, line 179, function rawpacket_parse()]
TCP src port: 2872 [rawparse.h, line 253, function rawpacket_parse()]
TCP dst port: 443 [rawparse.h, line 253, function rawpacket_parse()]
TCP flags: 0x10 [rawparse.h, line 253, function rawpacket_parse()]
...
Так как sFlow агент посылает в коллектор куски пакетов, их можно парсить и получать некоторую дополнительную информацию.
В коллекторе есть парсеры протоколов DNS и TLS (HTTPS) SNI.
Например, если вы хостер, то эти парсеры могут помочь составить "карту хостинга", чтобы понимать какие домены хостятся на вашей площадке.
"fwm": [
// ...
{
"name": "dns",
"fields": ["dns-name", "dns-ips"]
}
,
{
"name": "sni",
"fields": ["src host", "dst host", "sni"]
}
]
Коллектор парсит A(IPv4) и AAAA(IPv6) DNS-записи.
dns-ips
сохраняются в виде {ip1, ip2, ...}
- в пакете с DNS-ответом может быть несколько IP-адресов.
Запрос к СУБД для получения доменных имен и их адресов может выглядеть приблизительно так:
=> select distinct dns_name, unnest(dns_ips::inet[]) as ip from all_dns_sni_d order by ip;
ns4-34.azure-dns.info. | 13.107.206.34
ns3-34.azure-dns.org. | 13.107.222.34
144.240.101.34.bc.googleusercontent.com. | 34.101.240.144
connectivity-check.ubuntu.com. | 91.189.91.49
connectivity-check.ubuntu.com. | 185.125.190.18
connectivity-check.ubuntu.com. | 2001:67c:1562::24
ns3-39.azure-dns.org. | 2a01:111:4000:10::27
mirror.docker.ru. | 2a04:8580:ffff:fffe::2
...
Для получения доменных имен из SNI размер захватываемых пакетов должен быть достаточно большим.
Объекты мониторинга могут быть иерархическими/вложенными. Для этого используется иерархия файловой системы. В каталоге, где находится mo.conf
, создайте подкаталог и в нем файл mo.conf
, это будет вложенный объект. Вложенные объекты мониторинга обрабатываются начиная с "верхнего".
Например, вы можете создать объект какой-то сети, а внутри него создать подобъект "udp" с фильтром "proto 17"
- это будет объект с udp-трафиком только этой сети.
Вложенные объекты мониторинга могут быть полезными, когда объектов много: они упрощают конфигурацию и могут обрабатываться более производительно, чем плоский список.
Иногда сетевые инженеры хотят учитывать трафик только некоторых интерфейсов, а остальные игнорировать или обрабатывать особенным способом.
Это можно сделать с помощью фильтров в МО, а можно использовать механизм "классификации интерфейсов" в коллекторе.
В конфигурационном файле devices.conf
в секции роутера есть два параметра - "mark" и "skip-unmarked":
{
"ip": "1.2.3.4",
"mark": [
"src ifidx 1000063 or 1000070 or 1000071",
"dst ifidx 1000063 or 1000070 or 1000071"
],
"skip-unmarked": true
}
Трафик на портах 1000063, 1000070, 1000071 будет маркироваться таким образом: если flow проходит через один из портов (src ifidx
/dst ifidx
), виртуальное поле dev-mark
выставляется в 1
. Если два порта есть в списке, dev-mark
выставляется в 2
. Если не проходит ни через один из портов, dev-mark == 0
.
Когда skip-unmarked == true
и dev-mark == 0
, флов отбрасывается и не учитывается.
Если вы считаете, что трафик с dev-mark == 2
аномальный и хотите его отдельно анализировать, можно сделать отдельный объект мониторинга с фильтром "dev-mark 2"
.
Коллектор с помощью скользящих средних может отслеживать не только всплески трафика, но и падение его ниже порога. Это можно использовать для косвенного мониторинга отдельных хостов или сервисов (DNS/HTTP и т.д.). Если трафик сервиса упал, скорее всего ему стало плохо, и имеет смысл уведомить пользователя.
В описании объекта мониторинга mo.conf
:
"mavg": [
{
"name": "pps",
"time": "30",
"dump": "5",
"fields": ["packets"],
"underlimit": [
{
"name": "level1",
"default": [1000],
"back2norm-time": 120,
"action-script": "/var/lib/xenoeye/scripts/underlimit.sh",
"back2norm-script": "/var/lib/xenoeye/scripts/underlimit-over.sh"
}
]
}
]
Когда коллектор получает сигнал -HUP, он смотрит на время изменения файлов mo.conf
. Если дата отличается от начальной, конфиг перечитывается. Но применяются только данные о порогах.
Механизмом можно пользоваться как вручную, так и автоматически. Например, менять пороги может скрипт, который периодически пересчитывает и выставляет новые пороги для аномалий и DoS/DDoS атак.
Некоторые анализаторы используют время суток и день недели для рассчета автопорогов. Если ваш скрипт пересчета порогов тоже использует эту информацию, пороги можно менять несколько раз в сутки.