Сервер в кармане, или просто о сложном!

главная - Статьи - Linux, FreeBSD

Мониторинг загрузки канала интернет-шлюза на FreeBSD

Теги: FreeBSD RRDTool Linux

Это вторая версия статьи, редактировано 24.08.2011. Все полностью рабочее, так сказать, с пылу - с жару.

Статистика трафика, посторенная с помощью RRDTool

В этой небольшой статье я постараюсь описать простой и часто необходимый способ постороения графиков загрузки интернет-канала (общий график, график www, график pop3, график smtp). Это может быть полезно системным администраторам для того, чтобы они знали, в какое время их офис потребляет много интернета, забита ли их полоса пропускания постоянно или только перед обедом, на что именно расходуется полоса пропускания канала – на просмотр сайтов (тогда, возможно, кто-то качает всякую фигню), на получение почты (тогда, возможно, надо рассмотреть вопрос настройки собственного почтового сервера), на отправку писем (возможно, какой-либо компьютер заражен вирусом и рассылает спам). Применений этому может быть множество. Итак, приступим.

ТРЕБОВАНИЯ

RRDTool - установка и настройка см. здесь и здесь (англ.).

Брандмауэр на шлюзе – в нашем случае рассмотрим ipfw в составе ОС FreeBSD. В общем случае подойдет любая система, которая может считать пакеты и отдавать их значения нашим скриптам.

Apache – веб-сервер для просмотра сгенерированных изображений. Впрочем, это не обязательно, нам главное сгенерировать изображение, а что с ним делать – решать вам.

Будем считать, что rrdtool установлена, apache – тоже, брандмауэр, полагаю, был всегда, так что самое время описать работу нашей схемы.

БРАНДМАУЭР

Итак, нам необходимы правила брандмауэра, которые будут считать трафик www (входящий), pop3 (входящий), smtp (исходящий), imap (входящий) и общий входящий. Вот они:

pif="xl0" # внешний интерфейс
cmd="ipfw -q add"
# Считаем трафик
# SMTP, SMTPS
$cmd 0020 count tcp from any to any 25,465 out via $pif
# POP3, POP3S
$cmd 0021 count tcp from any 110,995 to any in via $pif
# WWW
$cmd 0022 count tcp from any 80,443,8080 to any in via $pif
# ALL
$cmd 0023 count all from any to any in via $pif
# IMAP, IMAPS
$cmd 0024 count tcp from any 143,993 to any in via $pif

Первые две строки – объявления макросов, остальные – понятно, считают соответствующий трафик.

После включения этих правил проверим, считают ли они трафик, идущий через шлюз.

freebsd-host# ipfw show 23

Выдает нам нечто похожее:

00013 146322 109248471 count ip from any to any in via xl0

Нас будет интересовать третья цифра – 109248471 – количество байт, сосчитанное правилом 23, которое в нашем случае считает общий входящий трафик.

RRDTOOL

Считаем RRDTool установленным и, желательно, проверенным хотя бы на тестовом примере, который весьма неплохо описан здесь. Не поленитесь, просмотрите эту статью, несмотря на то, что она на английском. Я не могу сказать про себя, что английский знаю даже средне, но мне там все было понятно.

Расположение файлов в моем примере:

  • База RRDTool: /var/rrdtool/db/network_usage.rrd
  • Скрипты: /var/rrdtool/scripts/

СКРИПТЫ

Нам будет необходимы следующий скрипты:

  1. network_usage_create.sh – создает базу данных для хранения значений счетчиков, описанных выше. Запускается один раз.
  2. network_usage.sh – обновляет базу. Запускается периодиески. Для нашего примера, один раз в минуту.
  3. network_usage_graph.sh – рисует графики загрузки канала. Запускается один раз в минуту (не обязательно так часто - это просто рисунок, который можно создавать хоть раз в сутки).
  4. network_usage_update_rrdtool.sh – фактически, этот скрипт просто запускает раз в пять минут network_usage.sh и network_usage_graph.sh. Его содержимое самое очевидное.

Вот их содержимое:

Создаем базу данных RRDTool

network_usage_create.sh

#!/bin/sh

rrdtool create /var/rrdtool/db/network_usage.rrd \
        --start 1176595200 \
        --step 60 \
        DS:input_pop3:COUNTER:120:U:U \
        DS:input_imap:COUNTER:120:U:U \
        DS:output_smtp:COUNTER:120:U:U \
        DS:input_www:COUNTER:120:U:U \
        DS:input_all:COUNTER:120:U:U \
        RRA:AVERAGE:0.5:1:1200 \
        RRA:MAX:0.5:1:1200 \

Этим скриптом создаем файл (базу данных) RRDTool "network_usage.rrd". Прокомментирую команды:

  • --step 60 - наша база расчитана на прием значений каждые 60 секунд.
  • число 120 в строках DS - т.н. heartbeat, обычно ставится как step*2.
  • U:U - минимальные и максимальные значения. В нашем случае не определены.
  • строки RRA:AVERAGE и RRA:MAX содержат значения 0.5:1:1200 - это означает, что наша база содержит 1200 ячеек для хранения значений счетчиков через каждый 1 step (грубо: 1200 * (1*60 сек) = 50 часов). Параметр 0.5 имеет хитрое определение, я даже приводить его не буду.

Проверяем, появился ли файл /var/rrdtool/db/network_usage.rrd. Если появился, переходим к следующему шагу. Если нет, то проверяем пути запуска rrdtool (возможно, у вас rrdtool запускается не такой командой /usr/local/bin/rrdtool, а как-нибудь иначе). В любом случае, пока база rrdtool не будет создана, дальше идти нельзя.

Заносим новые данные в базу RRDTool

network_usage.sh

#!/bin/sh

input_pop3=`/sbin/ipfw show 0021 | awk '{print $3}'`
input_imap=`/sbin/ipfw show 0024 | awk '{print $3}'`
output_smtp=`/sbin/ipfw show 0020 | awk '{print $3}'`
input_www=`/sbin/ipfw show 0022 | awk '{print $3}'`
input_all=`/sbin/ipfw show 0023 | awk '{print $3}'`
/usr/local/bin/rrdtool update /var/rrdtool/db/network_usage.rrd \
   N:$input_pop3:$input_imap:$output_smtp:$input_www:$input_all

Здесь все ясно, через параметры командной строки в базу заносятся текущие значения счетчиков.

Рисуем график интернет-трафика

network_usage_graph.sh

#!/bin/sh

WWWPREFIX=/var/www/htdocs/rrdtool/images
RRDPREFIX=/var/rrdtool/db
DATE="`date +%d.%m.%Y`"
HOUR="`date +%H`"
MINUTE="`date +%M`"

/usr/local/bin/rrdtool graph $WWWPREFIX/network.png \
    --width 500 --height 200 --imgformat PNG \
    --start -8h \
    --end now \
    --title "Traffic: last 8 hours ($DATE)"  --rigid  --color BACK#FAFAFA  \
    --vertical-label bit/sec \
    --base=1024 \
    --watermark "(c)2011 BOZZA.RU Ivanov Ilya" \
    DEF:tmp_in_pop3=$RRDPREFIX/network_usage.rrd:input_pop3:AVERAGE:step=60   \
    DEF:tmp_out_smtp=$RRDPREFIX/network_usage.rrd:output_smtp:AVERAGE:step=60   \
    DEF:tmp_in_www=$RRDPREFIX/network_usage.rrd:input_www:AVERAGE:step=60   \
    DEF:tmp_in_all=$RRDPREFIX/network_usage.rrd:input_all:AVERAGE:step=60   \
    DEF:tmp_in_imap=$RRDPREFIX/network_usage.rrd:input_imap:AVERAGE:step=60   \
    CDEF:in_pop3=tmp_in_pop3,8,*       \
    CDEF:out_smtp=tmp_out_smtp,8,*     \
    CDEF:in_www=tmp_in_www,8,*         \
    CDEF:in_all=tmp_in_all,8,*         \
    CDEF:in_imap=tmp_in_imap,8,*       \
    VDEF:sum_in_pop3=tmp_in_pop3,TOTAL      \
    VDEF:sum_out_smtp=tmp_out_smtp,TOTAL       \
    VDEF:sum_in_www=tmp_in_www,TOTAL            \
    VDEF:sum_in_all=tmp_in_all,TOTAL \
    VDEF:sum_in_imap=tmp_in_imap,TOTAL \
    VDEF:max_in_pop3=in_pop3,MAXIMUM          \
    VDEF:max_out_smtp=out_smtp,MAXIMUM         \
    VDEF:max_in_www=in_www,MAXIMUM            \
    VDEF:max_in_all=in_all,MAXIMUM             \
    VDEF:max_in_imap=in_imap,MAXIMUM          \
    AREA:in_all#CCCCCC:"ALL (in)          "        \
    GPRINT:max_in_all:"Max=%-8.2lf%sbit/s"      \
    GPRINT:sum_in_all:"Sum=%-8.2lf %sbytes\l"    \
    LINE1:in_www#0000FF:"WWW (80,443,8080) "          \
    GPRINT:max_in_www:"Max=%-8.2lf%sbit/s"       \
    GPRINT:sum_in_www:"Sum=%-8.2lf %sbytes\l"     \
    LINE1:in_pop3#FF6600:"POP3 (110,995)    "        \
    GPRINT:max_in_pop3:"Max=%-8.2lf%sbit/s"      \
    GPRINT:sum_in_pop3:"Sum=%-8.2lf %sbytes\l"    \
    AREA:out_smtp#FF0000:"SMTP (25,465, out)"        \
    GPRINT:max_out_smtp:"Max=%-8.2lf%sbit/s"      \
    GPRINT:sum_out_smtp:"Sum=%-8.2lf %sbytes\l"    \
    LINE1:in_imap#009900:"IMAP (143,993)    "        \
    GPRINT:max_in_imap:"Max=%-8.2lf%sbit/s"      \
    GPRINT:sum_in_imap:"Sum=%-8.2lf %sbytes\l"    \
    COMMENT:"    \l"    \
    COMMENT:"Last update\: $HOUR\:$MINUTE $DATE\l"    \    

Комментарий:

  • WWWPREFIX=/var/www/rrdtool/images – путь до директории, где будет храниться картинка network.png. Отредактируйте этот путь в соответствии с вашим веб-сервером apache или любым другим.
  • RRDPREFIX=/var/rrdtool/db – путь до директории, где лежит база данных rrdtool.
  • Наш скрипт отображает загрузку канала за последние 8 часов:
    --start -8р – время в часах (символ h после 8).
  • --base=1024 - мы же страфик считаем, а не килограммы.
  • В строках DEF:...:step=60 - не забудьте поставить этот параметр для корректного масштабирования. 60 - это уже знакомые нам 60 секунд.
  • В строках CDEF байты преобразуем в биты. Формат такой: a = b,8,* - т.е. a = b*8.
  • Обратите внимание на то, что скорость в битах в секунду (bit/s), а сумма трафика - в байтах (bytes). %s указывает порядок - Мега (M), Кило (k) и др. Для того, чтобы понять, откуда ноги растут, внимательно просмотрите создание переменных, а лучше выпишите их на бумагу: tmp_in_all - байты, in_all - биты. Максимумы считают биты (это относится к скорости, бит/сек). Общее (TOTAL) - в байтах. Так нам привычнее. Только и всего.

Данный скрипт не обязательно запускать раз в минуту - он просто рисует картунку на основании базы данных.

Обновляем базу RRDTool и графики регулярно

network_usage_update_rrdtool.sh

#!/bin/sh

/var/rrdtool/scripts/network_usage.sh
/var/rrdtool/scripts/network_usage_graph.sh

Здесь самое простое место - просто для удобства запускаем два скипта из одного места. В cron мы добавим именно этот скрипт:

# crontab –e
*/1 * * * * /var/rrdtool/scripts/network_usage_update_rrdtool.sh

ЗАКЛЮЧЕНИЕ

Вот, собственно и все. До помещения чего-либо в cron, лучше проверить в ручном режиме. Разумеется, многое из того, что я описал, я взял из примеров, разбросанных по сети, многое отредактировал сам. Надеюсь, статья будет полезна многим. С уважением, BOZZA.RU

Обновление: ежедневное сохранение статистики в виде изображений

Все здорово - система настроена, рисует график, но есть проблема - статистика исчезнет (точнее говоря, рисунок обновится), как только пройдет 8 часов. А мне надо, чтобы через месяц я мог по дням просмотреть объемы трафика. Это вам не Squid с его логами. Это статистика брандмауэра, тут логи не пишутся. Решение 1: создать отдельные скрипты (и базу данных) для создания не 8-часовой статистики, а, например, за последние 3 месяца. Но мне стало откровенно лень. Решение примитивное - каждый день копировать сгнерированное изображение с именем, например, "01-11-2009.png". Впоследствии можно будет всегда обратиться к нужному изображению и увидеть, какой соотношение почтового трафика было к веб-трафику и пр.

Примечание: мы "рисовали" график для 8 часового отрезка. Чтобы "запечатлеть" сутки, параметр --start в скрипте network_usage_graph.sh надо заменить на --start -24h.

Создаем файл copyTrafStatImage.sh и помещаем его в любую директорию на ваш вкус. Например, в /var/rrdtool/scripts.

Делаем файл исполняемым:

chmod +x /var/rrdtool/scripts/copyTrafStatImage.sh

Далее редактируем файл любым текстовым редактором. Я препочитаю "ee". Например, так:

ee /var/rrdtool/scripts/copyTrafStatImage.sh

Вносим в файл следующее содержимое:

copyTrafStatImage.sh

#!/bin/sh

currentDate=`date "+%d-%m-%Y"`

fileFrom="/var/www/rrdtool/images/network.png"
fileTo="/var/www/rrdtool/images/$currentDate.png"

cp $fileFrom $fileTo

Пояснять синтаксис не буду, все очевидно. Для понимания того, как менять формат имени файла (читай, текущей даты) смотрите "man date" - в самом конце мана несколько очевидных примеров. Данный скрипт будет создавать изображения вида 14-05-2009.png в той же директории, где расположен файл network.png.

Выполнение данного скрипта надо поместить в cron:

# crontab –e
0 */12 * * * /var/rrdtool/scripts/copyTrafStatImage.sh

Каждые 12 часов файл будет скопирован. Вы можете сделать так, чтобы в имени файла была не только дата (ежедневное копирование), а например, еще и час суток. Только чистите периодически директорию веб-сервера, да и просматривать будет муторнее.

Авторизуйтесь для добавления комментариев!


    забыли пароль?    новый пользователь?