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

ClusterSecurityEventConfig с Loki (явный список источников)

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
  name: default
spec:
  defaultSeverityThreshold: High
  enabledSources:
    - clusterSecurityEventShipper/kube-audit/kube-apiserver
  destinations:
    - cluster-loki

ClusterSecurityEventConfig с масками

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
  name: default
spec:
  defaultSeverityThreshold: High
  enabledSourcesMasks:
    - clusterSecurityEventShipper/kube-audit/*
    - podSecurityEventShipper/*
  destinations:
    - cluster-loki

ClusterSecurityEventDestination (Loki)

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: cluster-loki
spec:
  type: Loki
  loki:
    endpoint: https://loki.d8-monitoring:3100
    auth:
      strategy: Bearer
      token: EXAMPLE
    tls:
      verifyCertificate: false
      verifyHostname: false

Учётные данные (token, password) также можно подключать из Secret через tokenSecretRef/passwordSecretRef вместо указания inline. Secret должен находиться в namespace d8-security-events-manager с ключом value в поле data и меткой security-events-manager.deckhouse.io/credential-secret: "true". Inline-поля учётных данных и их *SecretRef-аналоги взаимно исключают друг друга.

SecurityEventDefinition

apiVersion: security.deckhouse.io/v1alpha1
kind: SecurityEventDefinition
metadata:
  name: k8s-privilege-escalation
spec:
  code: K8S_PRIV_ESC
  category: Rbac
  severity: High
  description: "Попытка создать привилегированный под или повысить права"
  source: kube-apiserver
  fields:
    - name: metadata.extra.privileges
      required: true

PodSecurityEventShipper (KubernetesPods с inline parser)

apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
  name: my-audit
  namespace: my-namespace
spec:
  - source: my-audit-app
    input:
      type: KubernetesPods
      kubernetesPods:
        labelSelector:
          matchLabels:
            app: audit
    parser:
      - name: app
        parser:
          type: Regex
          regex:
            patterns:
              - '^(?P<level>\w+)\s+(?P<msg>.+)$'
        fields:
          - name: level
            type: String
    produces:
      - eventCode: K8S_PRIV_ESC
        extract:
          field: message
          operator: Regex
          values:
            - '.*'
        transform:
          - key: event.severity
            value: level

ClusterSecurityEventShipper (File с parserRef)

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventShipper
metadata:
  name: kube-audit
spec:
  - source: kube-apiserver
    input:
      type: File
      files:
        - /var/log/kube-apiserver/audit.log
    parserRef: audit-json
    produces:
      - eventCode: K8S_AUDIT_FAIL

С ClusterSecurityEventLoggingTransformationRules:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventLoggingTransformationRules
metadata:
  name: audit-json
spec:
  type: File
  file:
    paths:
      - /var/log/kube-apiserver/audit.log
    transform:
      parser:
        type: JSON
      fields:
        - name: stage
          type: String
        - name: responseStatus
          type: Int
      drop_raw: true

Несколько приёмников (Loki + Splunk)

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: cluster-loki
spec:
  type: Loki
  loki:
    endpoint: https://loki.example:3100
---
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: splunk-prod
spec:
  type: SplunkHEC
  splunkHEC:
    endpoint: https://splunk.example:8088
    token: YOUR_TOKEN
---
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
  name: default
spec:
  defaultSeverityThreshold: Medium
  enabledSourcesMasks:
    - "*"
  destinations:
    - cluster-loki
    - splunk-prod

SecurityEventLoggingTransformationRules (переиспользуемый парсер)

apiVersion: security.deckhouse.io/v1alpha1
kind: SecurityEventLoggingTransformationRules
metadata:
  name: falco
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: runtime-audit-engine
  containers:
    - name: falco
      parser:
        type: JSON
      fields:
        - name: priority
          type: String
        - name: output
          type: String
      drop_raw: true

Обогащение через плагин (k8s-pod-info)

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

apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
  name: app-audit
  namespace: my-namespace
spec:
  - source: my-audit-app
    input:
      type: KubernetesPods
      kubernetesPods:
        labelSelector:
          matchLabels:
            app: audit
    parser:
      - name: app
        parser:
          type: JSON
    producesDefaults:
      # k8s.pod.name / k8s.namespace.name заполняются input-ом KubernetesPods.
      enrich:
        - target: actor.id
          source: Plugin
          plugin: k8s-pod-info
          value: serviceAccountName
          args:
            - key: pod_name
              value: k8s.pod.name
            - key: namespace
              value: k8s.namespace.name
    produces:
      - eventCode: K8S_PRIV_ESC
        extract:
          field: message
          operator: Regex
          values:
            - '.*'

Режим поиска по container ID

Если в исходном событии есть только container runtime ID (характерно для syscall/falco событий), используйте плагин k8s-container-info, чтобы определить serviceAccountName, name или namespace за один поиск:

apiVersion: security.deckhouse.io/v1alpha1
kind: PodSecurityEventShipper
metadata:
  name: falco-audit
  namespace: kube-system
spec:
  - source: falco
    input:
      type: KubernetesPods
      kubernetesPods:
        labelSelector:
          matchLabels:
            app: falco
    parser:
      - name: falco
        parser:
          type: JSON
    producesDefaults:
      # container.id заполняется парсером из JSON-вывода falco.
      enrich:
        - target: actor.id
          source: Plugin
          plugin: k8s-container-info
          value: serviceAccountName
          args:
            - key: container_id
              value: container.id
    produces:
      - eventCode: K8S_PRIV_ESC
        extract:
          field: message
          operator: Regex
          values:
            - '.*'

Обогащение через плагин (k8s-nodeuser-info)

Shipper может определить имя статического пользователя (metadata.name объекта nodeusers.deckhouse.io) по системному UID, присутствующему в событии, используя enrich.source: Plugin с плагином k8s-nodeuser-info. Описание плагина (обязательные входные параметры, доступные выходные значения и шаблон элемента массива enrich) приведено в разделе Плагины обогащения.

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventShipper
metadata:
  name: falco-nodeuser-enrich
spec:
  - source: runtime-audit-engine
    input:
      type: KubernetesPods
      kubernetesPods:
        labelSelector:
          matchLabels:
            app: falco
    parser:
      - name: falco
        parser:
          type: JSON
    producesDefaults:
      # output_fields.user.uid заполняется парсером из JSON-вывода falco.
      enrich:
        - target: actor.name
          source: Plugin
          plugin: k8s-nodeuser-info
          value: username
          args:
            - key: uid
              value: output_fields.user.uid
    produces:
      - eventCode: K8S_SSH_LOGIN
        extract:
          field: message
          operator: Regex
          values:
            - '.*'

Обогащение через пользовательский External-плагин

Пользователи могут создавать External-ресурсы ClusterSecurityEventEnrichmentPlugin для регистрации собственных enrichment-эндпоинтов. Ниже приведён пример External-плагина, который определяет информацию о сотруднике по badge ID.

Сначала создайте ресурс CSEP:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventEnrichmentPlugin
metadata:
  name: employee-info
spec:
  type: External
  description: "Resolve employee info by badge ID"
  endpoint:
    url: http://employee-enricher.hr-namespace.svc:8080/lookup
  args:
    - name: badge_id
      required: true
      description: "Event field path containing the employee badge ID"
  returns:
    fields:
      - name: username
        type: String
        description: "Employee username"
      - name: department
        type: String
        description: "Employee department"

Затем ссылайтесь на него в enrich-правиле shipper-а:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventShipper
metadata:
  name: badge-enrich-example
spec:
  - source: runtime-audit-engine
    input:
      type: KubernetesPods
      kubernetesPods:
        labelSelector:
          matchLabels:
            app: falco
    parser:
      - name: falco
        parser:
          type: JSON
    producesDefaults:
      # output_fields.user.badge_id заполняется парсером.
      enrich:
        - target: actor.name
          source: Plugin
          plugin: employee-info
          value: username
          args:
            - key: badge_id
              value: output_fields.user.badge_id
    produces:
      - eventCode: K8S_BADGE_LOGIN
        extract:
          field: message
          operator: Regex
          values:
            - '.*'

Конфигурация буфера

Production-настройка: Disk + Block (по умолчанию)

Настройки буфера по умолчанию предназначены для production — дисковый буфер с поведением Block при переполнении гарантирует нулевые потери событий безопасности при временной недоступности назначений.

Конфигурация модуля (ModuleConfig):

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: security-events-manager
spec:
  version: 1
  settings:
    gateway:
      buffer:
        type: Disk
        whenFull: Block
        maxSize: 512Mi
        maxEvents: 500
      logShipperBuffer:
        type: Disk
        whenFull: Block
        maxSize: 257Mi    # на узел; должно быть > 256Mi — минимум дискового буфера log-shipper
        maxEvents: 500

Поконкретное переопределение в ClusterSecurityEventDestination (например, больший буфер для удалённого Elasticsearch):

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: remote-elasticsearch
spec:
  type: Elasticsearch
  elasticsearch:
    endpoint: https://es.example.com:9200
    index: security-events
    auth:
      strategy: Bearer
      tokenSecretRef:
        name: es-token
  buffer:
    type: Disk
    whenFull: Block
    maxSize: 1Gi    # больший буфер для ненадёжного удалённого назначения
    maxEvents: 500

Тестовая настройка: Memory + DropNewest

Для тестовых/dev-окружений, где потеря данных допустима и требуется максимальная скорость без обратного давления:

Конфигурация модуля:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: security-events-manager
spec:
  version: 1
  settings:
    gateway:
      buffer:
        type: Memory
        whenFull: DropNewest
        maxSize: 50Mi
        maxEvents: 500
      logShipperBuffer:
        type: Memory
        whenFull: DropNewest
        maxSize: 50Mi
        maxEvents: 500

Socket-приёмник (CEF over syslog в SIEM)

Отправка событий безопасности в формате CEF, обёрнутых в RFC5424 syslog, по TCP/TLS в SIEM-приёмник:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: siem-syslog
spec:
  type: Socket
  socket:
    address: "siem.example.com:6514"
    mode: TCP
    tls:
      verifyCertificate: true
    encoding:
      codec: CEF
      syslogWrapper: RFC5424
      cef:
        deviceVendor: MyCompany
        deviceProduct: k8s-security
---
apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
  name: default
spec:
  destinations:
    - siem-syslog
  enabledSourcesMasks:
    - "clusterSecurityEventShipper/*"
    - "podSecurityEventShipper/*"
  defaultSeverityThreshold: Low

Socket-приёмник (сырой JSON по UDP)

Отправка событий в JSON по UDP (без гарантии доставки, без TLS):

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: udp-collector
spec:
  type: Socket
  socket:
    address: "collector.example.com:514"
    mode: UDP

Socket-приёмник (Unix-сокет для сайдкара SIEM-агента)

Отправка событий в локальный Unix-сокет (например, для сайдкара SIEM-агента):

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: sidecar-siem
spec:
  type: Socket
  socket:
    address: "/var/run/siem.sock"
    mode: Unix

Поконкретное переопределение:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: test-loki
spec:
  type: Loki
  loki:
    endpoint: http://loki:3100
  buffer:
    type: Memory
    whenFull: DropNewest
    maxSize: 50Mi
    maxEvents: 500