В коллекции планигов Munin, безусловно, есть огромное количество плагинов для получения статистики с самых разных сервисов и системных параметров. В дистрибутиве CentOS они располагаются в директории /usr/share/munin/plugins/. Однако есть потрясающая возможность создавать свои плагины, которые будут подключены к общей системе статистики, и анализиоровать практически всё, что угодно.
В именовании файлов плагинов Munin принято однообразные плагины (относящиеся к одной подсистеме или сервису) начинать с одного префикса. Например, mysql_bytes, mysql_innodb, mysql_queries и т.д. Впрочем, название файла не обязано соответствовать категоризации плагина. Категория и всевозможные параметры задаются внутри скрипта.
Плагины Munin представляют из себя обычные скрипты, чаще всего написанные на shell, которые принимают параметры config и autoconf, а также возвращают текущие значения для наблюдаемых параметров. При вызове с параметром config должны быть выданы настройки модуля (об этом ниже).
Создание плагина для мониторинга сетевых соединений
Возьмём в качестве основы модуль netstat. Здесь приводить его содержание не буду; содержание скрипта может отличаться от версии к версии. Скопируем его в свой файл, например, в файл my_connections:
[root@saytostroy.ru]# cd /usr/share/munin/plugins/ [root@saytostroy.ru]# cp netstat my_connections
И откроем его на редактирование. Для начала нам потребуется заменить текстовое описание head1 NAME, head1 CONFIGURATION, head1 AUTHOR и т.д., хотя в нашем случае их содержание не играет роли.
Перейдём непосредственно к коду. Ветка, отрабатывающая autoconf нас так же не интересует — там проверяется наличие исполнительной программы файрвола iptables. Поскольку мы заимствуем аналогичный модуль, то менять там ничего не требуется. Перейдём сразу к config, где и содержатся основные параметры. Все они выводятся через оператор echo. Рассмотрим их подробнее:
- graph_title определяет отображаемое в статистике название плагина;
- graph_vlabel — название раздела плагина. Будет отображаться в виде списка в просмотре готовой статистики;
- graph_category — принадлежность к категории всей системы Munin. В нашем случае здесь сохраняется network. Нужен для правильного распределение по категориям Munin. Таким образом все сетевые данные оказываются в одном месте:
- graph_period — период измерений, отображаемый на графиках. Оставим по умолчанию second, чтобы значения приводились из масштаба «число значений в секунду». Важное замечание: несмотря на то, что скрипт будет запускаться значительно реже (5 раз в минуту по умолчанию через планировщик заданий), значения будут приводиться исходя из секундного интервала;
- graph_info — описание, которое отображается в системе статистики в раскрытой вкладке выбранного плагина;
- graph_scale — производить ли масштабирование графика. Наш выбор: no.
Итак, в нашем случае будет следующая «шапка» конфигурационной части плагина:
echo 'graph_title MyConnections' echo 'graph_vlabel TCP connections' echo 'graph_category network' echo 'graph_period second' echo 'graph_info This graph shows the number of TCP connections.' echo 'graph_scale no'
Далее идёт непосредственно наш измеряемый параметр. Для примера я выбрал отображение числа SYN-пакетов протокола TCP. Эта статистика может быть полезна для обнаружение SYN-flood-атак. Мы наглядно увидим лавинообразное увеличение числа таких пакетов и получим уведомление, если правильно настроим Munin. Наш параметр будет называться syn и получит следующие значения:
echo 'syn.label SYN' echo 'syn.type ABSOLUTE' echo 'syn.max 1000000' echo 'syn.min 0' echo 'syn.info The number of SYN TCP packets.' print_warning syn print_critical syn
Здесь мы казали метку нашей кривой на графике (label), тип значений (ABSOLUTE — т.е., скрипт будет возвращать актуальные значения и их не нужно аккумулировать), минимальное и максимальное значение параметра и пояснение для графика (info). Так же будут высылаться уведомления в случае крайних значений параметра (значения для warning и critical задаются в общей конфигурации Munin или в конфиге модуля через параметры my_connections.syn.warning и my_connections.syn.critical).
Теперь нужно перейти к получению непосредственных значений, но вначале немного разберёмся с iptables, из которого мы их планируем извлекать.
Получение параметров из файрвола iptables
Для того, чтобы получать статистику по конкретным интересующим нас параметрам из файрвола, необходимо задать дополнительные правила. Нас интересуют пакеты с флагом SYN, поэтому мы добавляем такое правило:
iptables -I INPUT 1 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN -j ACCEPT
Мы добавили его первым номером, чтобы гарантировать обработку любого поступившего пакета. Если добавить правило в конец, возможно, пакет уже будет отброшен.
Теперь посмотрим, что показывает статистика файрвола:
[root@saytostroy.ru]# iptables -L -n -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x02 ...
В поле pkts отображено текущее число пакетов по данному правилу, а bytes — суммарный объём наших пакетов с флагом SYN. Пока что они нулевые.
Для наших нужд потребуется каждый раз обнулять статистику файрвола, чтобы при вызове iptables собранные данные не суммировались (мы ведь выбрали type ABSOLUTE в параметрах модуля). Для этого будем использовать параметр вызова -x, который будет обнулять статистику при каждом вызове. Кроме того, нас интересуют несокращённые значения (без обозначения K для килобайтов и т.д.), пожтому мы используем параметр -Z. Чтобы разгрузить программу от лишнего обращения к DNS для разрешения IP-адресов, зададим параметр -n. Итак, итоговый вызов будет следующим:
iptables -L -x -n -v -Z
Теперь вернёмся к нашему новоиспечённому плагину и завершим работу над ним, задав вывод актуального значения параметра syn.
Отображение значений параметра
Из вывода iptables по команде выше мы должны выбрать только ту цепочку, за которой мы хотим наблюдать, а именно — за нашим правилом. Для этого воскользуемся следующей цепочкой команд:
iptables -L -x -n -v -Z | awk '/tcp flags:0x3F/0x02/ { print "syn.value " $1 }'
Сохраним наш модуль и проверим его вывод при помощи программы munin-run
[root@saytostroy.ru]# /usr/sbin/munin-run my_connections syn.value 32
Уже успели пробежать три десятков пакетов, инициирующих сетевые соединения, поэтому мы увидели value больше нуля.
Отлично. Теперь остаётся только подключить наш модуль к Munin и перезапустить сервис:
[root@saytostroy.ru]# sudo ln -s /usr/share/munin/plugins/my_connections /etc/munin/plugins/my_connections [root@saytostroy.ru]# service munin-node restart
Мы установили символическую ссылку на наш модуль в папку /etc/munin/plugins/, где «лежат» модули, задействованные в системе.