
Всем привет! Меня зовут Михаил, и, как некоторые уже знают, я разработчик в команде ОС Astra Linux.
Ранее я уже осветил основы сбора логов в нашей операционной системе и рассказал об одном из ключевых элементов в этом процессе - syslog-ng. Теперь же, наконец, могу приступить к рассказу о подсистеме регистрации событий - нашей собственной разработке.
Я долго размышлял над тем, о чем именно писать, потому как мы с коллегами проделали и продолжаем большую и сложную работу - каждый кирпичик в ней имеет свою интересную историю. В итоге решил остановиться на кратком обзоре всей подсистемы, ведь без хотя бы общего представления о целом трудно переходить к частностям.
Также хочу оговориться, что всё, что будет описано ниже, актуально для самой новой на момент написания статьи версии Astra Linux Special Edition - 1.8.2. Сейчас мы всё ещё поддерживаем подсистему регистрации событий для ALSE 1.7, однако между версиями для 1.7 и 1.8 в некоторых частях нет различий, а в некоторых имеется существенная разница. Это обусловлено тем, что проект продолжает динамично развиваться. С моей же стороны параллельное освещение особенностей в ALSE 1.7, помимо очевидного усложнения статьи, будет своего рода взглядом в прошлое, в то время как хотелось бы сфокусироваться на настоящем и, быть может, немного заглянуть в будущее.
Итак, после столь долгого введения мы, наконец, можем приступить!
Как родилась подсистема регистрации событий
Причина, по которой мы начали разработку подсистемы регистрации событий, заключалась в необходимости решить две задачи.
Первое, с чем мы столкнулись — задача подсчёта удачных и неудачных входов в систему, фиксация времени предыдущего входа и вывод уведомления с собранной статистикой. В Astra Linux версии 1.7.0 за это отвечал пакет fly-notify-prevlogin, который производил простой анализ лога "/var/log/auth.log".
Ещё одна задача, которую предстояло решить нашей команде: сделать вывод уведомления при попытке запуска не подписанного исполняемого файла при включенном режиме замкнутой программной среды. Забегая немного вперед, скажу, что для этого потребовалась простая обработка записей в логе "/var/log/kern.log".
Ниже я попытаюсь максимально сжато описать ключевые идеи, которые мы выработали в результате реализации каждого из требований. Из-за сжатости изложения может показаться, что какие-то решения пришли к нам спонтанно и даже хаотично, но в действительности каждое из них сопровождалось комплексными исследованиями, разработкой архитектуры и долгими часами работы.
В начале был вход в систему
Началось же всё с того момента, когда наши внутренние тесты показали, что в некоторых сценариях использования операционной системы fly-notify-prevlogin выводил частично недостоверную информацию. Сперва мы попробовали найти какое-то простое решение проблемы, но в итоге упёрлись в то, что в любом случае оставались сценарии, в которых информация из "/var/log/auth.log" не позволяла сформировать полностью достоверную статистику входов.
Таким образом мы перешли к комплексным исследованиям проблемы, которые показали, что информация из лога подсистемы аудита "/var/log/audit/audit.log" лучше подходит для отслеживания и подсчёта удачных и неудачных входов.
Например, для подсчёта удачных входов достаточно находить в логе аудита записи вида:
type=USER_START msg=audit(1749621652.939:335): pid=1674 uid=0 auid=4294967295 ses=4294967295 subj=0:0:0:0:0 msg='op=PAM:session_open grantors=pam_unix,pam_systemd acct="fly-dm" exe="/usr/bin/fly-dm" hostname=splr11 addr=? terminal=/dev/tty7 res=success'
В данном случае нам достаточно, чтобы параметр type (тип записи) был равен значению USER_START, параметр exe соответствовал приложению, обеспечивающему вход в систему, например, /usr/bin/fly-dm, а параметр res (результат операции) был равен значению success.
Ещё одной важной особенностью лога аудита, характерной для Astra Linux SE, является наличие информации о мандатном уровне доступа, с которого был произведен вход, за что отвечает параметр subj. Это позволяет вести статистику для каждого настроенного в системе мандатного уровня.
Параллельно мы работали над реализацией второй задачи. При исследовании возможных способов отправки уведомления о попытке запуска не подписанного исполняемого файла мы так же, как и в случае со статистикой входов, пришли к выводу, что проще всего для этого анализировать содержимое стандартного лога "/var/log/kern.log".
В ALSE 1.8.2 соответствующие записи имеют примерно следующий вид:
Jun 16 13:13:45 alse-1832 kernel: DIGSIG:[ERROR] type=NOT_SIGNED path=/home/splr11/test uid=1000 gid=1001 ppid=4444 sid=3
И жили они вместе долго и счастливо
В вышеприведенных кейсах уже видна общая идея: отслеживать появление в логах некоторых значимых для нас записей и выдавать на них какую-то реакцию (в нашем случае - уведомление). Но в более глобальном смысле нам требовалось реагировать не на сами записи, а на некоторые системные события, наступление которых в случае вышеприведенных примеров мы могли отследить через логи.
Также видно, что источники логов могут различаться. В случае со статистикой входов нами в качестве первоисточника информации был выбран лог подсистемы аудита. В случае же с уведомлением о попытке запуска не подписанного исполняемого файла мы остановились на стандартном логе подсистемы Syslog. При этом нам хотелось иметь универсальный механизм отправки уведомлений для обоих источников.
В приведенных выше примерах визуальные различия между записями минимальны, но даже они существенны для дальнейшей обработки. Если в случае с аудитом для проверки того, что запись соответствует событию, достаточно разбиения на пары ключ-значение, то во втором примере нужно ещё каким-то образом проверять наличие подстроки "DIGSIG:[ERROR]". Отсюда вытекает необходимость масштабируемой обработки логов для проверки соответствия записей некоторым событиям.
Таким образом, мы подошли к идее, что имеются несколько разных источников логов, для которых нужны некоторые обработки с последующей отправкой обработанной информации в единую точку назначения.
Потому от идеи просто переписать fly-notify-prevlogin мы отказались практически сразу в пользу разработки более универсального и масштабируемого решения. И как раз здесь нам на помощь пришёл syslog-ng, который позволил объединить источники, обработку и отправку в рамках общего ядра. Кроме того, он обладает другими полезными качествами, которые я описал в соответствующей статье.
И еще раз вспомним, что в начале всё-таки был вход в систему
Одной из конечных точек в цепочке прохождения логов в Astra Linux Special Edition, начиная с версии 1.7.2, является файл "/parsec/log/astra/events". Это файл журнала системных событий. Однако в изначальных задачах ни о чём подобном речи не шло. Требовались только уведомления. Так откуда же он взялся, спросит удивленный читатель?
И здесь в пору вернуться к первому нашему подзаголовку: в начале был вход в систему.
Во время разработки алгоритмов подсчёта статистики входов на основе лога аудита мы пришли к выводу, что эффективнее всего накапливать статистику в процессе работы системы и выводить уведомление на основе заранее подготовленного результата. Ещё одним важным для нас моментом была необходимость подсчёта длительности пользовательской сессии. В данном случае нам так или иначе нужно было читать исходный лог для того, чтобы достоверно определить время начала сессии. Однако, лог аудита в некоторых случаях может достигать существенных размеров, и перечитывать его всякий раз даже с конца затруднительно.
Отсюда возникли следующие идеи:
Хранить в отдельных файлах статистику входов для каждого пользователя.
Иметь отдельный файл для хранения записей об авторизациях и завершении сессии.
Далее нужно было что-то делать с уведомлениями о запуске не подписанных исполняемых файлов. Дело в том, что исходные записи в "/var/log/kern.log" совершенно не годятся для того, чтобы выводить их в уведомлении как есть (что справедливо и для лога аудита). Требовалась некая обработка, которая приводила бы исходную запись к более понятному виду.
В процессе работы мы пришли к выводу, что преобразованные данные из "/var/log/kern.log" тоже хорошо бы где-то накапливать, прежде чем отправлять в уведомлении. И здесь нам пригодился тот же самый файл, в который мы записывали данные об авторизациях и завершении сессии.
В итоге нам стало понятно, что решение с отдельным файлом легко масштабировать для будущих новых событий. Также при работе над масштабируемостью системы мы продумали ещё одно полезное свойство файла. Дело в том, что и лог аудита, и стандартные логи Syslog содержат множество разнообразной информации. Выше я уже подсветил необходимость отслеживать только значимые для нас записи. Нахождение подобных записей в одном месте в некоторых сценариях избавляет от лишней обработки информации, имеющей второстепенную важность, поскольку всё заведомо лишнее было заранее отброшено нашей подсистемой.
Файл, аккумулирующий предобработанные записи о наиболее важных системных событиях, мы очевидным образом назвали журналом событий.
Это - наш формат!
Итак, мы определились с местом хранения данных. И параллельно с этим перед нами встал вопрос выбора формата хранения данных. Выше я уже подсветил момент, что сырые логи могут иметь определенные недостатки. Главным из них является разнообразие форматов. В зависимости от формата логи могут быть:
удобны для чтения человеком, но не удобны для машинного чтения;
удобны для машинного чтения, как, например, лог аудита, но не удобны для чтения человеком;
не удобны ни для машинного чтения, ни для чтения человеком.
Соответственно, нам хотелось соблюсти какую-то золотую середину, чтобы лог можно было легко обрабатывать машинным образом, но при этом сохранялась хотя бы минимальная читаемость человеком. Кроме того, в перспективе виделась необходимость передачи записей по сети на удаленный сервер логов и возможность интеграции с системами мониторинга.
В процессе разработки архитектуры регистрации событий было предложено использовать формат JSON. Различные эксперименты показали, что формат удобен для машинного чтения, также относительно удобен для чтения человеком; его можно обрабатывать штатными средствами syslog-ng и передавать системам мониторинга, поддерживающим указанный формат. Также выяснилось, что JSON удобно использовать и для конфигурации, о которой поговорим ниже.
Не рефлексируй - конфигурируй!
Исходя из вышеописанного, мы пришли к задаче преобразования записей из лога-первоисточника к формату JSON. Очевидно, что итоговый формат записей должен был быть плюс-минус единообразным вне зависимости от формата первоисточников. Соответственно, нам нужно было каким-то образом описывать правила преобразования из исходного формата в целевой.
Практика показала, что использование стандартных конфигов syslog-ng ограниченно подходит для данной задачи. Кроме того, мы хотели создать систему, которая в будущем могла бы стать независимой от демона логирования. Поэтому мы решили разработать собственный формат конфигурации для описания преобразований логов-первоисточников. Так родилось то, что получило имя конфигурация события.
Конфигурация события описывает:
Признаки, по которым мы можем считать, что запись в логе-первоисточнике соответствует некоему событию.
Набор некоторых обязательных параметров, которые должны присутствовать в записи журнала событий. Например, человекочитаемое название события.
Набор некоторых необязательных параметров, которые переносятся из лога-первоисточника в журнал событий.
Набор некоторых специфичных параметров. Например, параметр, определяющий, включена ли регистрация конкретного события.
Также мы пришли к выводу, что конфигурацию событий удобно разбить на две части:
Конфигурация по умолчанию, которая присутствует в системе всегда.
Пользовательская конфигурация в файле /etc/astra-syslog.conf, которая при необходимости переопределяет отдельные параметры по умолчанию.
Ещё мы пришли к выводу, что события удобно объединять в группы. Для этого достаточно хранить файлы конфигурации событий в отдельных каталогах, соответствующих группе, и иметь файл конфигурации группы с именем, соответствующим имени каталога.
Всё вышеперечисленное и составило основу (также мы часто называем это ядром) нашей подсистемы регистрации событий. А именно:
Логи и другие первоисточники.
Журнал системных событий и статистика авторизаций в формате JSON.
Возможность отправки уведомлений о событиях.
Конфигурация событий и групп событий.
Набор плагинов и конфигураций для syslog-ng, увязывающий всё это вместе.
В Astra Linux SE версии 1.8.2 ядро подсистемы регистрации событий предоставляется пакетом syslog-ng-mod-astra.
Чем администрировать подсистему регистрации событий
Рассказывая о рождении нашей подсистемы, я умышленно обошел стороной набор административных утилит, которые мы создали для взаимодействия с ней. Пришло время осветить и их.
Для Astra Linux SE версии 1.8.2 утилиты администрирования подсистемы регистрации событий можно разбить на следующие группы:
-
Самодиагностика подсистемы регистрации событий:
astra-event-diagnostics
-
Настройка регистрации событий:
fly-admin-events
astra-admin-events
-
Просмотр зарегистрированных событий:
fly-event-viewer
astra-event-viewer
Также имеется пользовательская служба astra-event-watcher, которая принимает информацию о событиях от ядра подсистемы и отправляет на её основе уведомления.
Все перечисленные утилиты предоставляются соответствующими пакетами.
Ниже я не стану расписывать подробно возможности каждой утилиты, поскольку в противном случае статья превратится в дублирование документации.
Самодиагностика
Одним из важных требований к нашей подсистеме является возможность самодиагностики. И за это отвечает утилита astra-event-diagnostics.
В Astra Linux SE 1.8.2 утилита может работать в трех режимах:
Запуск примерно раз в сутки по таймеру systemd для общей диагностики
Запуск в качестве службы (демона) для непрерывного отслеживания штатной работы syslog-ng
Ручной запуск для ситуативной диагностики
Результат самодиагностики можно посмотреть в журнале /parsec/log/astra/astra-event-diagnostics. По возможности информация дублируется также в основной журнал событий.
Настройка
Утилита fly-admin-events предоставляет графический интерфейс для настройки регистрации событий. Её ключевыми функциями являются включение и выключение регистрации отдельных событий и их групп, а также настройка уведомлений о событиях.
Также утилита позволяет настраивать перенаправление журнала событий в другую точку назначения, например, на удаленный сервер.
Утилита astra-admin-events предоставляет консольный интерфейс для настройки регистрации событий. В утилите упор делается на тонкие настройки регистрации тех или иных событий.
Просмотр
Для графического просмотра журнала событий служит утилита fly-event-viewer. Она предоставляет широкие возможности для удобной работы с журналом. Одной из отличительных особенностей утилиты является возможность работы с журналами событий большого размера.
Для удобного просмотра журнала событий в консоли служит утилита astra-event-viewer.
А что дальше?
Выше я уже писал, что за минувшее время со старта разработки подсистемы регистрации событий мы проделали большую и сложную работу. Однако это не повод останавливаться на достигнутом.
Кратко перечислю часть того, к чему мы стремимся.
Мы активно увеличиваем количество и качество регистрируемых событий,
Работаем над точностью и удобством самодиагностики,
Непрерывно развиваем функциональные возможности утилит администрирования.
На текущий момент наша подсистема уже способна регистрировать более сотни событий от различных компонентов, входящих в состав ОС, и при этом непрерывно развивается.
Для меня работа над подсистемой стала одним из значимых этапов в профессиональном развитии. Без ложной скромности скажу, что это один из моих любимых проектов, над которыми я когда-либо трудился. Также хочу выразить огромную благодарность всем коллегам, вместе с которыми мы выпустили и развиваем наше детище.
И на этом я завершаю свой краткий обзор подсистемы регистрации событий.
Комментарии (2)
b4444
17.07.2025 14:28Большая просьба, сделайте заготовки скриптов по событиям:
on_startup_pc
on_shutdown_pc
on_login_user
on_logoff_user
on_lock_userscreen
on_unlock_userscreen
Писал в техподдержку, они предложили самостоятельно мониторить подсистему аудита.А мне, все, что надо, вызывать скрипт записи событий во внешнюю БД)
ps. Понятно, что часть реализуется штатно. Что-то через cron (@reboot), что-то через скрипт логина в /etc/profile.d, но... Было бы здорово, если бы Астра приобрела чуть больше функционала, тем более, что они уже заложены в неё
trojan218
Всё просто замечательно.
DomainLogCollectors - дата?
astra-domain-event-diagnostics?