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-сервер на получение сообщений от клиентов и складывать их в отдельные каталоги. Для реализации данной задачи, Нужно написать шаблон для динамической генерации имен. И добавить правило, с указанием действия на шаблон.

  1. Создаем новый шаблон:
    template (name="SystemLogs" type="string" 
              string="/var/log/rsyslogs/logs/%HOSTNAME%/%PROGRAMNAME%/%PROGRAMNAME%.log")```
    
    

В этом объекте создается новая строка, в которой каждый раз будет генериться каталог для клиента и программы. %HOSTNAME%, %PROGRAMNAME% - это переменные, которые будут принимать значения хоста и программы. Тут думаю все ясно.

  1. Создадим правило:
    *.info;mail.none;authpriv.*;cron.none;kern.* -?SystemLogs```
    
    

Здесь вы говорим, что обратабываем:

  • Все источники(*) с уровнем info;
  • Источники authpriv, все уровни(*);
  • С ядра, все уровни(*);
  • mail,cron - none. И применяем на них шаблон SystemLogs.

Для проверки валидации конфига, команда:

$ rsyslogd -N1 -f /etc/rsyslog.conf

После перезапускаем rsyslog на сервере, и идем настраивать клиентов.

  1. На стороне клиента, в конфиге 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 немного некорректно отрабатывает. Поэтому нужно дополнительно проверят. И траблшутить.