Стадия жизненного цикла модуля: Experimental
У модуля есть требования для установки

Нужен ли мне этот модуль?

Имеет смысл использовать его, если вы хотите:

  • Собирать события безопасности (audit, runtime, приложение) в едином каноническом формате.
  • Маршрутизировать события в Loki, Elasticsearch, Splunk и др. по источнику и Severity.
  • Дать другим командам описывать извлечение событий (Shipper), а сами владеть реестром (SecurityEventDefinition) и приёмниками.

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

Как включить доставку в Loki?

Доставка в loki расположенный в кластер включена по-умолчанию.

Для отправки во внешний loki требуется произвести следующие действия:

  1. Создайте ClusterSecurityEventDestination с spec.type: Loki и укажите эндпоинт, аутентификацию и TLS для Loki. Подробнее о конфигурации и примерах — в CR и Examples.
  2. Создайте ClusterSecurityEventConfig: в spec.destinations укажите этот приёмник и задайте разрешённые источники в spec.enabledSources или spec.enabledSourcesMasks.
  3. Убедитесь, что есть минимум один SecurityEventDefinition (контроллер создаст ClusterLogDestination для шлюза) и хотя бы один Shipper, производящий события из источников, разрешённых в ClusterSecurityEventConfig.

События не доходят до приёмника. Что проверить?

  • Список источников — в ClusterSecurityEventConfig источник должен быть указан в enabledSources или enabledSourcesMasks. Формат источника —
    • clusterSecurityEventShipper/<имя ClusterSecurityEventShipper>/<source> (например clusterSecurityEventShipper/kube-audit/kube-apiserver)
    • podSecurityEventShipper/<namespace>/<имя PodSecurityEventShipper>/<source> (например podSecurityEventShipper/my-ns/audit/my-component)
  • Маски — при использовании enabledSourcesMasks символ * сопоставляется с любой подстрокой, включая /. Нельзя задавать одновременно enabledSources и enabledSourcesMasks.
  • Severity — параметр defaultSeverityThreshold фильтрует по .event.severity; события ниже порога, заданного в ClusterSecurityEventConfig, не отправляются в соответствующие приёмники.
  • Реестр — при использовании SecurityEventDefinition события, пара которых (event.code, source.component) не найдена в реестре, отбрасываются на шлюзе. Убедитесь, что produces[].eventCode и source в Shipper совпадают с SecurityEventDefinition.

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

В чём разница между PodSecurityEventShipper и ClusterSecurityEventShipper?

  • PodSecurityEventShipper — оперирует объектами в рамках одного неймспейса. Читает логи подов в этом неймспейсе. Используйте для событий приложений или привязанных к неймспейсу.
  • ClusterSecurityEventShipper — cluster-scoped. Может читать логи подов в выбранных неймспейсах или файлы на узлах. Используйте сбора событий с однотипных подов расположенных в нескольких неймспейсах (например поды dex-authnticator) или сбора логов на узлах.

Оба производят события с полями eventCode и source; маршрутизация в ClusterSecurityEventConfig использует один и тот же формат источника с префиксом podSecurityEventShipper/... или clusterSecurityEventShipper/....

Как добавить новый тип события?

  1. Создайте или используйте существующий SecurityEventDefinition с нужными code, severity, category, source и fields (обязательные по необходимости).
  2. Создайте или обновите PodSecurityEventShipper или ClusterSecurityEventShipper с элементом spec, в котором produces[].eventCode совпадает с этим definition, а source — с source из definition. Настройте input, parser или parserRef, при необходимости produces[].transform и enrich.
  3. Убедитесь, что ClusterSecurityEventConfig разрешает этот источник (enabledSources или enabledSourcesMasks) и ссылается на приёмник, куда должны попадать события.

severity и category задаются только в SecurityEventDefinition, а не в Shipper.

Как отправлять события во внешнюю систему (OpenSearch, Elasticsearch, Splunk и др.)?

Модуль security-events-manager поддерживает отправку событий в несколько типов внешних систем хранения и аналитики: Loki, Elasticsearch, Kafka, Splunk (HEC), Vector, File и Console.

Рассмотрим подключение на примере сервиса OpenSearch.

OpenSearch обратно совместим с Elasticsearch API, поэтому для отправки событий используется тип назначения Elasticsearch и эндпоинты _bulk/_search.

Для настройки отправки данных требуется:

  1. настроить приёмник событий — ресурс ClusterSecurityEventDestination;
  2. настроить правила отправки — ресурс ClusterSecurityEventConfig;
  3. убедиться, что в кластере есть хотя бы один ClusterSecurityEventShipper или PodSecurityEventShipper, производящий события из разрешённых источников.

Настройка приёмника

Приёмник настраивается через ресурс ClusterSecurityEventDestination.

Для OpenSearch в поле endpoint указывается HTTPS-адрес API (через Ingress — https://opensearch-api.example.com, или внутренний — https://opensearch-cluster-master:9200). Стратегии авторизации — None, Bearer или Basic. Проверка сертификата сервера настраивается в блоке tls. Поле index задаёт имя индекса или шаблон индексации, например security-events-%Y.%m.%d для ежедневной ротации индекса.

Пример:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: opensearch-external
spec:
  type: Elasticsearch
  elasticsearch:
    endpoint: https://opensearch-api.example.com
    # Ежедневная ротация индекса. Уберите суффикс для единого индекса.
    index: security-events-%Y.%m.%d
    auth:
      # None | Bearer | Basic.
      strategy: Basic
      username: admin
      password: P@ssw0rd-CHANGE-ME
    tls:
      # Для публичного сертификата Let's Encrypt через Ingress.
      # Если у шлюза нет системного CA, проверку можно отключить.
      # Для production-окружения задайте ca (Base64 PEM) и включите проверку.
      verifyCertificate: false
      verifyHostname: false
      # ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...

Для production-окружения рекомендуется завести отдельного пользователя в OpenSearch с правами только на запись в целевой индекс.

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

Правила отправки настраиваются через ресурс ClusterSecurityEventConfig.

В поле destinations указывается имя приёмника, заданное в metadata.name ресурса ClusterSecurityEventDestination. В поле enabledSources (или enabledSourcesMasks) перечисляются источники, события из которых отправляются в приёмник. Поле defaultSeverityThreshold задаёт минимальный уровень серьёзности — события с уровнем ниже указанного отбрасываются.

Пример:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
  name: opensearch-routing
spec:
  # Low | Medium | High — отбрасывает события ниже порога.
  defaultSeverityThreshold: Low
  enabledSourcesMasks:
    - clusterSecurityEventShipper/* # Все кластерные источники.
    - podSecurityEventShipper/* # Все источники на уровне неймспейса.
  destinations:
    - opensearch-external # Имя ресурса ClusterSecurityEventDestination.

Можно создать несколько ресурсов ClusterSecurityEventDestination и указать их в destinations одного ClusterSecurityEventConfig — отобранные события будут отправлены во все приёмники одновременно. Для разбиения потока по уровню серьёзности используются несколько ресурсов ClusterSecurityEventConfig с разными значениями defaultSeverityThreshold и непересекающимися destinations или enabledSources.