WORM (Write Once Read Many) — журнал що не модифікується. Формати, ротація, аналіз.
WORM-журнал — це не «лог-файл з правильно налаштованими правами». WORM — це архітектурна гарантія: запис, що потрапив у журнал, не може бути ні змінений, ні видалений будь-якою особою системи, включно з адміністратором з root-доступом. Для систем з обмеженою інформацією — це не опція, а обов’язок за НД ТЗІ 2.5-004-99 (вимога Б.2).
WORM (Write Once Read Many) — модель зберігання, у якій дані можна записати, після чого їх можна тільки читати. Модифікація або видалення — заблоковані на рівні самого сховища, не на рівні застосування.
Технічні реалізації:
UBD використовує комбінацію останніх двох: журнал зберігається у таблиці БД з ланцюжком SHA-256, де кожен запис містить хеш попереднього. Спроба змінити запис у середині — виявляється при перевірці цілісності.
Норматив НД ТЗІ 2.5-004-99 Б.2 і NIST 800-53 AU-9 вимагають:
Додатково NIST 800-53 AU-11 — збереження аудиту достатньо довго для retroactive investigation, типово не менше 1 року для security events.
Базові параметри:
prev_hash у кожному записі = SHA-256 попереднього.Кожен запис журналу містить мінімум:
| Поле | Тип | Опис |
|---|---|---|
| id | bigint | Унікальний послідовний ідентифікатор |
| timestamp | timestamp(6) | Час події з мікросекундною точністю, UTC |
| user_id | bigint | Користувач, що ініціював дію |
| session_id | uuid | Ідентифікатор сесії (для кореляції) |
| action | string | Категорія: LOGIN, READ, WRITE, DELETE, ADMIN, EXPORT |
| resource | string | Об’єкт дії: тип + ID |
| result | enum | SUCCESS, DENIED, ERROR |
| details | jsonb | Контекстуальні дані (старе/нове значення для WRITE) |
| client_ip | inet | IP-адреса клієнта |
| prev_hash | bytea(32) | SHA-256 попереднього запису |
| signature | bytea | Підпис цього запису ключем платформи |
WORM-журнал росте постійно. Без ротації — таблиця розпухає, запити сповільнюються, бекап стає неможливим.
Кожен місяць (або тиждень для активних систем) — новий розділ таблиці. Старі розділи переводяться у read-only стан. Партиціонування БД (PARTITION BY RANGE timestamp) — стандартний підхід.
При досягненні певного розміру (наприклад, 100 GB) — новий розділ. Менш передбачувано, але стабільніше навантаження.
Розділи, старіші за 6-12 місяців, переносяться у архівне сховище. Архів містить:
Архівні розділи можна стискати — gzip, zstd дають коефіцієнт 5-10× на структурованих JSON-даних. Стиснення не порушує WORM-властивість: компресія перевіряється через контрольну суму архіву, перевірка чесна (нестиснений хеш записаний у метаданих).
Журнал треба не тільки писати, а й використовувати. Типові запити:
SELECT timestamp, user_id, action, result, details
FROM audit_log
WHERE resource = 'document:12345'
ORDER BY timestamp;
SELECT timestamp, action, resource, result
FROM audit_log
WHERE user_id = 7890
AND timestamp BETWEEN '2026-05-10' AND '2026-05-11'
ORDER BY timestamp;
SELECT user_id, client_ip, COUNT(*) as attempts
FROM audit_log
WHERE action = 'LOGIN'
AND result = 'DENIED'
AND timestamp > NOW() - INTERVAL '1 hour'
GROUP BY user_id, client_ip
HAVING COUNT(*) >= 5;
Активний моніторинг журналу — частина SOC-функцій. Типові правила:
WORM-журнал може використовуватися як доказ у судових експертизах за умови:
При судовій експертизі експерт перевіряє цілісність ланцюжка хешів. Якщо хоча б один запис змінено — це виявляється і знецінює журнал як доказ. Тому збереження chain integrity — це не лише регуляторна вимога, а й юридична.
UBD має вбудований WORM-журнал як частину сертифікованих функцій безпеки у експертному висновку Г-3. Реалізація включає chain integrity на SHA-256, підпис записів ключем платформи, окремий tablespace з мінімальними правами, інтерфейс адміністратора для перевірки цілісності одним кліком. Не потрібно зовнішнє hardware WORM-сховище для більшості сценаріїв.