Skip to content

Глава 18. Наблюдаемость

«Нельзя защитить то, чего не видишь. Нельзя обнаружить атаку, если не знаешь, как выглядит норма.»

Первые пять частей книги выстраивали контроли: идентичность, устройства, сеть, приложения, данные. Но контроли без видимости — это замки без камер. CISA ZTMM v2 выделяет Visibility & Analytics как сквозную возможность, пронизывающую все пять столпов: без неё невозможно ни обнаружение аномалий, ни адаптация политик.


18.1 Зачем: видимость как фундамент Zero Trust

NIST SP 800-207 определяет Механизм политик как центральный компонент, принимающий решения на основе контекста. Откуда берётся этот контекст?

Последние два пункта — это наблюдаемость. Без неё Механизм политик принимает решения вслепую.

Три сигнала наблюдаемости:

СигналНазначениеПример
TracesПуть запроса через сервисыЗапрос от user → API → payment → DB
MetricsЧисловые измерения во времениLatency p99 = 200ms, error rate = 0.1%
LogsДискретные событияuser=alice action=READ resource=orders status=DENIED

В Zero Trust к каждому сигналу привязывается идентичность: кто (SPIFFE ID, user principal), откуда (устройство, сеть), что делал (действие, ресурс).


18.2 OpenTelemetry: единый стандарт телеметрии

OpenTelemetry (OTel) — проект CNCF, объединяющий сбор traces, metrics и logs через единый SDK и Collector. OTel стал де-факто стандартом для облачных приложений.

На момент написания OTel находится в статусе Incubating в CNCF (принят в мае 2019, incubating с августа 2021); процесс graduation в активной стадии.

Архитектура OTel Collector

  • Receivers — приём данных (OTLP, Prometheus, Jaeger, Fluent Forward)
  • Processors — обогащение, фильтрация, batch (k8sattributes, resource, batch)
  • Exporters — отправка в backends (OTLP/gRPC, Prometheus Remote Write, Loki)

Текущая версия: OTel Collector v0.145.0 / v1.51.0 (февраль 2026).

Источник: github.com/open-telemetry/opentelemetry-collector/releases

Идентичность в телеметрии

Ключевой паттерн Zero Trust: каждый span и лог должен содержать идентичность вызывающей стороны.

OTel Semantic Conventions определяют resource attributes для идентификации сервиса:

yaml
# Resource attributes (стандартные)
service.name: payment-service           # Логическое имя сервиса
service.namespace: production           # Пространство имён
service.instance.id: "i-0abc123def"     # Уникальный экземпляр

Для Zero Trust нужно добавить атрибуты идентичности (см. главу 7 про SPIFFE). Стандартных SPIFFE-атрибутов в OTel semantic conventions пока нет — используем custom resource attributes:

yaml
# Конфигурация OTel Collector: processors
processors:
  resource:
    attributes:
      - key: workload.identity
        value: "spiffe://cluster.local/ns/payments/sa/api"
        action: upsert
      - key: workload.trust_domain
        value: "cluster.local"
        action: upsert

  # Автоматическое обогащение из Kubernetes
  k8sattributes:
    extract:
      metadata:
        - k8s.namespace.name
        - k8s.pod.name
        - k8s.deployment.name
      labels:
        - tag_name: app.kubernetes.io/name
          key: app.kubernetes.io/name
    pod_association:
      - sources:
          - from: resource_attribute
            name: k8s.pod.ip

Для пропагации идентичности между сервисами используется W3C Baggage:

baggage: spiffe.id=spiffe%3A%2F%2Fcluster.local%2Fns%2Fpayments%2Fsa%2Fapi

В service mesh (Istio, Linkerd) идентичность автоматически доступна через mTLS-сертификаты — Envoy proxy может извлекать SPIFFE ID из peer certificate и добавлять в заголовки.


18.3 OCSF: стандарт схемы событий безопасности

Open Cybersecurity Schema Framework (OCSF) — открытый стандарт для нормализации событий безопасности. Создан AWS и Splunk в 2022 году, с ноября 2024 — проект Linux Foundation.

Текущая версия: OCSF v1.7.0. Участники: 145+ организаций (CrowdStrike, Okta, Palo Alto, Wiz, Zscaler).

8 категорий событий

#КатегорияПримеры классов событийZT-релевантность
1System ActivityProcess, File System, KernelEndpoint posture
2FindingsSecurity Finding, Vulnerability, ComplianceRisk assessment
3Identity & Access ManagementAuthentication, Authorize SessionIdentity pillar
4Network ActivityNetwork, HTTP, DNS, SSHNetwork pillar
5DiscoveryDevice Inventory, Config StateAsset inventory
6Application ActivityAPI Activity, DatastoreApplication pillar
7RemediationFile, Process, Network RemediationIncident response
8Unmanned SystemsDrone FlightsIoT/OT

Категории 2, 3 и 4 наиболее важны для Zero Trust: они стандартизируют события аутентификации, авторизации и сетевой активности между разными вендорами.

Источник: schema.ocsf.io, github.com/ocsf/ocsf-schema

Почему OCSF важен для Zero Trust

Без нормализации схемы каждый источник логов использует свой формат: Okta — один JSON, AWS CloudTrail — другой, CrowdStrike — третий. Корреляция между ними требует ручного маппинга. OCSF решает эту проблему:


18.4 Security Data Lake

Традиционный SIEM vs Data Lake

ХарактеристикаТрадиционный SIEMSecurity Data Lake
ХранениеПроприетарноеS3/GCS/ADLS (открытое)
ФорматВендор-специфичныйParquet + OCSF
Ретенция30-90 дней (дорого)Годы (дёшево)
ЗапросыВендорный языкSQL (Athena, BigQuery)
Стоимость$/ГБ (высокая)Разделение compute/storage

Современный паттерн: Security Data Lake + SIEM — долгосрочное хранение в озере данных, real-time корреляция в SIEM.

AWS Security Lake

Amazon Security Lake (GA с мая 2023) — S3-based data lake с автоматической нормализацией в OCSF.

Архитектура:

Стоимость:

ИсточникЦена за ГБ
CloudTrail Management Events$0.75
VPC Flow Logs, Route 53, Security Hub$0.25
Нормализация (OCSF + Parquet)$0.035
Сторонние данныеБесплатно (ingestion)
ХранениеСтандартные тарифы S3

Источник: aws.amazon.com/security-lake/pricing

Microsoft Sentinel

Microsoft Sentinel — cloud-native SIEM, интегрированный с экосистемой Microsoft Defender.

Ключевые особенности:

  • KQL (Kusto Query Language) — язык запросов для аналитики
  • ASIM (Advanced Security Information Model) — нормализация данных (аналог OCSF для экосистемы Microsoft)
  • Commitment tiers — от 100 ГБ до 50 000 ГБ/день с экономией до 52% vs pay-as-you-go
  • Бесплатные источники — Azure Activity, Office 365 Audit, Microsoft Defender alerts

Пример KQL-запроса для обнаружения аномальных аутентификаций:

kql
SigninLogs
| where TimeGenerated > ago(24h)
| where ResultType != "0"  // Failed logins
| summarize
    FailedAttempts = count(),
    DistinctIPs = dcount(IPAddress),
    IPList = make_set(IPAddress, 10)
  by UserPrincipalName
| where FailedAttempts > 10 and DistinctIPs > 3
| sort by FailedAttempts desc

Важно: с 31 марта 2027 года Sentinel будет доступен только через портал Microsoft Defender (Azure-портал deprecated).

Источник: learn.microsoft.com/azure/sentinel/billing

Google SecOps

Google Security Operations (переименован из Chronicle в апреле 2024) — SIEM с петабайтным хранилищем.

Особенности:

  • 12 месяцев горячего хранения по умолчанию
  • YARA-L 2.0 — язык детекции (meta, events, match, outcome, condition)
  • Mandiant Threat Intelligence — встроенная интеграция (M-Score для автоматического обогащения)

Пример правила YARA-L для обнаружения множественных неудачных входов:

rule multiple_failed_logins {
  meta:
    author = "security_team"
    severity = "Medium"

  events:
    $event.metadata.event_type = "USER_LOGIN"
    $event.security_result.action = "FAIL"
    $event.principal.user.userid = $user

  match:
    $user over 10m

  outcome:
    $failed_count = count($event)

  condition:
    #event >= 5
}

Источник: docs.google.com/chronicle/docs/detection/yara-l-2-0-syntax


18.5 eBPF: наблюдаемость на уровне ядра

eBPF позволяет собирать телеметрию без модификации приложений — на уровне ядра Linux. Три ключевых инструмента:

Cilium Hubble

Hubble — компонент наблюдаемости Cilium (см. главу 10):

  • L3/L4 и L7 видимость сетевых потоков
  • Verdict по каждому потоку: FORWARDED, DROPPED, AUDIT (с привязкой к политике)
  • Service dependency graph — автоматическая карта зависимостей
  • Identity-aware — каждый поток привязан к Cilium identity (security labels)
bash
# Наблюдение потоков с вердиктами
hubble observe --namespace production \
  --verdict DROPPED \
  --output json | jq '{
    src: .source.labels,
    dst: .destination.labels,
    verdict: .verdict,
    policy: .drop_reason_desc
  }'

Grafana Beyla

Beyla — eBPF-based auto-instrumentation от Grafana, переданная в проект OpenTelemetry:

  • RED-метрики (Rate, Errors, Duration) без изменения кода
  • Distributed traces — автоматическое создание span-ов
  • Языки: Go, C/C++, Rust, Python, Ruby, Java, Node.js, .NET
  • Протоколы: HTTP/S, gRPC

Beyla особенно полезна для legacy-приложений, где инструментация невозможна.


18.6 Лаборатория: OpenTelemetry + Grafana с identity correlation

Цель

Развернуть OTel Collector с Grafana LGTM stack и настроить корреляцию по идентичности рабочей нагрузки.

Предварительные требования

  • Docker и Docker Compose
  • curl, jq

Шаг 1: Docker Compose для LGTM + OTel

yaml
# docker-compose.yaml
services:
  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.145.0
    ports:
      - "4317:4317"   # OTLP gRPC
      - "4318:4318"   # OTLP HTTP
    volumes:
      - ./otel-config.yaml:/etc/otel/config.yaml
    command: ["--config=/etc/otel/config.yaml"]

  tempo:
    image: grafana/tempo:2.10.0
    ports:
      - "3200:3200"
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
    command: ["-config.file=/etc/tempo.yaml"]

  loki:
    image: grafana/loki:3.6.5
    ports:
      - "3100:3100"

  grafana:
    image: grafana/grafana:12.3.2
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
    volumes:
      - ./grafana-datasources.yaml:/etc/grafana/provisioning/datasources/ds.yaml

Шаг 2: Конфигурация OTel Collector

yaml
# otel-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 5s

  resource:
    attributes:
      # Добавляем ZT identity атрибуты
      - key: deployment.environment
        value: "lab"
        action: upsert

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

  loki:
    endpoint: http://loki:3100/loki/api/v1/push

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, resource]
      exporters: [otlp/tempo]
    logs:
      receivers: [otlp]
      processors: [batch, resource]
      exporters: [loki]

Шаг 3: Конфигурация Tempo

yaml
# tempo.yaml
server:
  http_listen_port: 3200

distributor:
  receivers:
    otlp:
      protocols:
        grpc:

storage:
  trace:
    backend: local
    local:
      path: /var/tempo/traces

metrics_generator:
  processor:
    service_graphs:
      dimensions:
        - workload.identity
    span_metrics:
      dimensions:
        - workload.identity
  storage:
    path: /var/tempo/metrics

Шаг 4: Datasources для Grafana

yaml
# grafana-datasources.yaml
apiVersion: 1
datasources:
  - name: Tempo
    type: tempo
    url: http://tempo:3200
    access: proxy
    isDefault: true
  - name: Loki
    type: loki
    url: http://loki:3100
    access: proxy

Шаг 5: Запуск и отправка тестовых данных

bash
# Запуск стека
docker compose up -d

# Отправка тестового trace с identity атрибутами
curl -X POST http://localhost:4318/v1/traces \
  -H "Content-Type: application/json" \
  -d '{
  "resourceSpans": [{
    "resource": {
      "attributes": [
        {"key": "service.name", "value": {"stringValue": "payment-api"}},
        {"key": "service.namespace", "value": {"stringValue": "production"}},
        {"key": "workload.identity", "value": {"stringValue": "spiffe://cluster.local/ns/payments/sa/api"}},
        {"key": "workload.trust_domain", "value": {"stringValue": "cluster.local"}}
      ]
    },
    "scopeSpans": [{
      "spans": [{
        "traceId": "5b8aa5a2d2c872e8321cf37308d69df2",
        "spanId": "051581bf3cb55c13",
        "name": "POST /api/v1/charge",
        "kind": 2,
        "startTimeUnixNano": "1707500000000000000",
        "endTimeUnixNano":   "1707500000150000000",
        "attributes": [
          {"key": "http.method", "value": {"stringValue": "POST"}},
          {"key": "http.status_code", "value": {"intValue": "200"}},
          {"key": "peer.identity", "value": {"stringValue": "spiffe://cluster.local/ns/frontend/sa/web"}}
        ]
      }]
    }]
  }]
}'

echo "Открой Grafana: http://localhost:3000"
echo "Explore → Tempo → Search → найди trace по service.name = payment-api"

Шаг 6: Запрос в Grafana по идентичности

В Grafana Explore выберите Tempo и используйте TraceQL:

{ resource.workload.identity = "spiffe://cluster.local/ns/payments/sa/api" }

Это найдёт все traces от конкретной рабочей нагрузки — ключевой паттерн Zero Trust observability.

Очистка

bash
docker compose down -v

18.7 Чек-лист

  • [ ] OpenTelemetry Collector развёрнут для сбора traces, metrics, logs
  • [ ] Identity атрибуты добавлены в resource attributes (service.name, workload.identity)
  • [ ] Security events нормализованы (OCSF для мультивендорного окружения)
  • [ ] Security Data Lake настроен (Security Lake / Sentinel / Google SecOps)
  • [ ] Ретенция соответствует требованиям комплаенса (PCI DSS: 1 год, SOX: 7 лет)
  • [ ] eBPF-наблюдаемость развёрнута для сетевых потоков (Hubble / Beyla)
  • [ ] Корреляция по идентичности настроена (traces ↔ logs ↔ identity)
  • [ ] Алерты на аномальное поведение (множественные отказы, необычные паттерны доступа)

18.8 Итоги

Наблюдаемость в Zero Trust — это не «ещё один SIEM». Это источник контекста для Механизм политик:

  1. Три сигнала + идентичность — traces, metrics, logs обогащённые SPIFFE ID и user principal дают полную картину
  2. OCSF стандартизирует события безопасности между вендорами — без нормализации корреляция невозможна
  3. Security Data Lake > традиционный SIEM — разделение compute/storage снижает стоимость и увеличивает ретенцию
  4. eBPF — наблюдаемость без доверия — не требует инструментации приложений, что идеально для Zero Trust (не доверяй приложению сообщать о себе правду)
  5. Корреляция по идентичности — ключевой паттерн: от «IP 10.0.1.5 отправил 100 запросов» к «workload spiffe://cluster.local/ns/payments/sa/api отправил 100 запросов к spiffe://cluster.local/ns/orders/sa/db»

В следующей главе мы рассмотрим политику как код — как описать, версионировать и автоматически применять политики Zero Trust.

Опубликовано под лицензией CC BY-SA 4.0