Архитектура Шины Событий
Шина Событий — центральная нервная система Sentinel AI SOC: 10-шаговый pipeline, обрабатывающий каждое ИБ-событие от приёма до реагирования.
Философия проектирования
Почему HTTP/2 JSON, а не gRPC?
Sentinel использует HTTP/2 JSON для всего межкомпонентного взаимодействия. Это осознанное архитектурное решение:
| Фактор | gRPC | HTTP/2 JSON |
|---|---|---|
| Зависимость от CGO | ❌ Требует CGO для protobuf | ✅ Zero CGO (чистый Go) |
| Деплоймент | Сложный (proto gen, shared types) | Простой (стандартный HTTP-клиент) |
| Отладка | Непрозрачные бинарные фреймы | Читаемый JSON |
| Пропускная способность | ~550 событий/сек | ~520 событий/сек |
| Задержка (p50) | 0.8мс | 1.1мс |
| Размер бинарника | +12MB (grpc-go + protobuf) | 0 дополнительно |
Валидация Red Team: В ходе боевых red team учений разница в ~5% пропускной способности оказалась несущественной для SOC-нагрузок (цель: ≥500 событий/сек). Инвариант Zero CGO устраняет целые классы проблем сборки и деплоя.
Архитектура Pipeline
┌─────────────┐
│ Сенсор │ (sentinel-core, Shield, immune, custom)
└──────┬──────┘
│ HTTP POST /api/v1/soc/events
▼
┌──────────────────────────────────────────────────────┐
│ ШИНА СОБЫТИЙ │
│ │
│ Шаг 0: Секретный Сканер (ИНВАРИАНТ — нельзя откл.) │
│ ↓ │
│ Шаг 1: Аутентификация сенсора (PSK / mTLS) │
│ ↓ │
│ Шаг 2: Rate Limiter (≤100/сек на сенсор) │
│ ↓ │
│ Шаг 3: Дедупликация (скользящее окно 10с) │
│ ↓ │
│ Шаг 4: Валидация схемы (AlertEvent JSON Schema) │
│ ↓ │
│ Шаг 5: Decision Logger (SHA-256 хэш-цепочка) │
│ ↓ │
│ Шаг 6: Персистентность (SQLite WAL) │
│ ↓ │
│ Шаг 7: Движок корреляции (15 правил) │
│ ↓ │
│ Шаг 8: Триггер Playbook (авто-ответ ≤ MEDIUM) │
│ ↓ │
│ Шаг 9: Webhook / SSE Push (дашборд + внешние) │
│ │
└──────────────────────────────────────────────────────┘
Детали шагов
Шаг 0: Секретный Сканер
Тип: ИНВАРИАНТ — не может быть отключён никакой конфигурацией.
Сканирует каждый входящий payload на предмет утёкших секретов:
| Паттерн | Примеры |
|---|---|
| API-ключи | sk-..., AKIA..., gsk_... |
| Токены | ghp_..., xoxb-..., Bearer ... |
| Учётные данные | Пароли, строки подключения |
| Приватные ключи | -----BEGIN RSA PRIVATE KEY----- |
При обнаружении секрета событие:
- Редактируется — секрет заменяется на
[REDACTED:key_type] - Помечается — добавляются метаданные
secret_detected: true - Пересылается — обработка продолжается с очищенным payload
// pipeline.go — Секретный Сканер всегда первый
func (p *Pipeline) Process(event *AlertEvent) error {
// Шаг 0: Secret Scanner (ИНВАРИАНТ — никогда не пропускать)
event.Payload = p.secretScanner.Scan(event.Payload)
// Все последующие шаги...
}
Шаг 1: Аутентификация сенсора
Каждый сенсор должен аутентифицироваться перед приёмом событий:
| Метод | Конфигурация | Применение |
|---|---|---|
| PSK | Pre-shared key в заголовке | Простые разворачивания |
| mTLS | Клиентский сертификат | Production-среды |
| Без | Отключён | Только для разработки |
# spectorn.yaml
sensors:
- type: sentinel-core
auth:
type: "psk"
key: "${SENSOR_CORE_PSK}"
Шаг 2: Rate Limiter
Алгоритм Token Bucket для каждого sensor_id:
- По умолчанию: 100 событий/сек на сенсор
- Burst: 150 событий (1.5x bucket)
- Переполнение: События в очередь, затем сброс с предупреждением
Сенсор → [Token Bucket: 100/сек] → Принять или Очередь
При превышении лимита:
- SOC генерирует алерт
rate_limit_exceeded - События ставятся в очередь (до ёмкости буфера)
- При переполнении очереди — сброс с инкрементом метрики
dropped_events
Шаг 3: Дедупликация
Дедупликация по скользящему окну с использованием отпечатков:
Fingerprint = SHA256(source + category + description + severity)
| Настройка | По умолчанию | Описание |
|---|---|---|
dedup_window | 10с | Окно обнаружения дубликатов |
| Алгоритм | SHA-256 fingerprint | Точное совпадение |
Дубликаты отбрасываются тихо. Метрика dedup_count отслеживает отфильтрованные.
Шаг 4: Валидация схемы
Каждое событие должно соответствовать схеме AlertEvent:
{
"source": "sentinel-core", // Обязательно: идентификатор сенсора
"severity": "HIGH", // Обязательно: INFO|LOW|MEDIUM|HIGH|CRITICAL
"category": "jailbreak", // Обязательно: категория атаки
"description": "...", // Обязательно: описание
"confidence": 0.95, // Опционально: 0.0-1.0
"payload": {}, // Опционально: доп. данные
"timestamp": "2026-03-13T..." // Авто-заполнение если не указан
}
Невалидные события отклоняются с HTTP 400 и логируются.
Шаг 5: Decision Logger
Неизменяемый аудиторский след на основе SHA-256 хэш-цепочек:
Запись N:
event_id: EVT-1710295200-042
action: "accepted"
timestamp: 2026-03-13T01:00:00Z
prev_hash: "a3b8c1d2e5f6..."
hash: SHA256(entry_data + prev_hash) = "7f8e9d0c..."
Каждая запись криптографически связана с предыдущей. Любая модификация разрывает цепочку и обнаруживается через gomcp doctor.
Хранение: Append-only JSONL файл с флагом O_APPEND (атомарность на уровне ядра).
Опционально: TPM 2.0 sealing для аппаратной привязки целостности (SEC-006).
Шаг 6: Персистентность
События сохраняются в SQLite в режиме WAL (Write-Ahead Logging):
| Настройка | Значение |
|---|---|
| Движок | SQLite 3.40+ |
| Режим | WAL (параллельное чтение) |
| Журнал | WAL |
| Synchronous | NORMAL |
| Макс. размер БД | Настраиваемый (по умолчанию: 10GB) |
Шаг 7: Корреляция
События сверяются с 15 правилами корреляции. Подробности — Движок Корреляции.
Шаг 8: Триггер Playbook
При совпадении правила корреляции и наличии настроенного playbook:
| Серьёзность | Действие |
|---|---|
| INFO / LOW | Авто-выполнение playbook (если настроен) |
| MEDIUM | Авто-выполнение playbook |
| HIGH | Требуется одобрение оператора (Zero-G) |
| CRITICAL | Требуется одобрение оператора (Zero-G) |
Шаг 9: Webhook / SSE Push
После обработки события и инциденты отправляются:
| Назначение | Протокол | Цель |
|---|---|---|
| Дашборд | SSE | Обновления UI в реальном времени |
| Webhooks | HTTP POST | Интеграция с внешними SIEM |
| Slack/Teams | Webhook | Уведомления оператору |
Кольцевой буфер
Шина событий использует lock-free кольцевой буфер для приёма:
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
↑ ↑
Указатель чтения Указатель записи
| Настройка | По умолчанию | Описание |
|---|---|---|
buffer_size | 10,000 | Ёмкость кольцевого буфера |
batch_size | 100 | Событий на пакет обработки |
flush_interval | 1с | Макс. ожидание перед сбросом пакета |
Метрики
Шина событий экспортирует метрики Prometheus:
| Метрика | Тип | Описание |
|---|---|---|
sentinel_events_total | counter | Всего получено событий |
sentinel_events_processed | counter | Успешно обработано |
sentinel_events_dropped | counter | Сброшено (rate limit / буфер полон) |
sentinel_events_deduplicated | counter | Отфильтровано дубликатов |
sentinel_pipeline_latency_ms | histogram | Сквозная задержка pipeline |
sentinel_secrets_detected | counter | Секретов найдено сканером |
sentinel_buffer_usage | gauge | Текущая загрузка буфера |
Обработка ошибок
| Ошибка | Поведение |
|---|---|
| Ошибка аутентификации | HTTP 401, логируется, метрика auth_failures |
| Превышен rate limit | HTTP 429, очередь, метрика rate_limited |
| Ошибка валидации схемы | HTTP 400, логируется, метрика validation_failures |
| Ошибка записи в БД | 3 попытки, затем очередь, генерация алерта |
| Ошибка корреляции | Событие сохранено, корреляция пропущена, алерт |
Дальнейшие шаги
- Движок Корреляции — Правила и кластеризация
- Схема AlertEvent — Полная JSON-схема
- Справочник метрик — Все метрики Prometheus