Стадия жизненного цикла модуля: Experimental
У модуля есть требования для установки
Модуль security-events-manager выполняет сбор, обработку и отправку событий безопасности, извлекаемых из логов приложений и инфраструктурных компонентов.
Событие безопасности — это строго структурированная запись о значимом с точки зрения информационной безопасности (ИБ) действии или факте, например:
- неуспешная аутентификация (в любой сервис);
- подозрительный доступ к API;
- критичные изменения ресурсов.
Цель модуля — получить логовые записи, распознать в них события безопасности, привести события к единому формату и отправить через настроенные приёмники.
В основе функциональности модуля:
- концепция событий безопасности;
- механизм сбора логовых записей из разных сервисов с помощью вспомогательного модуля
log-shipper; - механизм обработки (парсинга) и извлечения событий безопасности;
- механизм преобразования в единый формат и обогащения дополнительными данными;
- механизм фильтрации и отправки событий безопасности.
Для преобразования логовой записи в событие безопасности, сохраняемое во внешнем источнике, данные проходят следующие этапы обработки:
flowchart LR
%% --- СТИЛИ УЗЛОВ (Черный текст + Четкие границы) ---
classDef step fill:#ffffff,stroke:#000000,color:#000000,stroke-width:2px;
classDef source fill:#f1f5f9,stroke:#000000,color:#000000,stroke-width:2px;
classDef storage fill:#ffffff,stroke:#000000,color:#000000,stroke-width:2px;
%% --- ПОТОК ---
A(["fa:fa-server Источник логов <br/>(сервис)"]):::source ==> LS
subgraph LS [<b><font color='black'>log-shipper</font></b>]
direction TB
ls1[Определение записей с потенциальными<br/>событиями безопасности]:::step --> ls2[Отправка в security-events-shipper]:::step
end
LS ==> SES
subgraph SES [<b><font color='black'>security-events-shipper</font></b>]
direction LR
subgraph P [<b><font color='black'>Обработка</font></b>]
direction TB
p1["Обработка логов (парсинг)"]:::step --> p2[Извлечение событий безопасности]:::step
end
P ==> E
subgraph E [<b><font color='black'>Преобразование</font></b>]
direction TB
e1[Приведение в единый формат]:::step --> e2[Обогащение данными]:::step
end
E ==> F
subgraph F [<b><font color='black'>Фильтрация</font></b>]
direction TB
f1[Фильтрация <br/> по source и severity]:::step --> f2[Отправка в приёмник]:::step
end
end
%% --- БЛОК 3: ХРАНИЛИЩА ---
SES ==> ST
subgraph ST [<b><font color='black'>Целевые хранилища</font></b>]
direction TB
S1[("fa:fa-chart-area Loki")]:::storage
S2[("fa:fa-search Elastic")]:::storage
S3[("fa:fa-bolt ClickHouse")]:::storage
S1 ~~~ S2 ~~~ S3
end
%% --- ЦВЕТОВАЯ ГРУППИРОВКА (СВЕТЛАЯ) ---
style LS fill:#e0e7ff,stroke:#1a237e,stroke-width:2px,color:#000000
style SES fill:#f5f3ff,stroke:#4a148c,stroke-width:2px,color:#000000
style ST fill:#f0fdfa,stroke:#004d40,stroke-dasharray: 5 5,stroke-width:2px,color:#000000
style P fill:none,stroke:#4a148c,stroke-dasharray: 3 3
style E fill:none,stroke:#4a148c,stroke-dasharray: 3 3
style F fill:none,stroke:#4a148c,stroke-dasharray: 3 3
%% --- ТЕМНЫЕ ЖЕСТКИЕ СТРЕЛКИ ---
linkStyle default stroke:#000000,stroke-width:2px;
linkStyle 0,2,4,6,8,9,10 stroke:#000000,stroke-width:3px;
Пример итогового события:
{
"id": "2f0de5c2-2e58-4d3f-b4fe-5ec6f1935b9f",
"timestamp": "2026-05-10T14:21:03Z",
"source": {
"component": "kube-apiserver"
},
"event": {
"code": "UNAUTHORIZED_ACCESS",
"category": "Rbac",
"severity": "High",
"outcome": "Failure"
},
"eventMetadata": {
"cluster": "prod-cluster",
"sourceIPs": [
"206.123.145.70"
]
},
"actor": {
"id": "system:serviceaccount:default:demo",
"type": "ServiceAccount"
},
"object": {
"id": "/api/v1/namespaces/default/secrets",
"type": "KubernetesResource"
}
}Контент события может отличаться в зависимости от источника, но структура должна быть однородной. Модель события описана в SecurityEvent.
Описание события для конкретного источника задаётся ресурсом SecurityEventDefinition.
В этом ресурсе определяются обязательные и дополнительные поля, а также категория и уровень критичности.
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: SecurityEventDefinition
metadata:
name: k8s-pod-created
spec:
code: K8S_POD_CREATED
category: Runtime
severity: Low
description: >
Kubernetes pod created
source: runtime-audit-engine
fields:
- name: event.code
required: true # Значение по умолчанию — true.
- name: source.component
required: true
- name: metadata.extra.ka_target_name
required: false
- name: metadata
required: falseАрхитектура решения
Модуль выполняет три этапа работы:
- Сбор:
- сбор логов из источников подов и файлов узлов;
- первичный отбор записей, потенциально содержащих события безопасности.
- Обработка и обогащение:
- парсинг и извлечение полезных полей;
- преобразование в единую модель и обогащение контекстом.
- Доставка:
- фильтрация по политике и отправка в настроенные приёмники.
На этапе доставки поддерживается отправка в несколько типов систем хранения и аналитики (например, Loki, Elasticsearch, Kafka, Splunk, Vector, File).
Этапы обработки
Сбор логов
Логи в модуль security-events-manager поступают с помощью вспомогательного модуля log-shipper.
Применяется двухуровневая схема:
- модуль
log-shipperвыполняет предварительный отбор логовых записей с помощью простых операций сравнения (In,NotIn,Regex,NotRegex,Exists,DoesNotExist) и передаёт их в шлюз; - модуль
security-events-manager(шлюз) выполняет распознавание полей (парсинг, сериализация), последующую обработку и отправку.
Поскольку парсинг логов является ресурсоёмкой операцией, он выполняется только для записей, заранее отобранных как потенциально содержащие события безопасности, а не для всех входящих логов. Поэтому на этапе первичного отбора не выполняется глубокая фильтрация по значениям полей, требующая полноценного парсинга содержимого.
Настройка сбора логов и нескольких следующих этапов выполняется через ресурсы PodSecurityEventShipper и ClusterSecurityEventShipper (в зависимости от типа источника).
Кластерным источником логов являются источники, не привязанные к конкретному неймспейсу, например файлы узла.
Поскольку эти ресурсы используются для настройки нескольких этапов обработки, в примерах ниже показаны только соответствующие фрагменты манифестов.
Пример (фрагмент манифеста):
apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
name: runtime-audit-engine
namespace: d8-runtime-audit-engine
spec:
# Настройка источников логов.
- source: runtime-audit-engine
input:
type: KubernetesPods
kubernetesPods:
labelSelector:
matchLabels:
app: runtime-audit-engine
...
# Отбор записей, потенциально содержащих событие безопасности.
produces:
- eventCode: K8S_POD_CREATED
# Пример лога: Informational K8s Pod Created (user=system:serviceaccount:kube-system:replicaset-controller pod=example-7d6894dbd9-92hgx ns=d8-system resource=pods ... .
extract:
field: message
operator: Regex
values:
- ".*K8s Pod Created.*"
- eventCode: K8S_POD_DELETED
# Пример лога: Informational K8s Pod Deleted (user=kubernetes-admin pod=example-7d6894dbd9-92hgx ns=d8-system resource=pods ... .
extract:
field: message
operator: Regex
values:
- ".*K8s Pod Deleted.*"
...apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventShipper
metadata:
name: kube-audit
spec:
# Настройка источников логов.
- source: kube-audit
input:
type: File
files:
- /var/log/kube-audit/audit.log
...
# Отбор записей, потенциально содержащих событие безопасности.
produces:
- eventCode: UNAUTHORIZED_ACCESS
# Пример лога: ... "message":"Unauthorized","reason":"Unauthorized","code":401 ... .
extract:
field: message
operator: Regex
values:
- ".*\"code\":401.*"
...В манифестах возможна настройка нескольких источников, поскольку поле spec имеет формат массива объектов.
Для каждого объекта настраиваются:
- имя источника логов — поле
source; - тип и параметры источника логов — поле
input; - правила первичного отбора записей — поле
produces.
Обработка (парсинг), извлечение событий безопасности
После поступления логов в шлюз модуль security-events-manager выполняет парсинг и извлечение событий безопасности.
Настройка распознавания логов выполняется через поля объектов PodSecurityEventShipper и ClusterSecurityEventShipper. За настройку отвечает поле parser.
В поле parser указывается, логи какого контейнера необходимо распознавать (поле name) и каким способом (вложенное поле parser).
Поддерживаются следующие типы парсеров:
JSON— парсинг логов в формате JSON;Regex— парсинг логов по регулярному выражению;Grok— парсинг логов по Grok-шаблонам.
Дополнительно можно указать необходимость сохранения исходной логовой записи (drop_raw).
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
name: runtime-audit-engine
namespace: d8-runtime-audit-engine
spec:
# Настройка источников логов.
- source: runtime-audit-engine
input:
type: KubernetesPods
kubernetesPods:
labelSelector:
matchLabels:
app: runtime-audit-engine
# Настройка парсинга логов.
parser:
- name: falco
parser:
type: JSON
drop_raw: false
...Если требуется сложный парсинг, можно вынести правила распознавания в отдельные ресурсы SecurityEventLoggingTransformationRules (SELTR) и ClusterSecurityEventLoggingTransformationRules (CSELTR).
В этих ресурсах аналогичным образом задаётся, как именно необходимо парсить логи.
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventLoggingTransformationRules
metadata:
name: auth-log
spec:
type: File
file:
paths:
- /var/log/auth.log
transform:
parser:
type: Grok
grok:
# Применяется первый успешно сработавший шаблон.
patterns:
# Недопустимый пользователь zju_yd с 206.123.145.70 порт 33124.
- '%{AUTHLOGTIMESTAMP:ts} %{HOSTNAME:host} %{WORD:program}\[%{INT:pid}\]: %{DATA:action} %{USER} from %{SRCIP} port %{INT:src_port}'
# Соединение закрыто недопустимым пользователем gb 206.123.145.57 порт 49356 [preauth].
- '%{AUTHLOGTIMESTAMP:ts} %{HOSTNAME:host} %{WORD:program}\[%{INT:pid}\]: %{DATA:action} %{USER} %{SRCIP} port %{INT:src_port} \[%{DATA:context}\]'
# Соединение закрыто аутентифицирующимся пользователем root 206.123.145.52 порт 60078 [preauth].
- '%{AUTHLOGTIMESTAMP:ts} %{HOSTNAME:host} %{WORD:program}\[%{INT:pid}\]: %{DATA:action} %{USER} %{SRCIP} port %{INT:src_port} \[%{DATA:context}\]'
# Запасной вариант: сохранить исходное сообщение sshd в `msg`.
- '%{AUTHLOGTIMESTAMP:ts} %{HOSTNAME:host} %{WORD:program}\[%{INT:pid}\]: %{GREEDYDATA:msg}'
customPatterns:
# Соответствует формату "Mar 6 01:08:21" (допускается двойной пробел перед однозначным днём).
- key: AUTHLOGTIMESTAMP
value: '[A-Z][a-z]{2}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}'
# Минимальный набор шаблонов (без зависимости от конкретного встроенного набора grok).
- key: HOSTNAME
value: '[0-9A-Za-z][0-9A-Za-z._-]+'
- key: WORD
value: '[A-Za-z0-9_]+'
- key: INT
value: '[0-9]+'
- key: IPV4
value: '(?:\d{1,3}\.){3}\d{1,3}'
- key: DATA
value: '.*?'
- key: GREEDYDATA
value: '.*'
- key: USER
value: '(?<user>.*?)'
- key: SRCIP
value: '(?<src_ip>(?:\d{1,3}\.){3}\d{1,3})'
fields:
- name: pid
type: Int
- name: src_port
type: IntПри использовании SELTR или CSELTR в ресурсах PodSecurityEventShipper и ClusterSecurityEventShipper необходимо указать в поле parserRef имя ресурса, из которого берутся настройки распознавания:
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventShipper
metadata:
name: auth-log
spec:
# Настройка источников логов.
- source: auth-log
input:
type: File
files:
- /var/log/auth.log
# Настройка парсинга логов.
parserRef: auth-log
...Преобразование и обогащение события безопасности
Поскольку событие безопасности имеет фиксированную структуру, распознанную логовую запись необходимо преобразовать в целевую модель события. Для этого используются два механизма:
- Преобразование полей (
transform) — перенос значений из полей лога в поля события безопасности; - Обогащение (
Enrich) — добавление новых полей в событие безопасности.
Оба механизма настраиваются одноимёнными полями в блоке produces ресурсов PodSecurityEventShipper и ClusterSecurityEventShipper.
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
name: user-authn
namespace: d8-user-authn
spec:
# Настройка источников логов.
- source: user-authn
input:
type: KubernetesPods
kubernetesPods:
labelSelector:
matchLabels:
app: dex
...
produces:
# Отбор записей, потенциально содержащих событие безопасности.
- eventCode: USER_LOGIN_SUCCESS
# Пример лога: {"time":"2026-02-16T08:24:16.296841124Z","level":"INFO","msg":"login successful","connector_id":"local","username":"testuser","preferred_username":"","email":"test.user@example.ru","groups":["admins"],"client_remote_addr":"109.191.184.154","request_id":"712c95ff-94c2-41af-ac60-766a78218ceb"}.
extract:
field: message
operator: Regex
values:
- ".*login successful.*"
# Настройка трансформации полей лога в поля событий безопасности.
transform:
# Субъект.
- key: actor.id
value: username
# Метаданные.
- key: metadata.actor.preferredUsername
value: preferred_username
- key: metadata.actor.email
value: email
- key: metadata.actor.groups
value: groups
# Обогащение полей дополнительными данными.
enrich:
- target: actor.type
source: Static
value: UserПомимо трансформации и обогащения конкретного события, возможно задать глобальные трансформации и обогащения.
Это полезно, когда записи одного сервиса однотипны и содержат общие поля для всех событий.
Глобальные правила настраиваются в поле producesDefaults, структура которого аналогична produces.
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
name: user-authn
namespace: d8-user-authn
spec:
# Настройка источников логов.
- source: user-authn
input:
type: KubernetesPods
kubernetesPods:
labelSelector:
matchLabels:
app: dex
...
# Настройка глобальных трансформаций и обогащений.
producesDefaults:
transform:
- key: timestamp
value: time
- key: metadata.actor.sourceIPs
value: client_remote_addr
enrich:
- target: actor.type
source: Static
value: User
...
produces:
# Отбор записей, потенциально содержащих событие безопасности.
- eventCode: USER_LOGIN_SUCCESS
extract:
field: message
operator: Regex
values:
- ".*login successful.*"
# Настройка трансформации полей лога в поля событий безопасности.
transform:
# Субъект.
- key: actor.id
value: username
# Метаданные.
- key: metadata.actor.preferredUsername
value: preferred_username
- key: metadata.actor.email
value: email
- key: metadata.actor.groups
value: groups
# Обогащение полей дополнительными данными.
enrich:
- target: actor.type
source: Static
value: User
...Для трансформации используется структура «ключ-значение», где ключ — целевое поле события безопасности, значение — поле исходного лога.
Обогащение использует расширяемую модель источников данных.
Каждый элемент обогащения содержит поля — target — целевое поле события, source — источник данных, value — значение из источника.
На текущий момент поддержан источник:
Static— статические данные (подстановка фиксированного значения).
enrich применяется после transform; при конфликте целевого поля значение из enrich перезаписывает результат transform.
Фильтрация и отправка событий безопасности
После формирования события безопасности необходимо определить, в какие приёмники его отправлять. Для этого требуется:
- настроить приёмники событий безопасности;
- настроить правила отправки событий в приёмники.
Настройка приёмника
Приёмники настраиваются через ресурс ClusterSecurityEventDestination.
В качестве приёмников используются типы, доступные в экосистеме log-shipper.
Для хранения событий безопасности внутри кластера предусмотрена автоматическая настройка приёмника Loki при включении соответствующей опции модуля.
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
name: cluster-loki
spec:
type: Loki
loki:
auth:
strategy: Bearer
token: <EXAMPLE>
endpoint: https://loki.d8-monitoring:3100
tls:
verifyCertificate: true
verifyHostname: true
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...Настройка правил отправки событий в приёмники
При настройке правил отправки необходимо определить:
- события из каких источников отправляются;
- минимальный уровень severity для отправки;
- целевые приёмники.
Для этого используется ресурс ClusterSecurityEventConfig.
В ресурсе указываются источники (в формате точных имён или масок), минимальный severity, и массив приёмников (ресурсы ClusterSecurityEventDestination), в каждый из которых отправляются отобранные события.
Пример:
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
name: default
spec:
defaultSeverityThreshold: Low
enabledSources:
- clusterSecurityEventShipper/kube-audit/kube-audit
- podSecurityEventShipper/d8-runtime-audit-engine/runtime-audit-engine/falco
- podSecurityEventShipper/d8-user-authn/user-authn/dex
# Либо указать маски.
# enabledSourcesMasks:
# - clusterSecurityEventShipper/kube-audit/*
# - podSecurityEventShipper/*
destinations:
- cluster-lokiСтандартные настройки модуля
Если настройки модуля явно не заданы, то в кластере размещаются следующие объекты:
-
ClusterSecurityEventConfig— отвечает за настройку отправки событий безопасности в приёмники. Стандартно используются следующие настройки:apiVersion: security.deckhouse.io/v1alpha1 kind: ClusterSecurityEventConfig metadata: name: default spec: defaultSeverityThreshold: Medium destinations: - cluster-loki enabledSourcesMasks: - podSecurityEventShipper/* - clusterSecurityEventShipper/*На конфигурирование этих параметров отвечает настройка модуля
securityEventConfig. -
ClusterSecurityEventDestination— отвечает за настройку приёмника событий безопасности. Стандартно генерируется объект, с помощью которого возможно осуществить отправку событий безопасности в сервисloki, расположенный в кластере. Генерируется следующий объект:apiVersion: security.deckhouse.io/v1alpha1 kind: ClusterSecurityEventDestination metadata: name: cluster-loki spec: type: Loki loki: auth: strategy: Bearer token: <token> # Заполняется автоматически. endpoint: https://loki.d8-monitoring:3100Отключить генерацию стандартного CSED можно отдельным параметром
clusterSecurityEventDestination.clusterLoki.