Аудит и неизменяемые журналы
Аудит и неизменяемые журналы
1) Зачем это нужно
Цель аудита — зафиксировать «кто, что, где, когда и почему» с доказуемой целостностью, чтобы поддерживать безопасность, расследования, финансовую отчетность и соответствие требованиям.
Неизменяемый журнал — формат и хранилище, где события записываются только добавлением (append-only), а последующее изменение/удаление либо невозможно, либо обнаружимо криптографическими средствами и политиками хранения.
2) Модель угроз и цели контроля
Риски:- Умышленная правка/удаление событий инсайдером.
- Подмена времени/источника (replay/backdating).
- «Тихое» выключение логирования на узле.
- Потеря части журнала при авариях/миграциях.
- Избыточный сбор PII и разлад с приватностью.
1. Целостность: доказуемая защитой от модификаций/удалений.
2. Полнота: закрытие ключевых потоков (control plane, data plane, доступы, деньги).
3. Точность времени: воспроизводимое, синхронизированное время.
4. Доступность: чтение и поиск в пределах SLO.
5. Приватность: минимум PII, токенизация/шифрование, законность использования.
3) Таксономия и приоритеты событий
Разделите события на слои с приоритизацией ретенции и неизменяемости:- Control Plane: аутентификация/авторизация, изменения конфигураций, операции с ключами (KMS), управление секретами, изменение политик.
- Data Plane: доступ к объектам/записям/чекаутам/платежам; чтение/создание/удаление.
- Админ и DevOps: SSH/консоль, CI/CD, изменения инфраструктуры/IaC, эскалации прав.
- Продуктовые: транзакции, биллинг, операции клиентов.
- Системные/сетевые: ядро/агенты/прокси/балансеры, брокеры, БД.
- Безопасность: IDS/IPS/EDR, WAF, анти-DDoS, антифрод, DLP.
Для каждого класса фиксируем: критичность, схему, обязательные поля, срок хранения, требования к неизменяемости.
4) Обязательные поля и формат
Идентификаторы корреляции: `trace_id`, `span_id`, `request_id`, `actor_id` (пользователь/сервис), `tenant_id`, `resource_id`.
Контекст A&A: способ аутентификации, роли/политики на момент действия.
Время: RFC3339/UTC, миллисекунды/наносекунды; источник синхронизации.
Действие и результат: тип операции, цель, статус, количество затронутых объектов.
Целостность: локальный HMAC записи, порядковый номер (sequence), hash-prev.
Схема: JSON со стабильной моделью (например, совместимой с общими словарями событий).
Запрещено: секреты, ключи, токены, полные PAN, пароли, приватные ключи. PII — только по необходимости, с маскированием/токенизацией.
5) Время и синхронизация
Источник времени: как минимум два независимых источника (NTP/PTP) + мониторинг смещения.
Критичные подписи времени: используйте сервисы доверенной отметки времени (TSA) либо внутренний time-sealing сервис для пачек событий.
Правила: никаких локальных часовых поясов, только UTC; логировать и смещение/качество времени.
6) Архитектура потока логов
Агенты → Буфер → Транспорт → Лэндiнг → Хэш-цепь/подпись → Холод/Архив → Индекс для поиска.
Сбор на узле: легкие агенты (daemonset/sidecar) с буфером на диске (back-pressure).
Транспорт: защищенный канал (TLS/mTLS), гарантированная доставка (at-least-once), idempotent-ингест.
Лэндинг-зона: объектное хранилище в «сыром» виде (партиции по дате/тенанту/типу).
Индекс: движок поиска/аналитики для online-запросов (горячий слой).
Архив (WORM): неизменяемые бакеты/ленты с политиками ретенции и юридическими hold.
Anchor/Seal: периодическая «запайка» пачек хэш-цепей (см. ниже).
7) Криптографическая неизменяемость
7.1 Цепочки хешей (append-only)
Каждая запись содержит: `hash_curr = H(record)`, `hash_prev` из предыдущей записи, `seq`. Любая правка ломает цепь.
Псевдокод цепочки:
prev = GENESIS for record in stream:
payload = canonical_json(record_without_integrity_fields)
h = H(payload prev.hash record.seq)
store(record + {hash_prev: prev.hash, hash_curr: h})
prev = {hash: h}
7.2 Подпись пачек и штамп времени
Каждые N секунд/МБ формируем блок: корень Меркла всех `hash_curr`.
Подписываем блок ключом аудита (устойчиво хранимым в KMS/HSM).
Добавляем отметку времени TSA и публикуем «каталог блоков» (Transparency Log).
Опционально: периодически якорим хэш корня в внешнее доказуемое пространство (например, независимый журнал или публичное неизменяемое хранилище).
7.3 Управление ключами аудита
Ключи подписи — в KMS/HSM, ротация по графику, многофакторный доступ, dual-control для экспорта.
Отзыв ключа → новая ветка доверия; старые подписи остаются проверяемыми.
8) Политики хранения и WORM
WORM/immutability: включаем неизменяемые контейнеры/бакеты с политикой Retention и Legal Hold для классов P0/P1.
Версионирование: включено; удаление — только по процедурам с задержкой (запрет мгновенного purge).
Ретенция: горячий (7–30 дней), теплый (3–6 месяцев), холодный/архив (1–7 лет и более — в зависимости от регулятора/контракта).
Многоарендность: отдельные пространства имен/учетки/ключи шифрования на арендатора; отчетность по доступам к журналам.
9) Приватность и минимизация
Сбор по принципу необходимости: не логируем лишнее.
Токенизация/псевдонимизация чувствительных полей, хэш с солью для идентификаторов.
Шифрование полей на стороне продьюсера (AEAD) при хранении в общем объектном хранилище.
Право на удаление (где применимо): реализуется через крипто-стирание ключей полей/партиций, не нарушая неизменяемость контейнера (планируется при проектировании).
10) Доступ, роли и аудит самого аудита
Разделение: producers ≠ readers ≠ admins.
Только чтение из WORM; изменение политик ретенции — через обособленные роли и процедуру с одобрением.
Все операции чтения/экспорта журналируются во вторичный журнал (мета-аудит).
Экспорт для следствия/комплаенса — в зашифрованном виде с каталогом хэш-блоков и цепью доверия.
11) Наблюдаемость и SLO
Метрики: скорость инжеста, лаг до индекса, % утраченных/повторных, доля несинхронизированного времени, ошибки подписи/якорения, заполнение буферов.
SLO: ≥99.9% событий доставлены ≤ X сек до горячего индекса; 0 необъяснимых «дыр» в последовательностях; 100% блоков подписаны и промаркированы временем.
Алерты: пауза инжеста > N минут, рост invalid-hash, расхождение цепи, провал подписи/таймстампа, смещение времени за порог.
12) Тестирование и верификация
Red/Blue-тесты: попытка редактирования/удаления записи на разных стадиях; проверка детектирования.
Chaos: отключение агента на узле, разрыв сети, переполнение буфера, «подмена времени».
Крипто-проверки: регулярная валидация цепей, сверка корней Меркла и штампов.
Форензика: воспроизведение сценариев расследований из журналов end-to-end.
13) Эксплуатация и процедуры
Runbook «проверка целостности» (on-demand и по расписанию).
Процедура legal hold и временной «заморозки» партиций.
Процедура discovery и экспорта с сохранением цепи доверия.
План ротации ключей аудита и реакции на компрометацию (новая ветка доверия, пере-подпись блоков, уведомления).
14) Мини-рецепты
Подпись блока (мерклизация + TSA, схематично):
records = read_partition(ts_window)
leaves = [H(canonical_json(r)) for r in records]
root = merkle_root(leaves)
sig = KMS.sign(root ts_now)
tsa = TSA.timestamp(sig)
store_block({root, sig, tsa, count=len(leaves), window})
append_transparency_log(H(root sig tsa))
Проверка целостности цепочки (фрагмент):
for i in 1..N:
assert rec[i].hash_prev == rec[i-1].hash_curr assert rec[i].hash_curr == H(canonical_json(rec[i]_no_hash) rec[i].hash_prev rec[i].seq)
Политика ретенции (идея):
- Control/Data plane P0: горячий 30 дней → теплый 6 мес → архив 7 лет (WORM).
- DevOps: горячий 14 дней → теплый 3 мес → архив 1 год.
- Секурити-сигналы: горячий 90 дней (для расследований), потом 1–3 года.
15) Частые ошибки
«Логи — это текст без схемы». Без схемы нет детерминированной целостности и поиска; обязателен канонический JSON и фиксированные поля.
Нет корреляции. Отсутствие `trace_id` ломает расследования.
Локальное время. Только UTC и контроль смещения.
Запись в изменяемые тома. Без WORM любая неизменяемость — фикция.
Не логируют чтения. Чтение чувствительных данных важно фиксировать не меньше, чем запись.
Секреты в логах. Включайте санитайзеры до отправки, «красные списки» паттернов.
Один ключ на все. Ключи подписи и шифрования — раздельно, с ролью и ротацией.
16) Соответствие и регулирование
Требования к срокам хранения/неизменяемости зависят от домена (финансы, платежный, телеком и т. п.).
Доказываемость: наличие протоколов WORM/ретенции, отчетов валидации цепей, журналов доступа к журналам, процедур legal hold и экспорта.
17) Чек-листы
Перед продом
- Утверждена таксономия событий и схема (обязательные поля).
- Настроены агенты, буферы, защищенный транспорт, back-pressure.
- Включены: цепочки хешей, блоковая подпись, штамп времени, transparency-лог.
- Хранилище WORM/ретенции включено; тест на невозможность перезаписи/удаления.
- Маскирование/токенизация чувствительных полей.
- Синхронизация времени и мониторинг смещения.
- План ротации и хранение ключей аудита в KMS/HSM.
Эксплуатация
- Еженедельная валидация цепей и блоков (+ отчет).
- Алерты на разрыв цепи/ошибки подписи/смещение времени.
- Периодические Red-team тесты на подмену/удаление.
- Регулярный review ретенций и затрат.
18) FAQ
В: Достаточно ли просто «только-добавление» на уровне БД?
О: Нет. Нужны криптографические гарантии (цепочки хешей, подписи блоков, штампы времени) и политики WORM.
В: Как быть с правом на удаление данных?
О: Проектируйте крипто-стирание (удаление ключей) для полей/партиций, сохраняя неизменяемость носителя и доказуемость журналов.
В: Нужен ли отдельный ключ для подписи блоков?
О: Да. Ключи подписи блоков отделяйте от ключей шифрования хранения; храните в KMS/HSM, с ротацией и аудитом.
В: Можно ли «якорить» в публичное пространство?
О: Опционально. Это усиливает проверяемость и отсечет «переписывание истории» внутри контура.
Связанные материалы:
- «Шифрование At Rest»
- «Шифрование In Transit»
- «Менеджмент секретов»
- «Управление ключами и ротация»
- «Подпись и верификация запросов»