Недавно мы в Selectel запустили систему аудит-логов. Она предназначена для централизованного сбора и анализа событий, возникающих при работе сервисов Selectel. А также — обеспечивает единый доступ к операционным и административным действиям, фиксирует различные события с ресурсами аккаунта и помогает отслеживать потенциально подозрительные активности.

Важным фактором для удобства расследований и анализа является формат самих аудит-логов. Он должен быть структурированным и единообразным вне зависимости от части системы, где происходит события. При этом — достаточно информативным, чтобы можно было установить обстоятельства события.

Структура аудит-логов выглядит следующим образом:

[
{
  "event_saved_time": "2025-09-29T13:13:25.196Z",
  "event_id": "string",
  "event_type": "string",
  "event_time": "2025-09-29T13:13:25.196Z",
  "status": "string",
  "error_code": "string",
  "request_id": "string",
  "subject": {
    "id": "string",
    "type": "string",
    "name": "string",
    "auth_provider": "string",
    "is_authorized": true,
    "authorized_by": [
      "string"
    ],
    "credentials_fingerprint": "string"
  },
  "resource": {
    "id": "string",
    "type": "string",
    "name": "string",
    "account_id": "string",
    "project_id": "string",
    "location": "string",
    "details": {},
    "old_values": {
      "additionalProp1": {}
    },
    "new_values": {
      "additionalProp1": {}
    }
  },
  "source_type": "string",
  "request": {
    "remote_address": "string",
    "user_agent": "string",
    "type": "string",
    "path": "string",
    "method": "string",
    "parameters": "string"
  },
  "schema_version": "string"
}
]

Основные задачи аудит-логов можно условно разделить на два направления: превентивный контроль и реактивный анализ.

Превентивный контроль — мониторинг инфраструктуры на предмет отклонений и потенциально опасных действий. На этом этапе аудит-логи используются для раннего обнаружения подозрительной активности, аномалий и попыток несанкционированного доступа, в том числе с помощью SIEM-систем.

Реактивный анализ — разбор уже произошедших инцидентов. Структурированные записи позволяют восстановить полный контекст события: кто инициировал действие, какие ресурсы затронуты, в какой последовательности происходили операции и каков был результат.

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

Чтобы начать анализировать события, которые происходят в системе, нужно сначала эти события получить и передать анализатору — SIEM-системе. Этому и будет посвящена данная статья.

Краткое описание SIEM-систем

SIEM (Security Information and Event Management) — это класс систем, предназначенных для централизованного сбора, корреляции и анализа событий безопасности. Такие решения позволяют объединять данные из разных источников — облачных сервисов, сетевых устройств, приложений — и на их основе выявлять подозрительные действия или инциденты безопасности.

Типичная архитектура SIEM-системы включает несколько ключевых компонентов:

  • Уровень сбора данных — агенты, коллекторы или API, собирающие логи и телеметрию с конечных точек, серверов, сетевых устройств, облачных сервисов и SaaS-приложений.

  • Парсинг и нормализация — стандартизация различных форматов логов в единообразную схему для обеспечения кросс-платформенной корреляции.

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

  • Хранилище и индексация — долгосрочное хранение обработанных логов и алертов для последующего анализа.

  • Система оповещений и визуализации — дашборды и механизмы генерации уведомлений для команд безопасности.

В данной статье мы рассмотрим Wazuh и RuSIEM. 

Wazuh

Wazuh — это мощное open source-решение с гибкими возможностями кастомизации, особенно в области host security и endpoint monitoring.

Общая архитектура Wazuh.
Общая архитектура Wazuh.

Как видим, в качестве источников логов могут бы самые различные системы, а производительность Wazuh-сервера можно расширять за счет добавления нод в Wazuh-кластер. 

Основные функции Wazuh связаны с отслеживанием событий, созданием правил корреляции и разработкой панелей мониторинга (дашбордов) для анализа данных. Многие правила уже доступны в готовом виде, однако их потребуется доработать, чтобы избежать большого количества ложных срабатываний. 

При этом создавать правила довольно просто. «Из коробки» есть механизм их тестирования перед сохранением. Также в системе предусмотрен скоринг уязвимостей хостов с рекомендациями по их устранению. И есть возможность проверки соответствия хостов нормативным требованиям, таким как PCI DSS, GDPR и другим. 

Можно реализовать контроль целостности, указав файлы или ветки реестра, изменение которых необходимо отслеживать, и получать оповещения при их изменении. Кроме того, в модуле MITRE ATT&CK все события классифицируются по тактикам и техникам соответствующей матрицы и визуализируются в виде графиков.

RuSIEM

RuSIEM представляет собой коммерческую российскую SIEM-платформу с акцентом на удобство управления правилами корреляции и комплексное управление инцидентами.

Архитектура RuSIEM.
Архитектура RuSIEM.

Как видим, в компонент lsinput можно подавать данные из различных источников, после чего происходит нормализация полученный логов, сохранение их в PostgreSQL и передача в модуль lsfilter для анализа на предмет симптомов угроз. Далее модуль корреляции анализирует уже обработанные события на предмет совпадения правилами корреляции и выявления инцидентов ИБ. 

Благодаря сохранению данных в elasticsearch можно очень удобно работать с событиями ИБ при ретроспективном анализе. Система предоставляет следующие возможности.

  • Симптомы — дружественные названия симптомов позволяют быстро находить события среди миллионов других. Нет необходимости запоминать текст события или event.id.

  • Корреляция в реальном времени — обеспечивает быстрое обнаружение угроз и аномалий. Гибкий графический дизайнер правил корреляции позволяет создавать пользовательские правила без навыков программирования.

  • Управление инцидентами — централизованная система управления инцидентами безопасности.

  • Долгосрочное хранение событий — обеспечивает хранение событий для ретроспективного анализа.

  • Отчеты — автоматизированная генерация отчетов для упрощения аудита.

  • Управление уязвимостями — обнаружение уязвимостей через анализ сетевого трафика и событий.

Сравнение Wazuh и RuSIEM

Обе SIEM-системы поддерживают сбор логов через агенты и syslog, нормализацию и парсинг различных форматов логов, корреляцию событий безопасности, управление инцидентами и долгосрочное хранение событий. Но есть и между данными решениями различия, о которых важно знать на старте.

Критерий

Wazuh

RuSIEM

Лицензирование и стоимость

Бесплатное open source-решение

Коммерческое решение с лицензионной моделью

Фокус функциональности

Сильный фокус на host security, endpoint detection and response

Комплексная SIEM-платформа с акцентом на корреляцию и управление инцидентами

Простота развертывания

Низкий барьер для начала работы

Требует специализированной настройки и интеграции

Кастомизация

Высокий уровень кастомизации декодеров и правил, требует экспертизы для тонкой настройки

Графический интерфейс для создания правил корреляции без программирования

Обнаружение угроз

Rule-based обнаружение, требует настройки для продвинутых угроз

Комбинация rule-based и behavioral-анализа с поддержкой ML-модулей

Что Wazuh, что RuSIEM — следуют общей архитектуре SIEM. Выбор зависит от специфических требований организации: ресурсных ограничений, необходимости в локализованной поддержке, наличия экспертизы для настройки и поддержки, требований к обнаружению продвинутых угроз и необходимости соответствия российским регуляторным требованиям. 

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

Security Center

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

Исследовать →

Способы интеграции источников с SIEM

Как мы обсудили ранее, любая SIEM-система выполняет четыре базовые операции с логами, прежде чем аналитик увидит их в поиске или уведомлениях: сбор, парсинг, нормализацию и корреляцию.

Сбор

Обычно SIEM-системы собирают события несколькими стандартными способами: через syslog (UDP/TCP/TLS), с помощью агентов, через API или webhook‑интеграции, путем импорта файлов (CSV/JSON).

Логи обычно передаются как syslog‑сообщения (в «сыром» текстовом виде, CEF, LEEF или JSON), JSON по HTTP(S) в транспорте собственного коннектора SIEM или как файлы JSON/CSV, которые затем подбирает агент или коллектор.

Парсинг

Парсинг — это превращение строки лога в набор полей: временную метку, пользователя, IP‑адрес, тип события, объект и т. д. Типичные техники парсинга в SIEM представляют из себя регулярные выражения, шаблоны (pattern matching), парсинг структурированных форматов (JSON, CEF, LEEF, CSV, KVP) и ML‑/LLM‑подходы для сложных и разнообразных логов.

Нормализация

Нормализация выравнивает разные форматы в общую схему. Независимо от того, пришел лог от панел��, AD или прокси, SIEM приводит его к единому набору полей (например, src_ip, dst_ip, user, event_type, object, result).

Нормализация включает переименование полей, приведение типов и форматов (включая время), классификацию событий по категориям и классам, обогащение (GeoIP, каталоги пользователей).

Хранение и корреляция

Нормализованные события индексируются и сохраняются на месяц и более. Часто — до 1–3 лет и дольше, с разделением на «горячее» и «холодное» хранилища.

Модуль корреляции уже опирается не на «сырые события», а на нормализованные поля, что позволяет писать универсальные правила. Например, «5 и более неудачных логинов, затем успешный логин этим же пользователем с того же IP».

Пути интеграции с SIEM

С точки зрения SIEM, аудит‑лог — просто еще один источник. Важно лишь, по какому протоколу его отправлять и в каком формате. Рассмотрим несколько способов отправки логов в SIEM.

Syslog (RFC 3164/5424, CEF, LEEF)

Классический и до сих пор основной способ отправки логов в SIEM — syslog.

Syslog — это стандартный протокол и формат для передачи системных журналов (логов) между приложениями и центральным сервером сбора событий. Он позволяет отправлять сообщения в реальном времени по сети, классифицировать их по уровню важности и источнику, а также централизованно хранить и обрабатывать логи.

Существуют различные форматы данных при передаче по syslog: «сырой» syslog с произвольной строкой в MSG‑части; syslog + формат CEF (Common Event Format) в MSG; syslog + LEEF (Log Event Extended Format); syslog + JSON (когда MSG — валидный JSON‑объект); syslog + CEF (аудит‑лог входа в панель) и syslog + JSON (аудит‑лог входа в панель).

Для SIEM‑интеграции аудит‑логов через syslog необходимо реализовать отправку на адрес/порт SIEM (обычно UDP/TCP/514 или TLS‑порт), определить формат и структуру данных (CEF/LEEF/JSON), гарантировать стабильную временную метку и хостнейм в syslog‑заголовке.

HTTP(S) и API / Webhook‑интеграции

Многие облачные и SaaS‑сервисы экспортируют SIEM‑логи через API в формате JSON или через webhook‑нотификации.

Типовой сценарий

  • Панель/продукт реализует эндпоинт /audit/export или поток webhook‑событий.

  • Коннектор SIEM периодически опрашивает API или принимает webhooks и преобразует JSON в нормализованный вид.

  • Результат — поток нормализованных событий в общей схеме SIEM.

Агенты и файлы

Если продукт пишет аудит‑логи в файл (JSON/CSV/текст), агент SIEM (или универсальный лог‑коллектор) может отслеживать последние данные (аналог утилиты tail), забирать новые записи, парсить и нормализовать их по заданным шаблонам.

Настройка интеграции аудит-системы Selectel в SIEM

Архитектура интеграции

Для начала рассмотрим систему на верхнем уровне. Сама интеграция с системой аудита реализована через REST API, предоставляющий доступ к событиям в режиме почти реального времени, и состоит из следующих компонентов:

Схема интеграции аудит-системы с SIEM.
Схема интеграции аудит-системы с SIEM.
  1. Клиентское приложение или сервис получает временный токен авторизации.

  2. С помощью токена отправляется запрос к эндпоинту аудита.

  3. API возвращает список событий в выбранном диапазоне времени или с применением фильтров.

  4. Клиент сохраняет и обрабатывает полученные события — локально, в SIEM или с помощью собственной системы аналитики.

Безопасность: авторизация и аутентификация

Теперь больше обратимся к деталям. Первый шаг для получение аудит-логов — авторизация. Если вы уже работали с API Selectel, то, вероятно, уже умеете получать токены. А если нет, то это можно сделать по инструкции. Также ниже будет пример простого кода, с помощью которого можно получать токены.

В нашем случае понадобится авторизация через X-Auth-Token сервисного пользователя. Нужно создать такого пользователя с ролью member. Для этого нужно войти в раздел Аккаунт → Сервисные пользователи — и нажать Добавить сервисного пользователя. После этого важно не забыть добавить роль member, а также запомнить имя пользователя и пароль — они нам понадобятся в дальнейшем. 

Схема для получения токена следующая. Мы должны пойти на специальный авторизационный URL — с паролям и данными, указывающими на сервисного пользователя и аккаунт, и получить в ответе токен. Ниже представлена простая функция для получения токена. Примеры кода в статье будут немного урезанные и упрощенные, полный код доступен в репозитории на GitHub.

async def get_auth_token(username: str, password: str, account_id: str):
   auth_url = "https://cloud.api.selcloud.ru/identity/v3/auth/tokens"

   async with aiohttp.ClientSession() as session:
       data = {
           "auth": {
               "identity": {
                   "methods": ["password"],
                   "password": {
                       "user": {
                           "name": username,
                           "domain": {"name": account_id},
                           "password": password,
                       }
                   },
               },
               "scope": {"domain": {"name": account_id}},
           }
       }
       async with session.post(
           auth_url,
           headers={"Content-Type": "application/json"},
           data=json.dumps(data),
       ) as response:
           response.raise_for_status()
           token = response.headers["X-Subject-Token"]
           return token

Базовый скрипт для получения логов

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

Сам доступ к аудит-логам имеет фильтр: можно получать события по дате, события конкретных типов, проектов, источников и не только. Вот полный список возможных фильтров:

Имя параметра

Назначение

Где передается

Формат/ограничения

event_saved_time_from

Фильтрует логи по времени, оставляя только логи со временем появления после определенной даты

Body

Время в RFC 3339 (ISO 8601) формате.

Пример: "2025-07-10T13:00:01+00:00"

event_saved_time_from

Фильтрует логи по времени, оставляя только логи со временем появления до определенной даты

Body

Время в RFC 3339 (ISO 8601) формате.

Пример: "2025-07-10T13:00:01+00:00"

event_types

Фильтр по типам событий: оставляет только те события, которые имеют типы, переданные в этом фильтре

Body

Список типов событий из документации.

Пример: [“iam.account.fill”, "iam.user.login”]

project_ids

Фильтр по id проектов

Body

Список id проектов, по которым нужны логи.

Пример: 

[“2128277041c64440a1a10cdfc0fe1a5f”]

source_types

Фильтр по типу источников события

Body

Список источников.

Пример: [“iam”, “billing”]

cursor

Указатель на первый элемент страницы

Query

Зашифрованный указатель на начало страницы. Не нужно генерировать самому — берется из ответа, из блока pagination.

dir

Направление сортировки

Query

Может быть только:

backward (от новых к старым);

forward (от старого к новым, используется по-умолчанию)

Для фильтрации по времени используется event_saved_time (время появления события в системе аудит-логов), а не временная метка самого события, чтобы обеспечить устойчивую пагинацию для API. Причина в том, что события поступают асинхронно и могут задерживаться, если использовать пагинацию/фильтрацию на основе метки времени события: они могут появляться в середине каких-то существующих страниц, из-за чего есть риск упустить какие-то важные события.

Параметры, отвечающие за страницу, передаются в query. Параметры фильтрации — в теле запроса, так как содержат списки, могут быть очень длинными и могут превышать лимиты по передаваемой длине URL.

Максимальное количество логов в ответе — 1 000. Чтобы можно было получать и остальные данные корректно, реализована курсорная пагинация. Допустим, нужно получить логи с самого начала, откуда они доступны (Selectel хранит логи за последние 90 дней) до текущего момента. Причем хотелось бы после не завершать работу, а раз в какое-то время запрашивать новые логи, чтобы все время иметь актуальное состояние на своей стороне. Это стандартная задача.

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

async def get_audit_logs(token: str, cursor: str | None = None) -> dict:
   async with aiohttp.ClientSession() as session:
       params = {
           "limit": "100",
       }
       if cursor:
           params["cursor"] = cursor

       async with session.post(
               "https://api.selectel.ru/audit-logs/v1/logs",
               headers={"X-Auth-Token": f"{token}"},
               params=params,
       ) as response:
           response.raise_for_status()
           data = await response.json()
           return data

Теперь для стабильного получения данных из API-сервиса нам нужно регулярно вызывать приведенную функцию и сохранять полученные логи. При этом — запоминать последнее записанное событие, чтобы в момент, когда дойдем до конца, можно было запросить ту же самую страницу и понять, появились ли на ней новые логи или нет. И так как пагинация курсорная, то есть указывает на конкретную строку, с которой мы читаем данные, то она будет довольно устойчивым решением:

async def main() -> None:
   token = "<your_token>"
   repeated = False
   last_event = {}
   cursor = None
   while True:
       response = await get_audit_logs(token, cursor)
       result = response["data"]
       if result:
           if not repeated:
               # do smth with data
               add_events(result)
               last_event = {
                   "event_id": result[-1]["event_id"],
                   "event_saved_time": result[-1]["event_saved_time"],
               }
           else:
               for i, event in enumerate(result):
                   if (
                           event["event_id"] == last_event["event_id"]
                           and event["event_saved_time"]
                           == last_event["event_saved_time"]
                   ):
                       if i == len(result) - 1:
                           break
                       add_events(result[i + 1 :])
                       last_event = {
                           "event_id": result[-1]["event_id"],
                           "event_saved_time": result[-1]["event_saved_time"],
                       }
                       break
       next_cursor = response["pagination"].get("next_cursor")
       if next_cursor:
           repeated = False
           cursor = next_cursor
           continue

       repeated = True
       await asyncio.sleep(30)

Для дальнейшей обработки данных пока будем просто сохранять их в файл. За это отвечает функция add_events:

def format_events(events: list[dict]) -> str:
   return "\n".join(json.dumps(event) for event in events)


def add_events(events: list[dict]):
   with open("events.txt", "a", encoding="utf-8") as file:
       file.write(format_events(events) + "\n")

Таким образом, мы будем получать в файле events.txt строки с событиями в JSON-формате. Полный код интеграции можно найти на GitHub.

Интеграция с SIEM

Просто получать аудит-логи и сохранять их у себя для просмотра вручную — довольно муторная и кропотливая работа. Конечно, ее хотелось бы автоматизировать — для этого и существуют SIEM-системы, которые способны обрабатывать массивы этих данных, выявлять необычные паттерны и несанкционированные доступы.

Напомним, что для интеграции с разными системами есть разные пути: отправка логов через syslog, сохранение их в файл или передача по HTTP(s). По сути, сохранение логов в файл мы рассмотрели в предыдущем пункте — так что сфокусируемся на интеграции через syslog.

Для SIEM‑интеграции аудит‑логов через syslog необходимо реализовать отправку на адрес/порт SIEM (обычно UDP/TCP/514 или TLS‑порт), определить формат и структуру данных (CEF/LEEF/JSON), гарантировать стабильную временную метку и хостнейм в syslog‑заголовке. 

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

class SyslogTransport:
   def __init__(
       self,
       host: str,
       port: int = 514,
   ):
       self.host = host
       self.port = port

       # Create syslog logger
       self.syslog_logger = logging.getLogger("auditlogs")
       self.handler = SysLogHandler(address=(self.host, self.port))
       self.syslog_logger.addHandler(self.handler)
       self.syslog_logger.setLevel(logging.INFO)
       self.syslog_logger.propagate = False

   def send(self, event: dict) -> bool:
       try:
           message = json.dumps(event, ensure_ascii=False)
           self.syslog_logger.info(message)
           self.handler.flush()  # Force send immediately
           return True
       except Exception as e:
           logger.error(f"Failed to send event: {e}")
           return False

   def send_batch(self, events: list[dict]) -> int:
       success_count = 0
       for event in events:
           if self.send(event):
               success_count += 1
       return success_count

   def close(self):
       try:
           self.handler.close()
           self.syslog_logger.removeHandler(self.handler)
           logger.info("Syslog connection closed")
       except Exception as e:
           logger.error(f"Error closing syslog handler: {e}")

   def __enter__(self):
       return self

   def __exit__(self, exc_type, exc_val, exc_tb):
       self.close()

Теперь этот транспорт можно интегрировать в изначальный скрипт:

...
token = "<your_token>"
syslog = SyslogTransport("127.0.0.1", 5514)
repeated = False
...

После можно заменить add_event на send_batch:

syslog.send_batch(result)

Отлично — теперь у нас получился законченный скрипт, который умеет собирать аудит-логи и отправлять их в SIEM по syslog. В примерах есть возможность выбирать удобные для конкретных случаев способы работы с данными — сохранять в файлы или передавать по syslog или HTTP(s).

Настройка импорта логов SIEM

Wazuh

Для начала установим Wazuh-сервер по инструкции. Его также можно развернуть из уже подготовленного образа в my.selectel.ru, как это описано в документации.

Установку можно произвести, выполнив команду:

curl -sO https://packages.wazuh.com/4.14/wazuh-install.sh && sudo bash ./wazuh-install.sh -a

После установки панель управления будет доступна по адресу: https://<wazuh-server-ipaddr>.

Пройдя авторизацию, попадаем в раздел Overview:

В выпадающем меню слева доступны все разделы для управления логами, приходящими в Wazuh. 

Получение логов в Wazuh настроим в два шага. 

Шаг 1. В файле конфигурации выгрузки логов из API my.selectel.ru укажем следующие параметры:

# Обязательные параметры для доступа к API Selectel
AUDIT_LOGS_URL=https://api.selectel.ru/audit-logs/v1/logs
USERNAME=<указываем учетную запись>
PASSWORD=<указываем пароль>
ACCOUNT_ID=<указываем id учетной записи>

# Тип транспорта для отправки событий (выберите один: file, syslog, http)
TRANSPORT_TYPE=file

# Настройки для syslog транспорта (обязательны если TRANSPORT_TYPE=syslog)
SYSLOG_HOST=127.0.0.1
SYSLOG_PORT=5514

# Настройки для HTTP транспорта (обязательны если TRANSPORT_TYPE=http)
HTTP_URL=http://localhost:8080/events
HTTP_USERNAME=admin
HTTP_PASSWORD=secret

В параметре TRANSPORT_TYPE указываем значение file — это позволит сохранять полученные логи в файле, указанном в скрипте savers.py. В этом случае настройки для syslog и HTTP-транспорта будут игнорироваться.

Далее запустим сохранение логов в файл и проверим результат:

python3 example.py
tail -f /var/ossec/logs/audit.log

{"event_saved_time": "2025-12-09T11:43:14Z", "event_id": "ed253073-75ea-4563-919a-f01427f5a4a8", "event_type": "audit_logs.audit_logs.download", "event_time": "2025-12-09T11:42:22Z", "status": "success", "error_code": "", "request_id": "9604fd73-2225-4946-85bf-c9a47fa6359f", "subject": {"id": "logs", "type": "user", "name": "", "auth_provider": "keystone", "is_authorized": true, "authorized_by": [], "credentials_fingerprint": ""}, "resource": {"id": "517043", "type": "audit_logs", "name": "", "account_id": "517043", "project_id": "", "location": "", "old_values": null, "new_values": null, "details": null}, "source_type": "audit_logs", "request": {"remote_address": "185.55.58.180", "user_agent": "Python/3.12 aiohttp/3.13.2", "type": "http", "path": "", "method": "", "parameters": ""}, "schema_version": "1.0"}
{"event_saved_time": "2025-12-09T11:43:45Z", "event_id": "0d760adf-c5d4-485b-bbbc-a38cac72859f", "event_type": "audit_logs.audit_logs.download", "event_time": "2025-12-09T11:42:52Z", "status": "success", "error_code": "", "request_id": "52da9e95-f875-48cf-b8f9-d10c60f3980f", "subject": {"id": "logs", "type": "user", "name": "", "auth_provider": "keystone", "is_authorized": true, "authorized_by": [], "credentials_fingerprint": ""}, "resource": {"id": "517043", "type": "audit_logs", "name": "", "account_id": "517043", "project_id": "", "location": "", "old_values": null, "new_values": null, "details": null}, "source_type": "audit_logs", "request": {"remote_address": "185.55.58.180", "user_agent": "Python/3.12 aiohttp/3.13.2", "type": "http", "path": "", "method": "", "parameters": ""}, "schema_version": "1.0"}

Отлично, события в формате JSON сохраняются в нужный файл. Переходим к следующему шагу.

Шаг 2. Чтобы Wazuh знал, откуда брать события, необходимо добавить в последний блок <ossec_config> файла /var/ossec/etc/ossec.conf следующую запись:

 <localfile>
    <log_format>json</log_format>
    <location>/var/ossec/logs/audit.log</location>
 </localfile>

Эта конфигурация говорит Wazuh, что необходимо брать лог из локального файла /var/ossec/logs/audit.log, причем он будет в формате JSON.

Для отображения событий в Wazuh необходимо, чтобы все распарсенные события попадали под какие-то правила (rules). Добавим новое правило в файл /var/ossec/etc/rules/local_rules.xml:

<group name="audit_logs,">
  <rule id="100001" level="3">
    <decoded_as>json</decoded_as>
    <description>Audit log event from Selectel</description>
    <field name="event_type">audit_logs.audit_logs.download</field>
    <options>no_full_log</options>
    <group>audit_logs,</group>
  </rule>
</group>

В данном правиле мы задаем id новому правилу, указывая уровень его критичности 3. Под это правило будут попадать все события, у которых в поле event_type находится значение audit_logs.audit_logs.download.

После внесенных изменений необходимо перезапустить службу wazuh-manager:

systemctl restart wazuh-manager

Теперь проверим, что сырые события действительно парсятся и попадают под созданное правило:

cat /var/ossec/logs/audit.log | /var/ossec/bin/wazuh-logtest

Этой командой мы передаем содержимое файла /var/ossec/logs/audit.log в качестве входных данных в исполняемый файл /var/ossec/bin/wazuh-logtest. В результате получаем:

**Phase 1: Completed pre-decoding.

**Phase 2: Completed decoding.
    name: 'json'
    event_id: 'ed253073-75ea-4563-919a-f01427f5a4a8'
    event_saved_time: '2025-12-09T11:43:14Z'
    event_time: '2025-12-09T11:42:22Z'
    event_type: 'audit_logs.audit_logs.download'
    request.remote_address: '185.55.58.180'
    request.type: 'http'
    request.user_agent: 'Python/3.12 aiohttp/3.13.2'
    request_id: '9604fd73-2225-4946-85bf-c9a47fa6359f'
    resource.account_id: '517043'
    resource.details: 'null'
    resource.id: '517043'
    resource.new_values: 'null'
    resource.old_values: 'null'
    resource.type: 'audit_logs'
    schema_version: '1.0'
    source_type: 'audit_logs'
    status: 'success'
    subject.auth_provider: 'keystone'
    subject.authorized_by: '[]'
    subject.id: 'logs'
    subject.is_authorized: 'true'
    subject.type: 'user'

**Phase 3: Completed filtering (rules).
    id: '100001'
    level: '3'
    description: 'Audit log event from Selectel'
    groups: '['audit_logs', 'audit_logs']'
    firedtimes: '103'
    mail: 'False'
**Alert to be generated.


**Phase 1: Completed pre-decoding.

**Phase 2: Completed decoding.
    name: 'json'
    event_id: '0d760adf-c5d4-485b-bbbc-a38cac72859f'
    event_saved_time: '2025-12-09T11:43:45Z'
    event_time: '2025-12-09T11:42:52Z'
    event_type: 'audit_logs.audit_logs.download'
    request.remote_address: '185.55.58.180'
    request.type: 'http'
    request.user_agent: 'Python/3.12 aiohttp/3.13.2'
    request_id: '52da9e95-f875-48cf-b8f9-d10c60f3980f'
    resource.account_id: '517043'
    resource.details: 'null'
    resource.id: '517043'
    resource.new_values: 'null'
    resource.old_values: 'null'
    resource.type: 'audit_logs'
    schema_version: '1.0'
    source_type: 'audit_logs'
    status: 'success'
    subject.auth_provider: 'keystone'
    subject.authorized_by: '[]'
    subject.id: 'logs'
    subject.is_authorized: 'true'
    subject.type: 'user'

**Phase 3: Completed filtering (rules).
    id: '100001'
    level: '3'
    description: 'Audit log event from Selectel'
    groups: '['audit_logs', 'audit_logs']'
    firedtimes: '104'
    mail: 'False'
**Alert to be generated.

Этот результат говорит о том, что на втором этапе успешно прошел декодинг (парсинг) сырого события. Все значения полей JSON-файла были разложены по полям Wazuh, а на третьем третьем этапе распарcенное событие подошло под созданное нами правило 100001. 

Теперь события можно увидеть в веб-интерфейсе Wazuh. Для этого перейдем в раздел Explore → Discover и отфильтруем события по параметру rule.id:100001 за последние 60 минут:

Раскрыв событие, можно увидеть все переданные в сыром событии поля со значениями:

Таким образом, мы получили разложенные по полям (распарcенные) события в SIEM-системе Wazuh. Дальнейшим шагом будет подготовка правил корреляции для формирования инцидентов на основе полученных данных.

RuSIEM

Установка RuSIEM осуществляется путем выполнения команды:

wget https://files.rusiem.tech/nextcloud/s/j6wcHzzaqT8w5wc/download -О install.sh; bash

Далее в интерактивном меню нужно указать параметры будущей системы. Этот процесс подробно описан в документации вендора.

После установки будет доступен следующий веб-интерфейс:

RuSIEM по умолчанию получает syslog-события на порты 514/UDP, 514/TCP и 1514/TCP, 5013/UDP, 5014/UDP, 5014/TCP. 

Проверить это и при необходимости добавить/изменить эти порты можно, перейдя в веб-интерфейсе в раздел Настройки → Настройка микросервисов.

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

Запустим скрипт для выгрузки логов из панели my.selectel.ru в RuSIEM, указав следующие параметры в файле .env:

AUDIT_LOGS_URL=https://api.selectel.ru/audit-logs/v1/logs
USERNAME=<указываем учетную запись>
PASSWORD=<указываем пароль>
ACCOUNT_ID=<указываем id учетной записи>

SYSLOG_ENABLED=true
SYSLOG_HOST=<ip-адрес вашей SIEM-системы>
SYSLOG_PORT=<порт, на котором SIEM принимает syslog-события>

В веб-интерфейсе RuSIEM переходим в раздел События → Все события. Нажимаем кнопку Параметры на верхней панели интерфейса и включаем чекбокс Поиск по нераспарсенным событиям, после чего — Сохранить.

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

Отфильтруем события, указав номер аккаунта, из которого собираются аудит-логи, и увидим все пришедшие в SIEM события:

Как видим, событие имеет тег unparsed — это системный тег RuSIEM для событий, которые не прошли процесс парсинга.

Отлично, на данном этапе мы получили аудит-логи из панели my.selectel.ru в SIEM-системы.  Для дальнейшей работы необходимо проанализировать список всевозможных событий, регистрируемых сервисом аудита, и на их основе описать различные инциденты ИБ. Эту работу мы проведем в следующей статье.