Следим за трафиком при помощи протокола NetFlow


О системах подсчета трафика написано много. Но cnupm, trafd и прочие «считалки» - это сугубо утилитарные приложения, подходящие лишь для конкретных случаев. А что если подсчет трафика и представление его в красивой форме (например, на web-странице) не самоцель? Что если надо просто иметь возможность контролировать трафик, да еще приходящий с нескольких маршрутизаторов? В этом нам поможет протокол NetFlow.

NetFlow - это проприетарный, но открытый протокол, изначально разработанный компанией Cisco для своего железа с целью централизованного сбора информации о сетевом трафике. Однако технология получилась настолько удачной, что ее применение можно встретить где угодно: начиная от железок других производителей и заканчивая программными маршрутизаторами под *nix. Архитектура NetFlow состоит из трех основных компонентов:
сенсор;
коллектор;
обработчик данных, визуализатор.

Сенсоры устанавливаются на всех хостах (роутерах) сети, через которые проходит исследуемый трафик. Сенсоры собирают информацию о потоках трафика (flows) и отправляют ее по протоколу UDP на централизованное место сбора - коллектор. Коллектор сохраняет данные в базе в бинарном netflow-формате. Далее эти данные могут быть прочитаны и представлены в читаемом виде специальными утилитами-обработчиками, сохранены в реляционной базе данных, визуализированы в виде графиков и отчетов на web-странице и т.п.

Информация о потоке трафика (flow) - это информация об одном сеансе сетевого соединения, содержащая сведения об IP-адресах участвующих в сетевом взаимодействии машин, их портах (источника и получателя) и типе IP-протокола. Таким образом, роутер, через который проходят потоки сетевых соединений, передает информацию об этих соединениях (flows) на коллектор.

Запись о каждом сетевом соединении (flow record) содержит такую информацию, как время начала и окончания соединения, количество переданных байт и пакетов, IP-адреса источника и получателя, порты и тип IP-протокола. Этими записями удобно манипулировать: подсчитывать трафик, генерировать отчеты и т.п.
NetFlow? Да!

Итак, мы будем считать трафик при помощи NetFlow. Точнее, не считать, а собирать информацию, ведь NetFlow именно собирает информацию о трафике, которую в дальнейшем можно обрабатывать. Подсчет трафика - это всего лишь одна прикладная задача. Так что будем строить систему контроля или учета трафика. Имея такую систему, администратор всегда может дать оперативный ответ на вопросы вроде: «Сколько трафика потребил каждый хост за произвольный промежуток времени?», «С какими хостами был проведен самый интенсивный обмен трафиком?», «Кто сегодня превысил лимит в 100 Мб входящего трафика?», «Кто, когда и откуда вытянул 20 гигов, за которые вышестоящий провайдер выставил нам счет?» и т.п.

Сначала мы настроим сенсоры на машинах в сети, затем сконфигурируем коллектор, в который сенсоры будут отправлять информацию о трафике. Потом рассмотрим примеры того, как с помощью NetFlow-данных, специальных утилит для работы с ними и базовых знаний в области shell-скриптинга ответить на вопросы типа упомянутых выше. Задача эффектной визуализации полученных данных выходит за рамки этой статьи и будет решена в следующих номерах журнала.

Существует множество программных реализаций компонентов NetFlow под *nix-подобные системы. Мы остановимся на следующих:
softflowd в качестве NetFlow-сенсора;
flow-tools в качестве утилит для сбора информации о трафике и работы с ней.

Выбор этих программ обусловлен их популярностью и возможностями работы под множеством вариаций *nix-систем. Существуют также программы, заточенные под какую-либо конкретную операционку. Например, в случае OpenBSD в качестве сенсора рекомендуется использовать pfflowd, работающий в связке с пакетным фильтром PF. Тот же разработчик предлагает flowd - маленький, быстрый и безопасный NetFlow-коллектор, к которому прилагается набор утилит flowrrd для отображений NetFlow-данных в rrd-базе (для дальнейшей обработки их с помощью RRDtool).

В качестве коллектора будем использовать машину под управлением FreeBSD 6. Сенсор поставим на шлюз под управлением OpenBSD 4.1.

Установка и настройка

Установку flow-tools на FreeBSD будем производить штатно, из портов:

$ cd /usr/ports/net-mgmt/flow-tools
$ sudo make install clean

В результате будет установлена масса утилит для работы с NetFlow. Подробную информацию о том, что же поставлено из порта, можно получить, например, с помощью команды:

$ pkg_info -L flow-tools-0.68_1

Сейчас нас интересует только одна программа из набора - flow-capture. Это и есть тот самый коллектор, который собирает информацию с сенсоров. Аргументы запуска следующие:

/usr/local/bin/flow-capture -p /var/run/flow-capture.pid -N 3 -w /var/log/netflows -S 5 192.168.76.146/192.168.76.147/8818

Здесь /var/log/netflows - каталог, в котором собираются NetFlow-данные; -N 3 - уровень вложенности каталогов в этой папке. Данные пишутся в формате YYYY/YYYY-MM/YYYY-MM-DD/flow-file. Запись «192.168.76.146/192.168.76.147/8818» имеет форму «localip/remoteip/port», где localip - локальный адрес коллектора, на котором flow-capture слушать входящие соединения от сенсоров; remoteip - адрес сенсора (при такой настройке flow-capture будет принимать соединения только с определенного хоста); port - порт, на котором слушает коллектор. Если сенсоров несколько, можно выставить remoteip в 0 (принимать соединения со всех хостов), а доступ разграничить пакетным фильтром.

В результате нашей настройки коллектор будет слушать на хосту 192.168.76.146 (порт 8818/udp) и принимать соединения с коллектора на машине 192.168.76.147.

Осталось только прописать коллектор в автозапуск. К сожалению, порт flow-tools не содержит rc-скрипт для запуска коллектора в FreeBSD-стиле, поэтому мы сами создадим flowd.sh следующего содержания:

# vi /usr/local/etc/rc.d/flowd.sh
#!/bin/sh
. /etc/rc.subr
name=flowd
rcvar=`set_rcvar`
load_rc_config $name
: ${flowd_enable:="NO"}
: ${flowd_flags=""}
pidfile=${spamd_pidfile:-"/var/run/flow-capture.pid"}
command=/usr/local/bin/flow-capture
command_args="-p ${pidfile} -N 3 -w /var/log/netflows -S 5 192.168.76.146/192.168.76.147/8818"
stop_postcmd=stop_postcmd
stop_postcmd()
{
rm -f $pidfile
}
run_rc_command "$1"

Не забываем добавить запись «flowd_enable="YES"» в /etc/rc.conf.

Благодаря изумительным pkg_tools установка сенсора на OpenBSD необременительна. При прописанной PKG_PATH набираем:

$ sudo pkg_add softflowd-0.9.8

И дело в шляпе. Прописать демон в автостарт «по-опенковскому» также не представляет проблем. В /etc/rc.local добавляем:

# vi /etc/rc.local
if [ -x /usr/local/sbin/softflowd ]; then
echo -n 'softflowd '; /usr/local/sbin/softflowd -i fxp0 -n 192.168.76.146:8818
fi

Здесь fxp0 - интерфейс, через который проходит трафик и который будет слушать сенсор; 192.168.76.146:8818 - хост и порт коллектора, на который сенсор будет отправлять данные о потоках трафика.

Управляем!

Если все запущено и работает корректно, то на сенсоре мы увидим примерно следующую информацию по текущим netflow-потокам:

# softflowctl statistics
softflowd[26337]: Accumulated statistics:
Number of active flows: 925
Packets processed: 14552628
Fragments: 84
Ignored packets: 1080111 (1080111 non-IP, 0 too short)
Flows expired: 1013171 (0 forced)
Flows exported: 1980130 in 74625 packets (0 failures)
...

А в каталоге /var/log/netflows должны появиться собранные данные:

$ ls -la /var/log/netflows/2007/2007-05/2007-05-14
drwxr-xr-x 2 root wheel 3584 14 май 18:45 ./
drwxr-xr-x 16 root wheel 512 14 май 00:00 ../
-rw-r--r-- 1 root wheel 19309 14 май 00:15 ft-v05.2007-05-14.000001+0400
-rw-r--r-- 1 root wheel 18022 14 май 00:30 ft-v05.2007-05-14.001501+0400
-rw-r--r-- 1 root wheel 21379 14 май 00:45 ft-v05.2007-05-14.003001+0400
-rw-r--r-- 1 root wheel 20607 14 май 01:00 ft-v05.2007-05-14.004501+0400
...

Теперь начинается самое интересное - то, ради чего мы все затеяли. Вооружившись утилитами из набора flow-tools и минимальными знаниями shell-скриптинга, мы будем манипулировать информацией о трафике, ставя ее под всесторонний учет!

Нам понадобятся следующие утилиты:
flow-cat для конкатенации нескольких netflow-файлов;
flow-stat для генерации отчетов по netflow-файлам;
flow-print для вывода информации о netflow-потоках в текстовом виде.

Перечень задач, которые можно решать с помощью flow-tools, ограничивается только фантазией администратора. Попробую очертить типичный круг задач, под которые будут написаны скрипты:
Уведомление администратора о превышении какой-либо машиной дневного лимита трафика в N Мб с возможностью блокировки этой машины пакетным фильтром «до выяснения обстоятельств».
Уведомление администратора о превышении каким-либо сервером месячного лимита трафика в N Гб. Информативно и полезно для самоконтроля, например, в ситуации, когда в конторе имеются серверы, а оплата интернета производится по трафику с оплаченным лимитом.
Детальная, отсортированная netflow-информация по трафику за любой день, месяц, год. Удобна для выяснения вопросов вроде: «А кто и откуда у нас пятого числа качнул 800 мегабайт?».
Архивация старых netflow-данных (месячной давности).
Пример обработки записей с помощью flow-cat и flow-stat:


flowcat="/usr/local/bin/flow-cat"
flowstat="/usr/local/bin/flow-stat"
flows="/var/log/netflows"
$flowcat $flows/$year/$month/$day | $flowstat -f10 -p -S3

Результатом будет таблица из пяти колонок: src ip, dst ip, number of flows, number of bytes, number of packets. Выяснить, кто же превысил лимит, можно, например, так:

SUBJ="$INBOUND TRAFFIC ALERT"
MSG="Alert!!! Some of your machines gets more than 100 mbytes today. See details below."
$flowcat $flows/$year/$month/$day | $flowstat -f10 -p -S3 | tail -20 |
while read SRC DST undef COUNT undef; do
if [ $COUNT -gt 100000000 ]; then
echo -e "$MSG $COUNT bytes from $SRC to $DST" | mail -s "$SUBJ" toxa
echo $DST >> /etc/pf.blockedusers
fi
done

В этом случае пользователю toxa высылается уведомление о том, что определенная машина выкачала более 100 Мб трафика, и ее адрес заносится в таблицу /etc/pf.blockedusers. В конфиге пакетного фильтра /etc/pf.conf имеем:

table persist file /etc/pf.blockedusers
block quick from to any

Разумеется, все примеры разумно разнести по соответствующим скриптам и выполнять их с помощью cron(8) с определенной периодичностью.

Отмечу три интересные программы в наборе flow-tools(1):
flow-dscan - анализирует netflow-потоки на предмет попыток сканирования портов и наличия некорректно сформированных пакетов;
flow-gen - генерирует тестовые netflow-потоки, полезно для отладки;
flow-rptfmt - позволяет выводить netflow-данные в HTML.

Автор: Антон Карпов
Взято с августовского выпуска журнала Хакер

Обновлено: 12.03.2015