Тут мы рассмотрим примеры настройки rsyslog и его настройку для сбора логов с нескольких хостов. Далее — эти логи будут выводится в веб-интерфейсе с помощью утилиты LogAnalizer.
Для начала — определим, чем именно является rsyslog:
rsyslogd — reliable and extended syslogd
Т.е. по сути rsyslog = syslog. Мало того, он даже использует те же конфигурационные файлы, которые использует syslog:
# vim /usr/include/sys/syslog.h
...
#ifdef SYSLOG_NAMES
CODE facilitynames[] =
{
{ "auth", LOG_AUTH },
{ "authpriv", LOG_AUTHPRIV },
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "ftp", LOG_FTP },
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "mark", INTERNAL_MARK }, /* INTERNAL */
{ "news", LOG_NEWS },
{ "security", LOG_AUTH }, /* DEPRECATED */
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
#endif
...
В ОС FreeBSD по-умолчанию исползуется syslogd:
# ps aux | grep syslog root 898 0.0 0.1 9612 664 ?? Ss 31Jan14 1:07.60 /usr/sbin/syslogd -s
Тогда как в CentOS — rsyslogd:
# ps aux | grep syslog root 22962 0.0 0.0 309024 3600 ? Ssl Apr04 1:04 /sbin/rsyslogd -i /var/run/syslogd.pid -c 5
Важна и версия, в данном случае рассматривается:
# rsyslogd -v rsyslogd 5.8.10, compiled with: FEATURE_REGEXP: Yes FEATURE_LARGEFILE: No GSSAPI Kerberos 5 support: Yes FEATURE_DEBUG (debug build, slow code): No 32bit Atomic operations supported: Yes 64bit Atomic operations supported: Yes Runtime Instrumentation (slow code): No
И операционная система:
# cat /etc/redhat-release CentOS release 6.4 (Final)
Обратите внимание — что rsyslogd использует PID-файл syslogd.pid.
Основной конифгурационный файл демона rsyslogd - /etc/rsyslog.conf, синтаксис которого весьма схож с файлом /etc/syslog.conf:
rsyslog.conf:
... # The authpriv file has restricted access. authpriv.* /var/log/secure ...
syslog.conf:
... auth.info;authpriv.info /var/log/auth.log ...
Однако — у rsyslog намного больше возможностей, в частности — связанных с использованием пересылки логов на удалённые сервера и использование сервера баз данных для их хранения.
Наша задача — настроить пересылку логов с нескольких хостов — на один, который будет играть роль логгер-сервера, и записывать их в базу данных MySQL для последующего вывода наиболее важных (т.е. тех, у которых уровень «приоритет» (severity) будет WARNING или выше) в веб-интерфейсе LogAnalizer.
Для того, что бы это корректно настроить — давайте посмотрим на общие источники данных для логгирования и их уровни (или устройства) (имя — числовой номер — описание):
kern - 0 — сообщения ядра;
user - 1 — сообщения пользовательских программ;
mail - 2 — сообщения от почтовой системы;
daemon - 3 — сообщения от тех системных демонов, которые в отличие от FTP или LPR не имеют выделенных специально для них категорий;
auth - 4 — все что связано с авторизацией пользователей, вроде login и su (безопасность/права доступа);
syslog - 5 — система протоколирования может протоколировать сообщения от самой себя;
lpr - 6 — сообщения от системы печати;
news - 7 — сообщения от сервера новостей. (в настоящее время не используется);
uucp - 8 — сообщения от UNIX-to-UNIX Copy Protocol. Это часть истории UNIX и вероятнее всего она вам никогда не понадобится (хотя до сих пор определенная часть почтовых сообщений доставляется через UUCP);
cron - 9 — сообщения от системного планировщика;
authpriv - 10 — то же самое, что и auth, однако сообщения этой категории записываются в файл, который могут читать лишь некоторые пользователи (возможно, эта категория выделена потому, что принадлежащие ей сообщения могут содержать открытые пароли пользователей, которые не должны попадать на глаза посторонним людям, и следовательно файлы протоколов должны иметь соответствующие права доступа);
ftp - 11 — при помощи этой категории вы сможете сконфигурировать ваш FTP сервер, что бы он записывал свои действия;
NTP - 12 — сообщения сервера времени;
(?) - 13 — log audit (?);
(?) - 14 — log alert (?);
clock daemon - 15 — сообщения демона времени;
local0 - local7 (local0 = 16 => local7 = 23) — зарезервированные категории для использования администратором системы. Категория local7 обычно используется для сообщений, генерируемых на этапе загрузки системы;
mark - 1 — присваивается отдельным сообщениям, формируемым самим демоном syslogd;
Далее — сообщения делятся по уровням их важности, т.е. — по «приоритету» (имя — числовой номер — описание):
emerg - 0 — (старое название PANIC) чрезвычайная ситуация, система неработоспособна;
alert - 1 — тревога;
crit - 2 — критическая ошибка (критическое состояние);
err (старое название ERROR) - 3 — сообщение об ошибке;
warning (старое название WARN) - 4 — предупреждение;
notice - 5 — информация о каком-то нормальном, но важном событии;
info - 6 — информационное сообщение;
debug - 7 — сообщения, формируемые в процессе отладки.
Перейдём непосредственно к настройке rsyslogd на «клиентских» серверах, т.е. — машинах, которые будут отсылать логи на «логгер-сервер», который будет их хранить в базе MySQL.
По-умолчанию конфигурация rsyslog в ОС CentOS 6.4 выглядите так:
# cat /etc/rsyslog.conf | egrep -v '^[[:space:]]*$|#' $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $IncludeConfig /etc/rsyslog.d/*.conf *.info;mail.none;authpriv.none;cron.none /var/log/messages authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron *.emerg * uucp,news.crit /var/log/spooler local7.* /var/log/boot.log local4.* /var/log/ldap.log
Нам необходимо:
а) добавить логгирование kern всех сообщений, кроме сообщений уровня debug, в локальный файл;
б) добавить пересылку kern сообщений с уровнем важности WARN или выше на сервер логгирования;
в) включить логгирование самого демона логгирования.
Включаем логгирование kern. Для этого — в файле достаточно просто раскомментировать строку:
#kern.* /dev/console
И изменить вывод данных с /dev/console на /var/log/kern.log.
Создаём файл:
# touch /var/log/kern.log
Редактируем файл /etc/rsyslog.conf:
# записываем всё, кроме "ниже" уровня warning в локальный файл kern.*;kern.!warning /var/log/kern.log # хотя, конечно, лучше писать всё - тогда просто создаём строку: kern.* /var/log/kern.log # всё, что выше warning - пересылаем на хост logger.host.com, используйте @@ для TCP и @ - для UDP kern.warning @logger.host.com # записываем всё от самого rsyslog в файл syslog.* /var/log/syslog.log
ВАЖНО: для записи сообщений от kern — убедитесь, что в конфигурации раскомментирована строка модуля:
$ModLoad imklog
Проверим файл конфигурации rsyslogd:
# rsyslogd -N1 rsyslogd: version 5.8.10, config validation run (level 1), master config /etc/rsyslog.conf rsyslogd: WARNING: rsyslogd is running in compatibility mode. Automatically generated config directives may interfer with your rsyslog.conf settings. We suggest upgrading your config and adding -c5 as the first rsyslogd option. rsyslogd: Warning: backward compatibility layer added to following directive to rsyslog.conf: ModLoad immark rsyslogd: Warning: backward compatibility layer added to following directive to rsyslog.conf: MarkMessagePeriod 1200 rsyslogd: Warning: backward compatibility layer added to following directive to rsyslog.conf: ModLoad imuxsock rsyslogd: End of config validation run. Bye.
Предупреждения — хорошо. В случае реальной опечатки — сообщение будет выглядеть так:
# rsyslogd -N1 rsyslogd: version 5.8.10, config validation run (level 1), master config /etc/rsyslog.conf rsyslogd: WARNING: rsyslogd is running in compatibility mode. Automatically generated config directives may interfer with your rsyslog.conf settings. We suggest upgrading your config and adding -c5 as the first rsyslogd option. rsyslogd: unknown priority name "" [try http://www.rsyslog.com/e/3000 ] rsyslogd: the last error occured in /etc/rsyslog.conf, line 41:"aaa" rsyslogd: warning: selector line without actions will be discarded rsyslogd: CONFIG ERROR: could not interpret master config file '/etc/rsyslog.conf'. [try http://www.rsyslog.com/e/2124 ]
Если ERROR нет — перезапускаем демон:
# service rsyslog restart Shutting down system logger: [ OK ] Starting system logger: [ OK ]
И смотрим созданный нами файл лога самого rsyslogd:
# tail -f /var/log/syslog.log Apr 7 15:53:30 senderhostname rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="15278" x-info="http://www.rsyslog.com"] start
Переходим к настройке пересылки логов на удалённй хост.
На «сервере-логгере» редактируем rsyslog.conf, находим и раскомментируем строки:
$ModLoad imudp $UDPServerRun 514
И строки:
$ModLoad imtcp $InputTCPServerRun 514
Если хотим, что бы данные передавались по TCP, а не UDP.
Проверим как всё работает.
Т.к. через утилиту logger нельзя передать сообщение «от ядра» — для проверки в rsyslog.conf на хосте-отправителе добавим такие строки:
mail.*;mail.!crit /var/log/maillog mail.warning @logger.host.com
Т.е. — все сообщения уровнем от facility mail «ниже» crit — мы пишем в локальный файл /var/log/maillog, а «выше» уровня warning — передаём на хост logger.host.com по протоколу UDP.
На нём же с помощью утилиты logger создадим такое сообщение:
# logger -p mail.notice -t TEST "Test warning for remote host MAIL.NOTICE"
Проверяем локальный файл:
# tail -n 1 /var/log/maillog Apr 7 19:29:55 senderhostname TEST: Test warning for remote host MAIL.NOTICE
А теперь — отправим сообщение с утровнем crit:
# logger -p mail.crit-t TEST "Test warning for remote host MAIL.CRIT"
Смотрим локальный файл на хосте-отправителе:
# tail -n 1 /var/log/maillog Apr 7 19:29:55 senderhostname TEST: Test warning for remote host MAIL.NOTICE
И на сервере-логгере:
# tail -n 1 /var/log/maillog Apr 7 19:31:36 senderhostname TEST: Test warning for remote host MAIL.CRIT
Проблема, однако, в том — что в таком случае все данные будут писаться в общий файл /var/log/maillog (или другой, в зависимости от facility).
Что бы этого избежать — rsyslogd имеет набор различных фильтров, которые позволяют перенаправлять данные в зависимости от заданных параметров.
Содержание
Фильтры в rsyslog
Фильтры в rsyslog бывают трёх типов:
1. RainerScript-based filters
2. «Traditional» severity and facility based selectors
3. Property-based filters
Подробнее о них можно почитать тут>>> или тут>>>.
Нам необходимо создать простое правило, которое будет логи получаемые от определённого хоста направлять в базу данных.
Проверим, что на сервере-логгере раскомментирована строка:
$IncludeConfig /etc/rsyslog.d/*.conf
В каталоге /etc/rsyslog.d/ создадим файл, например — /etc/rsyslog.d/sender.conf с таким содержимым:
# cat /etc/rsyslog.d/sender.conf $ModLoad ommysql :fromhost-ip, isequal, "10.***.***.35" :ommysql:localhost,Syslog,rsyslog,megaPassword
Проверяем корректность:
# rsyslogd -N1
И переазпускаем rsyslogd:
# service rsyslog restart Shutting down system logger: [ OK ] Starting system logger: [ OK ]
Тут подразумевается, что rsyslog-mysql установлен и база для него уже создана. Если нет — детали установки описаны в статье Сбор и просмотр логов Syslog в MySQL с помощью LogAnalyzer.
Теперь на сервере-отправителе выполняем:
# logger -p mail.crit -t TEST "Test warning for remote host MAIL.CRIT PropertyBased filter"
И проверяем последнюю запись в базе данных сервера-логгера:
mysql> select ID,Message from SystemEvents order by ID desc limit 1; +--------+--------------------------------------------------------------+ | ID | Message | +--------+--------------------------------------------------------------+ | 524051 | Test warning for remote host MAIL.CRIT PropertyBased filter | +--------+--------------------------------------------------------------+ 1 row in set (0.00 sec)
Работает, отлично. Теперь все сообщения с facility mail и уровнем важности warning и выше будут отправляться на сервер logger.host.com и на нём — записываться в базу данных, которую мы указали после модуля ommysql - localhost,Syslog,rsyslog,megaPassword.
В этом примере мы использовали Property-Based Filters. Полный список propname можно найти тут>>> (на удивление — найти его оказалось не такой простой задачей, как думалось поначалу…).
Поддерживаются следующие операции сравнения:
contains — проверка, содержит ли свойство указанное значение;
isequal — сравнивает строку value с содержимым свойства, они должны быть полностью одинаковы;
startswith — проверяет что свойство начинается со строки value;
regex — сравнивает свойство с заданным регулярным выражением.
Давайте попробуем что-то изменить в нашем фильтре.Например — мы хотим изменить фильтр так, что бы записывать только сообщения от facility = mail. Тогда — используем propname syslogfacility а имя устройства — укажем в числовом виде, для mail это будет 2:
# cat /etc/rsyslog.d/sender.conf $ModLoad ommysql :syslogfacility, isequal, "2" :ommysql:localhost,Syslog,rsyslog,megaPassword
На удалённом сервере выполняем:
# logger -p mail.crit -t TEST "Test warning for remote host MAIL.CRIT PropertyBased filter with syslogfacility=mail"
И на логгере — проверяем:
+--------+---------------------------------------------------------------------------------------+ | ID | Message | +--------+---------------------------------------------------------------------------------------+ | 524053 | Test warning for remote host MAIL.CRIT PropertyBased filter with syslogfacility=mail | +--------+---------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
Другой пример — с фильтрами RainerScript.
Возьмём тот же файл, и изменим его так:
if $fromhost-ip == '10.***.***.35' then /var/log/sender.log
Обратите внимание, что тут 'value' указывается в одинарных кавычках, а не двойных, как в Property-Based Filter.
Не забываем проверять корректность файла конфигурации:
# rsyslogd -N1
Перезапускаем rsyslogd, затем на удалённом сервере выполняем:
# logger -p mail.crit -t TEST "Test warning for remote host MAIL.CRIT RainerScript filter"
На сервере-логгере смотрим файл:
# tail -n 1 /var/log/sender.log Apr 9 12:30:48 senderhostname TEST: Test warning for remote host MAIL.CRIT RainerScript filter
Или — вариант с использованием модуля MySQL:
if $fromhost == 'senderhostname' then :ommysql:localhost,Syslog,rsyslog,megaPassword
Проверяем:
mysql> select ID,ReceivedAt,Message from SystemEvents order by ID desc limit 1; +--------+---------------------+----------------------------------------------------------------------+ | ID | ReceivedAt | Message | +--------+---------------------+----------------------------------------------------------------------+ | 524055 | 2014-04-09 14:15:24 | Test warning for remote host MAIL.CRIT RainerScript filter to MySQL | +--------+---------------------+----------------------------------------------------------------------+ 1 row in set (0.00 sec)
Другой пример:
if $msg contains 'RainerScript' then :ommysql:localhost,Syslog,rsyslog,megaPassword
Запускаем:
# logger -p mail.crit -t TEST "Test warning for remote host MAIL.CRIT RainerScript filter to MySQL - msg"
Проверяем:
mysql> select ID,ReceivedAt,Message from SystemEvents order by ID desc limit 1; +--------+---------------------+----------------------------------------------------------------------------+ | ID | ReceivedAt | Message | +--------+---------------------+----------------------------------------------------------------------------+ | 524060 | 2014-04-09 14:34:04 | Test warning for remote host MAIL.CRIT RainerScript filter to MySQL - msg | +--------+---------------------+----------------------------------------------------------------------------+ 1 row in set (0.00 sec)
Достоинство RainerScript в том, что в нём можно использовать селекторы типа «if", "if not", "and", "and not" или "or".
Например — использование селектора «and«:
if $msg contains 'RainerScript' and $fromhost == 'senderhostname' then :ommysql:localhost,Syslog,rsyslog,megaPassword
Запускаем:
# logger -p mail.crit -t TEST "Test warning for remote host MAIL.CRIT RainerScript filter to MySQL - msg and fromhost"
Проверяем:
mysql> select ID,ReceivedAt,Message from SystemEvents order by ID desc limit 1; +--------+---------------------+-----------------------------------------------------------------------------------------+ | ID | ReceivedAt | Message | +--------+---------------------+-----------------------------------------------------------------------------------------+ | 524062 | 2014-04-09 14:36:58 | Test warning for remote host MAIL.CRIT RainerScript filter to MySQL - msg and fromhost | +--------+---------------------+-----------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
Увы — в Rsyslog v5 судя по всему ещё нет поддержки конструкции else, но можно обойтись и без неё, например:
if ($fromhost == 'senderhostname' or $msg contains 'RainerScript') and not ($msg contains 'Test') then /var/log/1test.log if ($fromhost == 'senderhostname' or $msg contains 'RainerScript') and ($msg contains 'Test') then /var/log/2test.log
Тут- сообщения, от хоста senderhostname или содержащие в тексте слово RainerScript и НЕ содержащие в тексте слово Test попадут в файл /var/log/1test.log.
Сообщения от хоста senderhostname или содержащие в тексте слово RainerScript и содержащие в тексте слово Test попадут в файл /var/log/2test.log.
Проверяем:
# logger -p mail.crit -t TEST "This message to 1test.log Test" # logger -p mail.crit -t TEST "This message to 1test.log"
# tail -n1 /var/log/1test.log Apr 9 17:55:12 senderhostname TEST: This message to 1test.log
# tail -n1 /var/log/2test.log Apr 9 17:54:57 senderhostname TEST: This message to 1test.log Test
И ещё один пример:
# cat /etc/rsyslog.d/sshd.conf if $programname == 'sshd' and $msg contains 'Failed' then @logger
Ещё хотелось бы записать использование шаблонов и создание новой базы для rsyslog-mysql и LogAnalizer — но, видимо, это уже будет отдельная статья.
Ссылки по теме
http://wiki.rsyslog.com
http://www.rsyslog.com // примечание — на оф. сайте Rsyslog документация для последней версии, в данном случае — 8, синтаксис может отличаться
http://www.rsyslog.com
http://www.rsyslog.com
http://www.rsyslog.com
http://www.rsyslog.com
http://www.rsyslog.com
http://www.k-max.name
http://www.k-max.name
https://access.redhat.com
http://www.maths.cam.ac.uk




