Считаем траффик во FreeBSD
Решил я завести у себя дома аналог статистики netflow для циски. То есть сбор данных о проходящих через сеть пакетах (откуда, куда, размер). Циски у меня нету, а статистику иметь охота.
Рассмотрим установку и эксплуатацию на FreeBSD 7.0
Для этого есть тулза ng_ipacct.
-
Установка
cd /usr/ports/net-mgmt/ng_ipacct/
А вот установка во FreeBSD 7 отличается от
make install
При выполнении make компиляция обрывается с ошибкойng_ipacct.c:905: error: too few arguments to function 'in_pcblookup_local'
Гугл почти ничего об этом не знает, но ответ я нашёл. Смысл его таков:
В седьмой фряхе изменили синтаксис этой системной функции. Непонятно, а нафига, но придётся с этим жить. А ещё более непонятно, как мэнтэйнер этого порта (чтоб ему руки оторвать) запихал собственно в порт заведомо нерабочую прогу
О какой функции тут идёт речь тут понятно. Дело за малым – подправить код.
make fetch extract vi work/ng_ipacct/ng_ipacct/ng_ipacct.c
идём на 905-ю строку и заменяем
--- pcb = in_pcblookup_local(pcbinfo, ina, port, 1); +++ pcb = in_pcblookup_local(pcbinfo, ina, port, 1, 1);
Далее просто
make install clean
Установили -
Настройка
Правим rc.conf. Добавляемng_ipacct_enable="YES"
Настраиваем конфиг/usr/local/etc/ng_ipacct.conf. Вот пример моего конфига с настройкой на один интерфейс# $FreeBSD: ports/net-mgmt/ng_ipacct/files/ng_ipacct.conf,v 1.6 2008/06/03 10:40:16 skv Exp $
#
# Please read and meditate on netgraph(4), ipacctctl(8) and ngctl(8).Мне нравится эта фраза. “читайте и медитируйте”
# Enable ng_ipacct (i.e. enable run startup script "ng_ipacct.sh") #ng_ipacct_enable="YES"
Аналог включения через /etc/rc.conf
# Enable kernel modules loading. # On "ng_ipacct.sh start" all kernel modules specified # in ${ng_ipacct_modules_list} will be loaded. # Note: on "ng_ipacct.sh stop" only "ng_ipacct" will be unloaded. ng_ipacct_modules_load="YES"Разрешаем при запуске автоподгрузку необходимых модулей. Я один фиг подгрузил руками
# Netgraph can load required ng_* modules automatically on the hook creation # - except for "ng_ether". Generally, modules preloading is recommended. # Do not add to this list modules which are statically compiled into kernel. #ng_ipacct_modules_list="netgraph ng_ether ng_cisco ng_socket ng_tee ng_ipacct" ng_ipacct_modules_list="netgraph ng_ether ng_ipacct"
Указываем какие модули подружать, если включена автоподгрузка. Сделано во избежание подгрузки модулем чего-либо скомпилированого статически
# List of monitored interfaces. For each interface additional vars must be # specified in corresponding variables 'ng_ipacct_IFACE_*'. # See examples below. #ng_ipacct_interfaces="xl0 cx0 vpn0" ng_ipacct_interfaces="vr0"
Указываем на каких интерфейсах вести сбор статистики
# Default start/stop scripts.
#
# Single quotes are required to preserve newlines.
# '%%iface%%' will be automatically expanded with a relevant interface.
# This feature should be applied to use indentical rules
# for similar interfaces.
ng_ipacct_default_ether_start='
mkpeer %%iface%%: tee lower right
name %%iface%%:lower %%iface%%_tee
connect %%iface%%: lower upper left
mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_ip_acct
connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'
ng_ipacct_default_ether_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_tee:
shutdown %%iface%%:
'
ng_ipacct_bpf_ether_start='
mkpeer %%iface%%: tee lower right
name %%iface%%:lower %%iface%%_tee
connect %%iface%%: lower upper left
mkpeer %%iface%%_tee: bpf right2left %%iface%%_in
name %%iface%%_tee:right2left %%iface%%_bpf
connect %%iface%%_tee: right2left left2right %%iface%%_out
mkpeer %%iface%%_bpf: ipacct %%iface%%_match_in %%iface%%_in
name %%iface%%_bpf:%%iface%%_match_in %%iface%%_ip_acct
connect %%iface%%_bpf: %%iface%%_ip_acct: %%iface%%_match_out %%iface%%_out
'
ng_ipacct_bpf_ether_stop='
shutdown %%iface%%_ip_acct:
shutdown %%iface%%_bpf:
shutdown %%iface%%_tee:
shutdown %%iface%%:
'
Это лучше не трогать. Это скрипты запуска по умолчанию. Я в них ничего не понял и оставил как есть. Далее идут настройки конкретно под интерфейс
# Configuration for 'vr0_ip_acct' node:
ng_ipacct_vr0_dlt="EN10MB" # required line; see ipacctctl(8)
Немного загадочная строка. Оставил как есть. Для ethernet интерфейса вроде как такая должна быть.
ng_ipacct_vr0_threshold="5000" # '5000' by default
Максимальное количество записей в буфере. Работает сбор инфомации в памяти ядра, и если размера ОЗУ, выделенного под ядро ядро системы не будет хватать, то система просто грохнется. Во избежание этого, сделана опция. При превышении указанной длинны новая статистика собираться не будет до обнуления буфера
ng_ipacct_vr0_verbose="yes" # 'yes' by default
Подробный режим
ng_ipacct_vr0_saveuid="yes" # 'no' by default
ng_ipacct_vr0_savetime="no" # 'no' by default
ng_ipacct_vr0_start=${ng_ipacct_default_ether_start}
ng_ipacct_vr0_stop=${ng_ipacct_default_ether_stop}
ng_ipacct_vr0_checkpoint_script="/root/ng.sh"
# this script is called on "stop" (to save accumulated
# data) or via "rc.d/ng_ipacct.sh checkpoint"
Последний параметр говорит, какой скрипт вызывать для сброса буфера через через стартовый скрипт. Ни разу не пользовался.
-
Использование
Для начала запустим/usr/local/etc/rc.d/ng_ipacct start
Через некоторое время( как накопится статистика) её можно снять. Для этого служит ipacctctl
ipacctctl $IFACE_ip_acct:IFCAE checkpoint
Снять статистику с модуля ядра во временный буфер
ipacctctl $IFACE_ip_acct:IFCAE show
Показать эту статистику. Если включён подробный режим, то формат спика такой:
IP_источника порт_источника IP_получателя порт_получателя номер_протокола число_пакетов число_байт какая_то_фигняipacctctl $IFACE_ip_acct:IFCAE clear
Очищает временный буфер. Без очистки нелья вызвать checkpoint
Что теперь со всем этим можно делать. Я сделал 2 скрипта. Один раз в 5 минут сбрасывает статистику во временный файл. Другой скрипт раз в полчаса переносит всё это в другой файл, больший по размеру.
Скрипт 1. Тот что раз в пять минут:
#!/bin/sh DATE=`date +"%Y %m %d %H %M"` YEAR=`echo $DATE | awk '{print $1}'` MONTH=`echo $DATE | awk '{print $2}'` DAY=`echo $DATE | awk '{print $3}'` HOUR=`echo $DATE | awk '{print $4}'` MINUTE=`echo $DATE | awk '{print $5}'` /usr/local/sbin/ipacctctl vr0_ip_acct:vr0 checkpoint /usr/local/sbin/ipacctctl vr0_ip_acct:vr0 show > /var/log/ngraph/tmp/$YEAR-$MONTH-$DAY-$HOUR-$MINUTE.log /usr/local/sbin/ipacctctl vr0_ip_acct:vr0 clearДиректория
/var/log/ngraph/tmp/предварительно создана.Скрипт 2. Тот, что “архивирует”
#!/bin/sh DATE=`date +"%Y %m %d %H %M"` YEAR=`echo $DATE | awk '{print $1}'` MONTH=`echo $DATE | awk '{print $2}'` DAY=`echo $DATE | awk '{print $3}'` HOUR=`echo $DATE | awk '{print $4}'` MINUTE=`echo $DATE | awk '{print $5}'` MINUTE=`expr $MINUTE - 1` if [ ! -d /var/log/ngraph/$YEAR ]; then mkdir /var/log/ngraph/$YEAR fi if [ ! -d /var/log/ngraph/$YEAR/$MONTH ]; then mkdir /var/log/ngraph/$YEAR/$MONTH fi if [ ! -d /var/log/ngraph/$YEAR/$MONTH/$DAY ]; then mkdir /var/log/ngraph/$YEAR/$MONTH/$DAY fi DNAME=/var/log/ngraph/$YEAR/$MONTH/$DAY for NAME in `ls /var/log/ngraph/tmp/ | grep log`; do echo $DNAME/$HOUR-$MINUTE.log cat /var/log/ngraph/tmp/$NAME >> $DNAME/$HOUR-$MINUTE.log rm /var/log/ngraph/tmp/$NAME doneЗапускается он каждую 1-ю и 31-ю минуты часа
Также необходимо сделать ротацию всего этого хозяйства. За неделю на канале 256 кбит/с при средней загрузке канала, набралось на 210 мегабайт статистики.
-
Для чего это
Вопрос дня. А для чего это нужно?Ну например для подсчёта траффика на IP. Например для биллинга, или ещё для чего-либо. Также можно использовать для поиска сетевых аномалий (флуд или ещё что-нить), ну и просто для красоты и выпендрёжу
Мне эта статистика помогла определить почему не до конца выделяется канал одному пользователю, при простое другого. Выяснилось, что выделяется-то он весь. Но CPU “не успевает” пакеты в очередь пихать и дропает их. Буду апгрейдить шлюз.
Кстати. Очень важное замечание. Netgraph (через который и берётся статистика) работает на уровне ядра FreeBSD и перед файрволом. То есть пакет вначале считается нетграфом, а потом только обрабатывается файрволом. В этом есть плюс. В статистику попадают все пакеты на интерфейсе, невжно дропнуты они были или нет. Есть и минус. Он в том, что статистика на шлюзе будет в этом случае отличаться от статистики на удалённой машине, или на файрволле.



Нармальная статейка у меня получилось …
только ng_ipacct_modules_load=”YES” это выключил ибо ошибки сыпались
хотелось бы все это с продолжением т.е. со складыванием в мускуль и т.д.
Хм. А что именно в мускуле хранить?
Если сами “логи”, то это имхо не имеет смысла. Так как во-первых, неудобно обрабатывать данные проихвольным методом (cat файл | что угодно), а во вторых это нерационально с точки зрения диска. Файлы можно просто архивировать, либо удалять устаревшие (сомневаюсь, что могут понадобиться подобные “сырые” данные годовалой давности, к примеру).
А если хранить в мускуле результаты обработки, то для начала надо придумать что собственно считать. А цели считать что-либо периодически у меня не было. Была цель получить подобную статистику о пакетах. Конечно, периодически, я считаю кое-что, но это разовые подсчёты, для решения разовых вопросов.
а зачем секс с awk?
date +”%Y-%m-%d-%H-%M”
а зачем поминутные файлы?
cat ~/bin/get_data
#!/bin/sh
now=`/bin/date +%Y%m%d`
INTERFACES=”vr0 ng0″
IPACCTCTL=”/usr/local/sbin/ipacctctl”
log=”/var/log/ng_ipacct/$now”
for IFACE in $INTERFACES; do
$IPACCTCTL ${IFACE}_ip_acct:$IFACE checkpoint
$IPACCTCTL ${IFACE}_ip_acct:$IFACE show v | /usr/bin/sort -nk 8 >> $log.$IFACE
$IPACCTCTL ${IFACE}_ip_acct:$IFACE clear
done