Следим за трафиком при помощи протокола NetFlow
Антон Карпов (toxa@real.xakep.ru)
О системах подсчета трафика написано много. Но cnupm, trafd и прочие «считалки» — это сугубо утилитарные приложения, подходящие лишь для конкретных случаев применения. А что если подсчет трафика и представление его в красивой форме (например, на web-странице) — не самоцель? Что если просто надо иметь возможность контролировать трафик, да еще приходящий с нескольких маршрутизаторов? В этом нам поможет протокол NetFlow.
Содержание:
NetFlow — это проприетарный, но открытый протокол, изначально разработанный компанией Cisco для своих железок с целью централизованного сбора информации о сетевом трафике. Однако технология получилась настолько удачной, что ее применение можно встретить где угодно, начиная от железок других производителей и заканчивая программными маршрутизаторами под *nix. Архитектура NetFlow состоит из трех основных компонентов: сенсор; коллектор; обработчик данных, визуализатор.
Сенсоры устанавливаются на всех хостах (роутерах) сети, через которые проходит исследуемый трафик. Сенсоры собирают информацию о потоках трафика (flows) и отправляют ее по протоколу UDP на централизованное место сбора — коллектор. Коллектор сохраняет данные в базе в бинарном netflow-формате, далее эти данные могут быть прочитаны и представлены в читаемом виде специальными утилитами-обработчиками, сохранены в реляционной базе данных, визуализированы в виде графиков и отчетов на web-странице и т.п.
Информация о потоке трафика (flow) — это информация об одном сеансе сетевого соединения, содержащая такую информацию, как IP-адреса участвующих в сетевом взаимодействии машин, их порты (источника и получателя) и тип IP-протокола. Таким образом, роутер, через который проходят потоки сетевых соединений, передает информацию об этих соединениях (flows) на коллектор.
Запись о каждом сетевом соединении (flow record) содержит такую информацию, как время начала и окончания соединения, количество переданных байт и пакетов, IP-адреса источника и получателя, порты и тип IP-протокола. Этими записями удобно манипулировать: подсчитывать трафик, генерировать отчеты и т.п.
Итак, мы будем считать трафик при помощи NetFlow. Точнее, не «считать», а «собирать информацию», ведь NetFlow именно собирает информацию о трафике, которую в дальнейшем можно обрабатывать. В данном случае подсчет трафика — это всего лишь одна прикладная задача. Так что будем строить систему контроля или учета трафика. Имея такую систему, администратор всегда может дать оперативный ответ на вопросы вроде «сколько трафика потребил каждый хост за произвольный промежуток времени», «с какими хостами был проведен самый интенсивный обмен трафиком», «кто превысил лимит в 100 Мб входящего трафика за сегодня» или «кто, когда и откуда вытянул двадцать гигов, за которые вышестоящий провайдер выставил нам счет?» и т.п.
Сначала мы настроим сенсоры на машинах в сети, затем сконфигурируем коллектор, в который сенсоры будут отправлять информацию о трафике. Потом рассмотрим примеры, как с помощью netflow-данных, специальных утилит для работы с ними и базовыми знаниями в области shell-скриптинга ответить на вопросы вроде упомянутых выше. Задача красивой визуализации полученных данных выходит за рамки этой статьи и будет рассмотрена в последующих номерах журнала.
Существует множество программных реализаций всех компонентов NetFlow под *nix-подобные системы. Мы выберем следующие:
- в качестве NetFlow-сенсора;
- в качестве утилит для сбора информации о трафике и работы с ней.
Выбор таких программ обусловлен их популярностью и работоспособностью под множеством вариаций *nix-систем. Существуют также программы, заточенные под какую-либо конкретную операционку. Например, в случае OpenBSD рекомендуется в качестве сенсора использовать , работающий в связке с пакетным фильтром PF. Тот же разработчик предлагает в качестве маленького, быстрого и безопасного 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)
… <skipped>
А в каталоге /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
… <skipped>
Теперь наступает самое интересное — то, ради чего мы все затеяли. Вооружившись утилитами из набора flow-tools и минимальными знаниями shell-скриптинга, мы будем манипулировать информацией о трафике, ставя ее под всесторонний учет!
Нам понадобятся следующие утилиты:
- flow-cat — для конкатенации нескольких netflow-файлов;
- flow-stat — для генерации отчетов по netflow-файлам;
- flow-print — для вывода информации о netflow-потоках в текстовом виде.
Задачи, которые можно решать с помощью flow-tools, могут быть ограничены, наверное, только фантазией администратора. Попробую очертить типичный круг задач, под которые будут написаны скрипты:
- Уведомление администратора о превышении какой-либо машиной дневного лимита трафика в N Мб с возможностью блокировки данной машины пакетным фильтром «до выяснения обстоятельств»;
- Уведомление администратора о превышении каким-либо сервером месячного лимита трафика в N Гб. Информативно и полезно для самоконтроля, например, в ситуации, когда в конторе имеются сервера, а оплата интернета производится по трафику с оплаченным лимитом;
- Детальная отсортированная netflow-информация по трафику за любой день, месяц, год. Удобна для выяснения вопросов вроде «а кто и откуда у нас пятого числа качнул восемьсот мегабайт?»;
- Архивация старых 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 «$MSGn$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 <blocked> persist file /etc/pf.blockedusers block quick from <blocked> to any
Разумеется, все примеры разумно разнести по соответствующим скриптам и выполнять их с помощью с определенной периодичностью. Примеры рабочих скриптов, выполняющих означенный функционал, можно найти на нашем диске.
-
Отмечу три интересные программы в наборе flow-tools(1):
- flow-dscan — анализирует NetFlow-потоки на предмет попыток сканирования портов и наличие некорректно сформированных пакетов;
- flow-gen — генерирует тестовые NetFlow-потоки, полезно для отладки;
- flow-rptfmt — позволяет выводить NetFlow-данные в HTML.
Статья опубликована в июльском номере журнала «Xakep» за 2007 год.




