Журналирование событий, происходящих в системе является неотъемлемой частью функционала любого серьезного программного обеспечения. Операционная система или приложение должны в обязательном порядке рассказывать о своей жизни: регистрировать входы в систему, сбои, ошибки и другие значительные события.
В этой статье мы будем говорить о том, как устроено логирование событий в ОС Linux. В качестве примера будет рассматриваться Ubuntu Linux 22.04, однако в других дистрибутивах основные элементы будут сходными.
Локальные логи
В Линуксе журналируются как системные события, так и события от приложений и служб. По умолчанию события журналируются в каталог /var/log/. В нем имеется множество различных *.log файлов содержащих события от различных источников в текстовом виде.
В зависимости от установленных в системе приложений, в каталоге /var/log могут находиться различные файлы журналов. Но мы приведем список основных файлов журналов:
Файлы /var/log/syslog или /var/log/messages — глобальный системный журнал. В нем мы можем найти события, произошедшие с момента запуска системы от различных компонентов ОС — ядра, служб, устройств и т. д.
Журнал событий var/log/kern.log — содержит сообщения от ядра и предупреждения, которые могут быть полезны при устранении ошибок, произошедших при работе пользовательских модулей встроенных в ядро.
Журналы /var/log/auth.log или /var/log/secure — наиболее интересны для безопасников, так как они содержат информацию об авторизации пользователей, то есть попытки не/успешных входов в систему и методов аутентификации.
События от оборудования и драйверов устройств находятся в файле /var/log/dmesg. В этом файле фиксируются ошибки работы драйверов и оборудования.
События установки системы можно найти в файле /var/log/anaconda.log, а в файле /var/log/boot.log находятся логи загрузки системы.
Еще один журнал событий, который представляет особый интерес для специалистов по информационной безопасности это /var/log/audit — лог демона auditd. Логирование аудита мы еще рассмотрим далее в этой статье.
Журнал демона crond /var/log/cron — содержит результаты выполнения различных событий планировщика задач cron.
Это основные журналы событий, которые есть в большинстве дистрибутивов Linux. Также в зависимости от установленных приложений в /var/log/ могут находиться логи БД MySQL или веб серверов Apache/Nginx.
Что, собственно, пишем
Каждое приложение само решает, какие события ему писать в лог, поэтому общим у всех событий в /var/log будет разве что формат, да и то с некоторыми исключениями. Поэтому, в качестве примера содержимого журнала событий рассмотрим сообщения в /var/log/messages.
Уровни логов или приоритеты определяет ядро Linux. В зависимости от важности события, ему присваивается один из приоритетов, представленных ниже:
KERN_EMERG - система неработоспособна;
KERN_ALERT - нужно немедленно принять меры;
KERN_CRIT - критическая ошибка;
KERN_ERR - обычная ошибка;
KERN_WARNING - предупреждение;
KERN_NOTICE - замечание;
KERN_INFO - информационное сообщение;
KERN_DEBUG - сообщения отладки.
Соответственно, при логировании можно указать в настройках работы Syslog, события с каким приоритетом сохранять в каком файле.
Еще одним важным значением в сообщения является категория (Facility). Категории могут принимать значения от 0 до 23, им соответствуют различные категории системных служб: 0.
— kernel, 2 — mail, 7 — news и т. д. Последние 8 категорий — от local0 до local7 — определены для служб, не попадающих в предопределённые категории.
Локальные недостатки
По умолчанию все журналы событий хранятся на машине локально. Однако даже в небольшой сети такой способ хранения логов не является оптимальным. Для чего нужны журналы событий? Для решения возможных проблем с производительностью, для мониторинга состояния системы и для своевременного выявления подозрительных и вредоносных активностей. И для всех этих активностей лучше использовать централизованное хранение логов на отдельном сервере или хранилище. Дело в том, что на локальных узлах в целях экономии места логи циклически удаляются (ротируются) то есть, при достижении максимального объема файла журнала, самые старые события удаляются. В результате мы можем лишиться важных событий просто потому что они уже затерлись более новыми. Также, не слишком удобно проверять логи локально на каждом узле, централизованно анализировать гораздо проще. Большой поток событий может создавать дополнительную нагрузку на дисковую подсистему.
Отдельная история про безопасность. В случае, если злоумышленник проник в систему и захватил права root он сможет без труда изменить файлы журналов так, чтобы скрыть следы своих действий. В процессе взлома такие события, как подбор пароля и вход в систему обязательно отражаются в логах, и если их сразу передать на центральный сервер и проанализировать, то можно предотвратить атаку еще до того, как злоумышленнику удалось захватить систему.
Таким образом, необходимо сохранять основные события со всех узлов на отдельном сервере. Изначально в ОС Linux для этого использовался протокол Syslog, по которому события могли передаваться между серверами. Но этот протокол имеет существенные недостатки. В качестве транспортного протокола Syslog использует UDP, то есть отправка пакетов ведется без подтверждения получения. Таким образом нет никакой гарантии, что отправленное с одного узла событие на сервер Syslog будет доставлено. В случае с критически важными событиями это не очень хорошо.
Кроме того, протокол Syslog не предусматривает никаких механизмов защиты. События передаются в открытом виде и могут быть легко перехвачены.
Rsyslog
В качестве альтернативы можно использовать протокол RSyslog (Rocket‑fast System for log processing). Преимуществами этого протокола является наличие многопоточности (то есть возможность обрабатывать большой объем событий), использование протокола TCP на транспортном уровне, наличие шифрования SSL, а также возможность сохранения готовых событий в базы данных (MySQL, PostgreSQL, Oracle). Отдельного внимания заслуживает возможность фильтрации по любой части лога и полностью настраиваемый формат вывода событий.
Ниже приводится фрагмент конфига /etc/rsyslog.conf с клиентской машины.
В качестве примера настроим пересылку логов с клиента на сервер. Для этого на стороне сервера необходимо в файле /etc/rsyslog.conf добавить следующие строки:
$ModLoad imtcp
$InputTCPServerRun 514
Для большей надежности мы используем TCP в качестве транспортного протокола и стандартный порт 514, на котором сервер будет слушать трафик.
Для того, чтобы не запутаться в собираемых журналах событий лучше всего сразу сохранять пришедши е события в отдельных файлах. Идея складывать все события в один файл очень плоха, так как файлы логов должны, либо подвергаться циклической чистке, когда старые события удаляются, либо архивироваться. И то, и другое ведет к тому, что вы можете потерять часть важных событий. Поэтому лучше использовать следующую структуру /var/log/rsyslog/ИМЯ_УЗЛА_источника/приложение_источник.log
. Для этого надо добавить в файл конфигураций следующие строки:
$template RemoteLogs,"/var/log/rsyslog/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteLogs
Так как Rsyslog может содержать набор правил для обработки приходящих событий, нам необходимо явно сообщить ему, что пришедшие события не надо дополнительно обрабатывать.
Для этого добавим:
& ~
Далее перезапускаем службу Rsyslog:
systemctl restart rsyslog
На клиенте необходимо настроить пересылку событий на сервер. Для этого нужно создать отдельный файл конфигураций:
nano /etc/rsyslog.d/log.conf
В этот файл добавляем строку, указывающую какие журналы, и куда необходимо пересылать
*.* @@192.168.222.135:514
В примере мы пересылаем все события с клиента на порт 514 сервера 192.168.222.135.
Но если нас не интересуют все события, а нужны только логи из конкретной категории, например аутентификации, то нужно указать следующее:
auth.* @@192.168.222.135:514
Далее также перезапускаем Rsyslog
systemctl restart rsyslog
В журнале событий на сервере можно убедиться, что события с клиента успешно приходят:
Модули Rsyslog
Иногда возникает необходимость в более интеллектуальной обработке журналов событий, поступающих с источников. Для этого в Rsyslog имеются модули. Модули ввода — начинаются с im, собирают информацию из различных источников. Модули вывода — начинаются на om, и они отправляют сообщения. Могут отправлять сообщения как в файл так и по сети или складывать в базу. Модули фильтрации — начинаются с fm. Фильтруют сообщения по разным параметрам. Модули парсинга — начинаются с pm. Позволяют проводить синтаксический анализ. Модули модификации сообщений — начинаются с mm. Меняют содержимое обрабатываемых сообщений. Модули генерации строк — начинаются с sm. Позволяют генерировать строки на основе обрабатываемых сообщений.
Посмотрим пример для того, чтобы было понятно, о чем идет речь. В следующем примере мы будем на клиенте отслеживать изменения в файле audit.log и отправлять на сервер события с уровнем warning и выше и категорией local0.
$ModLoad imfile
$InputFileName /var/log/audit/audit.log
$InputFileTag tag_audit_log:
$InputFileStateFile audit_log
$InputFileSeverity warning
$InputFileFacility local0
$InputRunFileMonitor
*.* @@192.168.222.135:514
На сервере также необходимо модифицировать файл конфигураций для того, чтобы данные события сохранялись в отдельном файле:
$template HostAudit, "/var/log/rsyslog/%HOSTNAME%/audit.log"
Local0.* ?HostAudit
Сохранение в БД
Собранные события удобно хранить в текстовых файлах лишь когда их не более десятка. При большем объем лучше использовать СУБД для централизованного хранения и обработки событий. В качестве примера будем отправлять все события в MySQL. Вот общий формат таких настроек:
$ModLoad ommysql
*.* :ommysql:адрес_сервера,имя_базы,имя_пользователя,пароль
Например:
mail.* :ommysql:127.0.0.1,syslog,syslogwriter,topsecret
В случае использования PostgreSQL формат будет следующий:
$ModLoad ompgsql
*.* :ompgsql:адрес_сервера,имя_базы,имя_пользователя,пароль
Использование СУБД позволяет не только собирать и хранить события, но и делать запросы по наличию тех или иных событий, строить отчеты и реагировать на появление определенных событий. Хотя, когда количество источников начинает измеряться сотнями, для работы с событиями уже лучше использовать специализированные решения. Например, для обработки событий ИБ лучше использовать решения класса SIEM (Security Information Event Management).
Заключение
В этой статье были рассмотрены основы журналирования в ОС Linux. Помимо описанных Syslog и Rsyslog, в Линуксе существуют также другие механизмы журналирования, да и Rsyslog содержит массу полезных функций. Так что продолжение следует…
Что такое инфраструктура как код? Что значит «сервера снежинки»? Как автоматизировать работу с серверами? Ответы на эти и другие вопросы дадим на бесплатном уроке, после которого вы узнаете как автоматизировать рутинные процессы создания и настройки серверов с помощью инструментов vagrant, terraform, ansible.
Комментарии (4)
Johan_Palych
02.02.2023 15:09+1В Ubuntu Linux 22.04 используется данная связка: rsyslog, journald(systemd-journald.service) и logrotate. Интеграция journald и rsyslog.
Официальная документация:
https://www.rsyslog.com/doc/v8-stable/configuration/index.html https://www.rsyslog.com/ubuntu-repository/ https://launchpad.net/~adiscon/+archive/ubuntu/v8-stable?field.series_filter=jammy
ZillahGiovanni
03.02.2023 08:53У себя решили использовать vector.dev кроме сбора логов собираем аудит, с фильтрацией и обогащением.
Altwazar
03.02.2023 14:38Логи можно вместо mysql/postgress писать сразу в manticore, чтобы запросы к ним для анализа проходили быстрее. Удобно, что это тот же sql и ничего дополнительно с rsyslog-ом изобретать не надо. Пример template rsyslog:
template(name="StdSQLformat" type="list" option.sql="on") { constant(value="insert into system_events (Message, Facility, HostIP, HostName, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag)") constant(value=" values ('") property(name="msg") constant(value="', ") property(name="syslogfacility") constant(value=", '") property(name="fromhost-ip") constant(value="', '") property(name="hostname") constant(value="', ") property(name="syslogpriority") constant(value=", '") property(name="timereported" dateFormat="unixtimestamp") constant(value="', '") property(name="timegenerated" dateFormat="unixtimestamp") constant(value="', ") property(name="iut") constant(value=", '") property(name="syslogtag") constant(value="')") }
Таблица в мантикоре:
create table system_events(Message text, Facility int, HostIP string, HostName string, Priority int, DeviceReportedTime timestamp, ReceivedAt timestamp, InfoUnitID int, SysLogTag string) engine='columnar' min_prefix_len = '2';
lexore
Может рассказать им про journald?