Перейти к содержимому

Может ли журнал быть доказательством

«У нас хранятся логи» — после инцидента этого не хватит. Вопрос не в том, что они хранятся, а в том, сможете ли вы доказать, что их не меняли.

SIEM
/
2026-08-04
/
7 мин чтения

Почему простого хранения недостаточно

На расследовании к журналу приходят с двумя вопросами. Первый простой: эта запись настоящая, кто её сделал и когда? Второй куда сложнее: какая из записей была удалена?

Обычный файл или поисковый индекс на второй вопрос не отвечает. Удалённая строка не оставляет следа — у вас остаются только оставшиеся, и они выглядят целыми. Удаление одного документа из индекса Elasticsearch делается запросом `DELETE /index/_doc/id`, и индекс после этого выглядит совершенно здоровым. В ClickHouse мутация `ALTER TABLE ... DELETE` работает так же: таблица есть, а строки, которую кто-то не хотел показывать, в ней нет.

Для атакующего это и есть самый дешёвый путь. В среде Windows очистка журнала оставляет одно событие — 1102, «журнал аудита очищен», — и именно поэтому опытный атакующий не чистит журнал целиком: он забирает одну строку из одного индекса в SIEM, потому что там эквивалента 1102 не существует.

Поэтому ответ «логи хранятся» ничего не значит ни для аудитора, ни для суда. Хранение — утверждение о наличии; доказательство — утверждение о неизменности. Это два разных технических требования, и выполняются они разными механизмами.

Первое условие — не трогать исходную запись

Многие системы хранят журнал нормализованным и выбрасывают исходный текст. Для поиска это удобно: поля называются одинаково, дата приведена к ISO 8601, лишние символы убраны. Для доказательства это фатально — вы показываете уже не источник, а собственную интерпретацию.

Чтобы увидеть разницу, хватит одного примера. Пусть в поле `$request` у nginx лежит `GET /a?b=%2e%2e%2f HTTP/1.1`. Нормализатор декодирует и запишет `GET /a?b=../`. Теперь вы показываете атаку — но не то, что именно пришло от клиента. Юрист спросит про эту разницу первой, потому что декодирование само по себе решение, и оно может быть ошибочным.

Правильный подход — хранить оба. Нормализованный вид для поиска и корреляции, неизменённая исходная запись для предъявления. Они связаны между собой, но исходная запись не перезаписывается никогда.

У этого есть и вторая польза, и в повседневной работе она срабатывает чаще первой. Появилось новое правило разбора или нашлась ошибка в старом — оно применяется к сохранённому оригиналу заново. В системе, выбросившей исходный текст, ошибка остаётся навсегда: пересчитывать не из чего, и полугодовые данные приходится принимать как есть.

Схема 1Хеш каждого блока включает хеш предыдущего. Поэтому изменение одной записи во втором блоке делает несогласованными все блоки после него.

Второе условие — хеш-цепочка блоков

Для каждой записи считается контрольная сумма — на практике SHA-256, потому что он быстрый и к нему относятся серьёзно. Записи собираются в блоки, для блока выводится общий хеш, и хеш каждого блока включает хеш предыдущего.

Это обычная хеш-цепочка. Никакого блокчейна, никакой сети, никаких токенов. Ровно этот механизм работает в journald под настройкой `Seal=yes` и называется там Forward Secure Sealing; журналы прозрачности сертификатов используют ту же идею в виде дерева Меркла. То есть это не экзотика, а стандартная практика.

В результате изменение или удаление одной записи ломает хеш её блока, тот ломает хеш следующего — и так до конца цепочки. Чтобы спрятать одну строку, придётся пересчитать всю историю после неё.

Ценность цепочки именно в этом: она не делает изменение невозможным, она делает его заметным. Для доказательства нужно ровно это. Никто не может доказать, что файла никто не касался; доказуемо другое — что касание будет видно.

Почему журнал хешей должен лежать отдельно

Если хеш-цепочка лежит рядом с логами и под теми же правами, это не защита, а украшение. Человек с правами root на лог-сервере пересчитает оба, и ничего не будет заметно. Это не теоретическое возражение: лог-сервер часто и есть первая цель, потому что там всё собрано в одном месте.

Поэтому хеши блоков хранятся отдельно: в другой системе, под другой учётной записью, в режиме, где после записи изменить нельзя. На практике это S3 Object Lock в режиме compliance, полка с WORM-дисками или попросту машина в другой организации.

Кое-где хеши выгружают третьей стороне ежедневным отчётом — аудитору или нотариусу. Этого тоже достаточно, потому что важна не копия, а разделение контроля. Ещё вариант — служба меток времени по RFC 3161: она даёт подпись «этот хеш существовал в этот момент».

Практическая проверка простая, и она умещается в один вопрос: может ли полный администратор системы журналирования изменить журнал хешей? Если да, контроля целостности у вас нет — у вас есть документ о контроле целостности.

Третье условие — проверка по расписанию

Цепочка сама по себе ничего не обнаруживает. Она говорит только тогда, когда её проверяют. Непроверяемая цепочка — записанная, но ни разу не прочитанная гарантия.

Поэтому проверка должна идти фоном и по расписанию: один раз после закрытия блока и регулярно по всему периоду. Интервал важен, потому что нарушение может остаться незамеченным месяцами. Если ежедневная полная проверка на большом архиве слишком дорога, берут выборку — несколько сотен блоков в сутки плюс последняя неделя целиком.

Второе требование — отчёт о целостности за период: какие блоки проверены, какой разошёлся, когда. После инцидента аудитор попросит именно этот отчёт, а не файлы журналов. И выходить он должен за секунды: отчёт, который готовят вручную, не готовят никогда.

Что происходит при расхождении, тоже должно быть записано заранее. Во многих системах это пишет одну строку в лог и на том заканчивается. Правильный ответ — заводить инцидент: нарушение целостности само по себе событие, и оно должно попасть в очередь, которую смотрит человек.

Схема 2Ни хранение оригинала, ни хеш-цепочка по отдельности не дают доказательства. Оно появляется только когда есть и то, и другое.

Четвёртое условие — писать и тех, кто читал

Целостность относится не только к записи. Кто искал, какой запрос выполнил, что выгрузил, кто менял политику хранения — всё это должно попадать в отдельный аудиторский след.

Иначе вопрос смещается: журнал, возможно, и не менялся, но кто его смотрел и вынес наружу, остаётся неизвестным. Во внутренних расследованиях второй вопрос нередко важнее — особенно если в SIEM попадают клиентские данные, платёжные следы или переписка сотрудников.

Чаще всего забывают про изменение срока хранения. Снижение срока с 90 дней до 7 даёт тот же результат, что и удаление строк, но никакой операции «удаление» при этом не фиксируется: просто сработала политика retention. Поэтому изменение политики — тоже часть аудиторского следа, и оно должно требовать отдельного подтверждения.

С выгрузкой так же. Скачанный CSV — это выход данных из системы, и что с ними будет дальше, вы уже не контролируете. Как минимум нужно знать, кто, когда, сколько строк и по какому фильтру забрал.

Источник времени и порядок событий

Второе слабое место доказательства — время. Записи приходят с десятков серверов, и часы у каждого идут по-своему. Если вы не можете сказать, какое из двух событий произошло раньше, у вас есть набор событий, но нет цепочки.

Поэтому все источники привязываются к одному источнику NTP — на практике chrony или ntpd, и они тоже пишут своё состояние в лог. А в записи хранятся два времени: время источника и время приёма системой. Разница между ними сама по себе полезный сигнал: заметный сдвиг обычно означает сбитые часы или запись, добавленную задним числом.

Часовой пояс — отдельная ловушка. Если внутри записи не написано `+05:00`, вы только предполагаете, в каком поясе она сделана, — и при переезде серверов предположение ломается. Все записи хранятся в UTC, местное время применяется только при отображении.

Границы блоков тоже задаются по времени. Тогда фраза «записи с 14:05 до 14:10 не изменялись» становится проверяемым утверждением, а не просьбой поверить на слово.

Схема 3Цепочка сама ничего не находит. Её нужно проверять по расписанию — и после закрытия блока, и по всему периоду. Отчёт рождается именно на этом шаге.

Что спросить до покупки

При выборе системы или провайдера хватает четырёх вопросов. Хранится ли исходная запись вместе с нормализованной? Где лежит журнал хешей и кто может его изменить? По какому расписанию идёт проверка и можете ли вы показать отчёт? Фиксируются ли операции чтения и выгрузки?

Если ответы «да», следующий шаг — демонстрация. Выберите произвольный период и попросите отчёт о целостности за него. Второй запрос ещё полезнее: на тестовом стенде намеренно измените одну запись и засеките, за какое время система это покажет.

Ни одно из этих требований не дорогое и не экзотическое. Раздел 10 PCI DSS и контроль защиты журналов в ISO 27001 требуют ровно того же — просто другими словами.

Но ставить их нужно в начале проекта, потому что потом не добавить: для прошлогодних логов цепочку уже не посчитать. Хеш, посчитанный сегодня, защищает только то, что появилось после него.

Все материалы

Познакомимся?

Покажите домен — дадим первичный анализ вашего текущего внешнего состояния. На этом этапе ничего не меняется.

Начнём
Связаться
Связаться