Поток пакетов - на контроль!Антон Карпов Хакер, номер #103, стр. 138 (toxa@real.xakep.ru) Следим за трафиком при помощи протокола NetFlow О системах подсчета трафика написано много. Но cnupm, trafd и прочие «считалки» - это сугубо утилитарные приложения, подходящие лишь для конкретных случаев. А что если подсчет трафика и представление его в красивой форме (например, на web-странице) не самоцель? Что если надо просто иметь возможность контролировать трафик, да еще приходящий с нескольких маршрутизаторов? В этом нам поможет протокол NetFlow. NetFlow - это проприетарный, но открытый протокол, изначально разработанный компанией Cisco для своего железа с целью централизованного сбора информации о сетевом трафике. Однако технология получилась настолько удачной, что ее применение можно встретить где угодно: начиная от железок других производителей и заканчивая программными маршрутизаторами под *nix. Архитектура NetFlow состоит из трех основных компонентов: 1) сенсор; 2) коллектор; 3) обработчик данных, визуализатор. Сенсоры устанавливаются на всех хостах (роутерах) сети, через которые проходит исследуемый трафик. Сенсоры собирают информацию о потоках трафика (flows) и отправляют ее по протоколу UDP на централизованное место сбора - коллектор. Коллектор сохраняет данные в базе в бинарном netflow-формате. Далее эти данные могут быть прочитаны и представлены в читаемом виде специальными утилитами-обработчиками, сохранены в реляционной базе данных, визуализированы в виде графиков и отчетов на web-странице и т.п. Информация о потоке трафика (flow) - это информация об одном сеансе сетевого соединения, содержащая сведения об IP-адресах участвующих в сетевом взаимодействии машин, их портах (источника и получателя) и типе IP-протокола. Таким образом, роутер, через который проходят потоки сетевых соединений, передает информацию об этих соединениях (flows) на коллектор. Запись о каждом сетевом соединении (flow record) содержит такую информацию, как время начала и окончания соединения, количество переданных байт и пакетов, IP-адреса источника и получателя, порты и тип IP-протокола. Этими записями удобно манипулировать: подсчитывать трафик, генерировать отчеты и т.п. NetFlow? Да! Итак, мы будем считать трафик при помощи NetFlow. Точнее, не считать, а собирать информацию, ведь NetFlow именно собирает информацию о трафике, которую в дальнейшем можно обрабатывать. Подсчет трафика - это всего лишь одна прикладная задача. Так что будем строить систему контроля или учета трафика. Имея такую систему, администратор всегда может дать оперативный ответ на вопросы вроде: «Сколько трафика потребил каждый хост за произвольный промежуток времени?», «С какими хостами был проведен самый интенсивный обмен трафиком?», «Кто сегодня превысил лимит в 100 Мб входящего трафика?», «Кто, когда и откуда вытянул 20 гигов, за которые вышестоящий провайдер выставил нам счет?» и т.п. Сначала мы настроим сенсоры на машинах в сети, затем сконфигурируем коллектор, в который сенсоры будут отправлять информацию о трафике. Потом рассмотрим примеры того, как с помощью NetFlow-данных, специальных утилит для работы с ними и базовых знаний в области shell-скриптинга ответить на вопросы типа упомянутых выше. Задача эффектной визуализации полученных данных выходит за рамки этой статьи и будет решена в следующих номерах журнала. Существует множество программных реализаций компонентов NetFlow под *nix-подобные системы. Мы остановимся на следующих: * softflowd (www.mindrot.org/projects/softflowd) в качестве NetFlow-сенсора; * flow-tools (www.splintered.net/sw/flow-tools) в качестве утилит для сбора информации о трафике и работы с ней. Выбор этих программ обусловлен их популярностью и возможностями работы под множеством вариаций *nix-систем. Существуют также программы, заточенные под какую-либо конкретную операционку. Например, в случае OpenBSD в качестве сенсора рекомендуется использовать pfflowd (www.mindrot.org/projects/pfflowd), работающий в связке с пакетным фильтром PF. Тот же разработчик предлагает flowd (www.mindrot.org/projects/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) ... <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-информация по трафику за любой день, месяц, год. Удобна для выяснения вопросов вроде: «А кто и откуда у нас пятого числа качнул 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\n$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 Разумеется, все примеры разумно разнести по соответствующим скриптам и выполнять их с помощью cron(8) с определенной периодичностью. Примеры рабочих скриптов, реализующих означенный функционал, можно найти на нашем диске. INFO Отмечу три интересные программы в наборе flow-tools(1): * flow-dscan - анализирует netflow-потоки на предмет попыток сканирования портов и наличия некорректно сформированных пакетов; * flow-gen - генерирует тестовые netflow-потоки, полезно для отладки; * flow-rptfmt - позволяет выводить netflow-данные в HTML. |