Всем привет! Меня зовут Михаил, и, как некоторые уже знают, я разработчик в команде ОС 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 ограниченно подходит для данной задачи. Кроме того, мы хотели создать систему, которая в будущем могла бы стать независимой от демона логирования. Поэтому мы решили разработать собственный формат конфигурации для описания преобразований логов-первоисточников. Так родилось то, что получило имя конфигурация события.

Конфигурация события описывает:

  1. Признаки, по которым мы можем считать, что запись в логе-первоисточнике соответствует некоему событию.

  2. Набор некоторых обязательных параметров, которые должны присутствовать в записи журнала событий. Например, человекочитаемое название события.

  3. Набор некоторых необязательных параметров, которые переносятся из лога-первоисточника в журнал событий.

  4. Набор некоторых специфичных параметров. Например, параметр, определяющий, включена ли регистрация конкретного события.

Также мы пришли к выводу, что конфигурацию событий удобно разбить на две части:

  1. Конфигурация по умолчанию, которая присутствует в системе всегда.

  2. Пользовательская конфигурация в файле /etc/astra-syslog.conf, которая при необходимости переопределяет отдельные параметры по умолчанию.

Ещё мы пришли к выводу, что события удобно объединять в группы. Для этого достаточно хранить файлы конфигурации событий в отдельных каталогах, соответствующих группе, и иметь файл конфигурации группы с именем, соответствующим имени каталога.

Всё вышеперечисленное и составило основу (также мы часто называем это ядром) нашей подсистемы регистрации событий. А именно:

  • Логи и другие первоисточники.

  • Журнал системных событий и статистика авторизаций в формате JSON.

  • Возможность отправки уведомлений о событиях.

  • Конфигурация событий и групп событий.

  • Набор плагинов и конфигураций для syslog-ng, увязывающий всё это вместе.

В Astra Linux SE версии 1.8.2 ядро подсистемы регистрации событий предоставляется пакетом syslog-ng-mod-astra.

Чем администрировать подсистему регистрации событий

Рассказывая о рождении нашей подсистемы, я умышленно обошел стороной набор административных утилит, которые мы создали для взаимодействия с ней. Пришло время осветить и их.

Для Astra Linux SE версии 1.8.2 утилиты администрирования подсистемы регистрации событий можно разбить на следующие группы:

  1. Самодиагностика подсистемы регистрации событий:

    • astra-event-diagnostics

  2. Настройка регистрации событий:

    • fly-admin-events

    • astra-admin-events

  3. Просмотр зарегистрированных событий:

    • fly-event-viewer

    • astra-event-viewer

Также имеется пользовательская служба astra-event-watcher, которая принимает информацию о событиях от ядра подсистемы и отправляет на её основе уведомления.

Все перечисленные утилиты предоставляются соответствующими пакетами.

Ниже я не стану расписывать подробно возможности каждой утилиты, поскольку в противном случае статья превратится в дублирование документации.

Самодиагностика

Одним из важных требований к нашей подсистеме является возможность самодиагностики. И за это отвечает утилита astra-event-diagnostics.

В Astra Linux SE 1.8.2 утилита может работать в трех режимах:

  1. Запуск примерно раз в сутки по таймеру systemd для общей диагностики

  2. Запуск в качестве службы (демона) для непрерывного отслеживания штатной работы syslog-ng

  3. Ручной запуск для ситуативной диагностики

Результат самодиагностики можно посмотреть в журнале /parsec/log/astra/astra-event-diagnostics. По возможности информация дублируется также в основной журнал событий.

Настройка

Утилита fly-admin-events предоставляет графический интерфейс для настройки регистрации событий. Её ключевыми функциями являются включение и выключение регистрации отдельных событий и их групп, а также настройка уведомлений о событиях.

Также утилита позволяет настраивать перенаправление журнала событий в другую точку назначения, например, на удаленный сервер.

Утилита astra-admin-events предоставляет консольный интерфейс для настройки регистрации событий. В утилите упор делается на тонкие настройки регистрации тех или иных событий.

Просмотр

Для графического просмотра журнала событий служит утилита fly-event-viewer. Она предоставляет широкие возможности для удобной работы с журналом. Одной из отличительных особенностей утилиты является возможность работы с журналами событий большого размера.

Для удобного просмотра журнала событий в консоли служит утилита astra-event-viewer.

А что дальше?

Выше я уже писал, что за минувшее время со старта разработки подсистемы регистрации событий мы проделали большую и сложную работу. Однако это не повод останавливаться на достигнутом.

Кратко перечислю часть того, к чему мы стремимся.

  • Мы активно увеличиваем количество и качество регистрируемых событий,

  • Работаем над точностью и удобством самодиагностики,

  • Непрерывно развиваем функциональные возможности утилит администрирования.

На текущий момент наша подсистема уже способна регистрировать более сотни событий от различных компонентов, входящих в состав ОС, и при этом непрерывно развивается.

Для меня работа над подсистемой стала одним из значимых этапов в профессиональном развитии. Без ложной скромности скажу, что это один из моих любимых проектов, над которыми я когда-либо трудился. Также хочу выразить огромную благодарность всем коллегам, вместе с которыми мы выпустили и развиваем наше детище.

И на этом я завершаю свой краткий обзор подсистемы регистрации событий.

Комментарии (2)


  1. trojan218
    17.07.2025 14:28

    Всё просто замечательно.

    DomainLogCollectors - дата?

    astra-domain-event-diagnostics?


  1. 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, но... Было бы здорово, если бы Астра приобрела чуть больше функционала, тем более, что они уже заложены в неё