WORM-журнал — це не «лог-файл з правильно налаштованими правами». WORM — це архітектурна гарантія: запис, що потрапив у журнал, не може бути ні змінений, ні видалений будь-якою особою системи, включно з адміністратором з root-доступом. Для систем з обмеженою інформацією — це не опція, а обов'язок за НД ТЗІ 2.5-004-99 (вимога Б.2).
Що таке WORM
WORM (Write Once Read Many) — модель зберігання, у якій дані можна записати, після чого їх можна тільки читати. Модифікація або видалення — заблоковані на рівні самого сховища, не на рівні застосування.
Технічні реалізації:
- Hardware WORM: спеціалізовані пристрої (NetApp SnapLock, Dell EMC Centera). Найжорсткіша гарантія, але дорого.
- Software WORM на файловій системі: XFS з extended attributes, ZFS snapshots, immutable файли через chattr +i.
- Database WORM: CDC-таблиці без UPDATE/DELETE-привілеїв, з тригерами проти модифікації.
- Криптографічний WORM: ланцюжок хешів, де модифікація запису розриває ланцюжок і виявляється.
UBD використовує комбінацію останніх двох: журнал зберігається у таблиці БД з ланцюжком SHA-256, де кожен запис містить хеш попереднього. Спроба змінити запис у середині — виявляється при перевірці цілісності.
Вимоги до WORM журналів
Норматив НД ТЗІ 2.5-004-99 Б.2 і NIST 800-53 AU-9 вимагають:
- Захист записів від несанкціонованої модифікації.
- Захист записів від несанкціонованого видалення.
- Контроль доступу до журналу — окремі ролі для запису і читання.
- Резервне копіювання журналу.
- Зберігання згідно з регуляторним терміном (зазвичай 3-5 років, для деяких категорій — 10+).
Додатково NIST 800-53 AU-11 — збереження аудиту достатньо довго для retroactive investigation, типово не менше 1 року для security events.
Налаштування WORM на UBD
Базові параметри:
- Tablespace: окремий, з обмеженими правами доступу на рівні БД.
- Шифрування at-rest: tablespace зашифрований ДСТУ 7624 (Калина) або AES-256.
- Sign-on-write: кожен запис підписується ключем платформи у момент створення.
- Chain integrity: поле
prev_hashу кожному записі = SHA-256 попереднього. - Read-only views: застосунок працює з журналом через VIEW з тільки SELECT-привілеями.
Формати запису
Кожен запис журналу містить мінімум:
| Поле | Тип | Опис |
|---|---|---|
| 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 місяців, переносяться у архівне сховище. Архів містить:
- Експорт записів у структурованому форматі (Parquet, ORC).
- Файл з контрольною сумою всього розділу.
- Файл з підписом контрольної суми ключем платформи.
- Метаінформація: період, кількість записів, мінімальний/максимальний ID.
Стиснення
Архівні розділи можна стискати — 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-функцій. Типові правила:
- >5 невдалих входів від одного користувача за 5 хвилин → alert.
- Доступ до записів з грифом «обмежений» поза робочим часом → alert.
- Експорт >1000 записів за один запит → alert.
- Зміна ролей користувача (privilege escalation) → alert.
- Видалення WORM-bypass спроба (виявляється через chain integrity) → critical alert.
Юридичне значення
WORM-журнал може використовуватися як доказ у судових експертизах за умови:
- Документально підтверджена система захисту журналу від модифікації.
- Підпис записів кваліфікованим електронним ключем (не звичайним hash, а підпис ДСТУ 4145).
- Експертний висновок щодо засобу журналювання.
- Архівні копії з підписами на момент архівування.
- Документований ланцюжок зберігання (chain of custody).
При судовій експертизі експерт перевіряє цілісність ланцюжка хешів. Якщо хоча б один запис змінено — це виявляється і знецінює журнал як доказ. Тому збереження chain integrity — це не лише регуляторна вимога, а й юридична.
UBD має вбудований WORM-журнал як частину сертифікованих функцій безпеки у експертному висновку Г-3. Реалізація включає chain integrity на SHA-256, підпис записів ключем платформи, окремий tablespace з мінімальними правами, інтерфейс адміністратора для перевірки цілісності одним кліком. Не потрібно зовнішнє hardware WORM-сховище для більшості сценаріїв.
UnityBaseDefense — технічна довідка →