Rsyslog - это механизм/система обработки потоковых сообщений. Тогда, сообщения журнала (логи) можно представить как поток событий.
Программы, которые известны syslog, заносят свои логи в специальный файл /dev/log
(сокет домена). Далее журнальные сообщения (лог-события) обрабатываются фильтрами и пересылаются по адресу назначения.
В Rsyslog каждый из этих этапов может быть сконфигурирован и дополнен модулям. Настройки службы rsyslog хранятся в файле - /etc/rsyslog.conf
.
Конфигурация rsyslog
Строки конфигурации системы rsyslog обрабатываются по умолчанию сверху вниз, порядок расположения директив имеет значение. В верхней части описываются глобальные настройки, которые применяются на сам rsyslog демон. В глобальных настроках указываются - загружаемые модули (Modules), формат сообщений, права собствености и разрешения на файлы, рабочий каталог. Фильтры (селекторы) составляют основную часть конфигурации, ими rsyslogd определяет как сортировать и обрабатывать сообщения. Фильтры формируются из выражений, в которых описаны критерии и действия. Давайте разберем каждый из разделов, что бы понимать как готовить rsyslog.
Модули
Модули демона rsyslog расширяют возможности механизма обработки. Через модули настраиваются источники входа и выхода, также модули могут анализировать и изменять сообщения. Модули которые начинаются с префикса im
(input module) - являются модулями входа, om
(output module)- модули выхода, mm
- модули модификации сообщений. Сейчас рассмотрим список часто используемых модулей:
imjournal
- модуль для интеграции с журналом systemd;imuxsock
- модуль, который считывает сообщения из сокета домена Unix;imklog
- модуль, который читает сообщения ядра в nix-подобных системах;imfile
- данный модуль преобразует данные из файла в формат сообшений системы syslog. Этот модуль может быть полезен для приложений, которые не имеют встроенной поддержки syslog;imtcp
,imudp
- модули, которые принимают сетевые сообщения через TCP/UDP, что позволяет централизировать ведение журналов.immark
- c помошью этого модуля, служба rsyslog может создавать сообщения с отметкой времени через равные промежутки времени.omfile
- модуль для записи сообщений в файл, единственный модуль который включен по умолчанию.omfwd
- модуль пересылает сообщения на удаленный сервер через TCP или UDP.ommysql
- модуль, который отправляет сообщения в базу данных mysql.
Правила и шаблоны
Базовый синтаксис правил такой:
selector action
Селекторы
В селекторе указывается источник (facility), посылающий сообщение. И уровень важности (severity) посылаемого сообщения. Синтаксис селектора такой:
facility.severity
--
источник.уровень_важности
Селекторы могут содержать символы *
- что означает “все”, и none
- нечего. В селекторе через запятые, можно перечислять несколько источников, допускается использования точки-запятой.
Примеры:
# Применяем действие ко всем сообщениям от facility.level
facility.level action
# Применяем действие ко всем сообщениям от facilityl.level и facility2.level
facilityl, facility2.level action
# Применяем действие только к сообщениям от facilityl.leve11 и facility2.level2
facilityl.levell; facility2.1eve12 action
# Применяем действие только источникам с заданным уровнем важности
*.level action
Какие источники (facility) могут быть:
*
- Все источники;auth
- Команды, связанные с безопасностью и авторизацией;authpriv
- Конфидециальные авторизационные данные;cron
- Демон cron;daemon
- Системные демоны;ftp
- Демон ftpd;kern
- Ядро;local0-7
- Восемь разновидностей локальных сообшений;mail
- Система sendmail, postfix и другие почтовые программы;user
- Пользовательские процессы.
Уровни важности (severity level) сообщений:
emerg
- Экстренные сообщения, что то вышло из строя;alert
- Срочные сообщения;crit
- Критические сообщения;warning
- Предупреждения;notice
- Необычные события, которые заслуживают внимания;debub
- Отладочные сообщения;info
- Информационные сообщения.
Для различных вариаций уровней, допускается использовать символы =
и !
перед указанием уровня. Символ =
- указывает использовать только этот уровень, а символ !
означает - исключить этот уровень и более высокие уровни.
Шаблоны
Шаблоны могут быть использованы, в случаи если нам нужно указать определенный формат лога или же мы динамически генерить имена для файлов. Примеры шаблонов, для указания форматов:
$template FileFormat,"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$template TraditionalFileFormat,"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$template ForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
$template TraditionalForwardFormat,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
Если же на центральном сервер, мы хотим разделать логи по клиентам, то можем воспользоваться шаблоном для генерации динамических имен:
$template DynFile,"/var/log/system-%HOSTNAME%.log"
В обновленном формате, можем использовать конструкцию:
template (name="DynFile" type="string" string="/var/log/system-%HOSTNAME%.log")
Действия
Поле с действиями опеределяет способ обработки сообщения, рассмотрим основные.:
имя_файла
- писать сообщения в указанный файл, на текущей системе.@имя_хоста
- пересылать сообщения на удаленный хост под этим именем@IP_адресс
- пересылать сообщения на удаленный хость под этим ip на TCP порт 514.@@IP_адресс
- пересылать сообщения на удаленный хость под этим ip на UDP порт 514.~
- игнорировать сообщения*
- вывести сообщения на экраны терминалов.?имя_шаблона
- это действие можем использовать при формировании файла, шаблоном.?имя_шаблона;шаблон_фильтра
- сообщения будут писаться в файл по указанному шаблону, предварительно обрабатываясь шаблоном фильтра.
Перед действием имя_файла
можно ставить дефис -
, чтобы указать, что файловая система не должна синхронизироваться после внесения каждой журнальной инфомации. Бывает это полезно, с точки зрения производительности систем ввода/вывода.
RainerScript
Это язык обработки для потоковых сообщений с возможностями фильтрации и управления потоком. С помошью различных выражений мы можем выбирать сообщения по определенным критериям и выполнять какое-либо действие. Например, следующее выражение направит сообщения аутентификации в файл: /var/log/auth.log
:
if $syslogfacility-text == 'auth' then {
action (type = "omfile" file = "/var/log/auth.log")
}
$syslogfacility-text
- это свойство сообщение, часть метаданных сообщения.
Ниже представлен список, часто используемых свойств:
$msg
- текст сообщения без метаданных;$rawmsg
- полное сообщение включая метаданные;$hostname
- имя хоста, пославшего сообщение клиента;$syslogfacility
- источник syslog в числовой форме;$syslogfacility-text
- источник syslog в текстовой форме;$syslogseverity
- уровень важности Syslog в числовой форме;$syslogseverity-text
- уровень важности Syslog в текстовой форме;timereported
- временная метка сообщения.
Как стало ясно из примера, RainerScript активно использует условные операторы - if, then, else, else if
. Также можно использовать цикл - for
.
В качестве условия могут быть использованы:
- Логические выражения -
and, or, not
, для группировки нескольких условий. - Операторы сравнений:
==
- равно,!=
- не равно,>
,<
,>=
,<=
- больше/меньше, больше/меньше или равно,startswith
,!startswith
- выражение “начинается с” и его отрицательная форма,contains
,!contains
- выражение “содержит” и также его отрицательная форма.
Практика
Давайте перейдем к практическому заданию. Таска достаточно банальная, нужно настроить rsyslog-сервер на получение сообщений от клиентов и складывать их в отдельные каталоги. Для реализации данной задачи, Нужно написать шаблон для динамической генерации имен. И добавить правило, с указанием действия на шаблон.
- Создаем новый шаблон:
template (name="SystemLogs" type="string" string="/var/log/rsyslogs/logs/%HOSTNAME%/%PROGRAMNAME%/%PROGRAMNAME%.log")```
В этом объекте создается новая строка, в которой каждый раз будет генериться каталог для клиента и программы. %HOSTNAME%
, %PROGRAMNAME%
- это переменные, которые будут принимать значения хоста и программы. Тут думаю все ясно.
- Создадим правило:
*.info;mail.none;authpriv.*;cron.none;kern.* -?SystemLogs```
Здесь вы говорим, что обратабываем:
- Все источники(*) с уровнем info;
- Источники
authpriv
, все уровни(*); - С ядра, все уровни(*);
- mail,cron - none.
И применяем на них шаблон
SystemLogs
.
Для проверки валидации конфига, команда:
$ rsyslogd -N1 -f /etc/rsyslog.conf
После перезапускаем rsyslog на сервере, и идем настраивать клиентов.
- На стороне клиента, в конфиге rsyslog, провисываем.:
*.* @@192.168.190.45
В процессе настройки rsyslog-сервера, я заранее раскоментировал модуль imtcp
, что бы он мог принимать входящие сообщения поверх tcp.
Давайте рассмотрим другой пример, например нам понадобилось парсить сообщения от ssh демона, и складывать их в другой каталог. Для решения данной задачи воспользуемся возможностями rainerscript. Для начала напишем шаблон, для генерации пути. Потом реализуем условие, по которому будет использоваться шаблон. На сервер rsyslog, добавляем:
# Шаблон
template (
name="sshdAuth"
type="string"
string="/var/log/rsyslog/security/%HOSTNAME%-%PROGRAMNAME%.log"
)
# Рулсет
if $programname == 'sshd' then {
action(type="omfile" dynafile="sshdAuth")
}
И так, шаблон просто генерит нам путь куда мы будет складывать наши логи. В рулсете, мы проверяем условие. Если имя программы ($programname) равно sshd, тогда выполнить действие. А в действие мы подключаем модуль, и в качестве аргумента передаем название нашего шаблона.
UPD: Скорее всего, в конце у нас будет основное правило для записи всех остальных программ. И что бы не повторно не писать логи по sshd
куда-нибудь еще, нужно добавить закрывающее правило.
# Рулсет
if $programname == 'sshd' then {
action(type="omfile" dynafile="sshdAuth")
}
if $programname == 'sshd' then ~
Auditd
Если на серверах стоит системный демон - auditd
, то для того что бы он начал писать в rsyslog нужно плагин:
$ yum install audispd-plugins
После установки плагина, нужно его активировать в конфиге: /etc/audit/plugins.d/syslog.conf
:
active = yes
direction = out
path = /sbin/audisp-syslog
type = always
args = LOG_INFO
format = string
И теперь просто нужно перезапустить auditd
:
$ service auditd restart
Logrotate
Последнее условие, говорит демону больше не писать лог по этой программе.
И в завершении, хотелось бы добавить. Правильным решением будет натравить logrotate демона, для архивации лог файлов. Ну или как вариант, файлы архивировать и складывать в отдельные каталоги.
В нашем случаи логи пишутся сюда: /var/log/rsyslog/security/%HOSTNAME%-%PROGRAMNAME%.log
. Настройка logrotate будет такой:
/var/log/rsyslog/*/*/*.log
{
daily
rotate 1460
create
dateext
compress
dateext
missingok
notifempty
delaycompress
sharedscripts
postrotate
/usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
endscript
}
Параметры, для ротации логов:
hourly
- эта опция говорит ротировать лог каждый час;size
- задает размер лога, при котором лог файл будет сротирован. В нашем случаи значения 50М. Значит все файлы равные или больше 50мб будут ротироваться.missingok
- этот параметр говорит, что если лог-файла не существушет, то нечего не предпринимать;compress
- сжимаем логи;sharedscripts
- если в целевом каталоге несколько лог файлов, то секция -postrotate/endscript
будет выполнена по многу раз.
Далее мы перезапускает rsyslog демона, после ротации.
UDP: В процессе тестирования, logrotate немного некорректно отрабатывает. Поэтому нужно дополнительно проверят. И траблшутить.