Esper на службі кореляції

Продукти класу SIEM відрізняються від звичайних Log-серверів як мінімум наявністю кореляційного движка, здатного перетворити величезний потік подій в набір алертів. У даній статті ми розглянемо деякі можливості бібліотеки Esper, що дозволяє реалізувати свій кореляційний движок, який не поступається за можливостями підсистеми кореляції промисловим SIEM-рішень, а в чомусь навіть перевершує їх.

Esper, принцип роботи

Esper на службі кореляції
Web GUI Esper Enterprise Edition

Для виконання кореляції в своєму додатку необхідно описати типи подій, їх поля і правила обробки, всю іншу роботу Esper візьме на себе. Правила обробки подій (statements) описуються за допомогою мови EPL (Event Processing Language), який дуже схожий на SQL, однак сама логіка роботи Esper принципово відрізняється від СУБД. Замість того щоб зберігати події і періодично виконувати запити, Esper зберігає правила (запити) і пропускає крізь них потік подій, немов через решето (або набір решіт). Як тільки умови правил виконуються, бібліотека миттєво віддає результат з додатком.

Правила описуються за допомогою двох основних способів:

  • event patterns - шаблони подій, які дозволяють виявляти наявність або відсутність послідовностей або комбінацій подій в потоці або наборах потоків;
  • event stream queries - запити, через які пропускається потік подій, що залишають тільки необхідні за заданими правилами.

Як вже було сказано, Esper працює з безперервними потоками подій різних типів, наприклад від брандмауера, антивіруса, контролера домену. Esper дозволяє крутити ці потоки і події в них, як тільки захочеться: об'єднувати, групувати, фільтрувати, дедупліціровать, сортувати, проганяти через різні типи вікон (тимчасові, статистичні) - в загальному, зробити все, щоб знайти ворога, виявити аномалію або зірвати куш на біржі. Так-так, Esper використовується навіть для трейдингу!

кореляційні правила

Esper на службі кореляції
Один із способів опису типу подій

Так, до речі, тут немає помилки: Esper, на відміну від SQL, допускає застосування конструкції where в запитах, що містять агрегатні функції. Незважаючи на те що правило буде працювати, більш оптимальним був би запит із застосуванням фільтра потоків:

Фільтр потоку відсіває події ще до потрапляння їх у вікно, в той час як фільтр where застосовується для всіх подій, що знаходяться у вікні, після чого вважаються агрегатні функції, значення яких фільтруються конструкцією having. Чим менше подій у вікні, тим менше ресурсів ми споживаємо.

У разі якщо в нашу мережу проник зловредів, який почне активно переглядати мережу, правила, створені вище, згенерують багато подій, які завалять поштовий сервер повідомленнями, тому додамо конструкцію, що залишає висновок тільки першої події протягом години для кожного джерела, на якому спрацював запит :

Esper на службі кореляції

Дуже часто не тільки наявність певних подій, а й їх відсутність протягом певного часу вимагає уваги, оскільки це може свідчити про вихід з ладу обладнання, помилку конфігурації або атаці. Щоб не проклацувати момент, коли з брандмауера перестануть приходити логи, створимо ще одне правило з використанням шаблону:

Після кожної події з потоку firewall Esper буде запускати п'ятихвилинний таймер. Якщо протягом цього часу не прийде ще одна подія, додаток буде про це повідомлено.

Машина часу

  1. Відправкою в Esper спеціального повідомлення типу CurrentTimeEvent, в яке поміщається значення часу з балки, зрушує внутрішній таймер. Далі засилаємо саму запис з журналу, яка проходить через запит, який використовує звичайне тимчасове вікно win: time (період).
  2. Відправкою в Esper повідомлення з логу з полем, що містить час з журналу в форматі unixtime (значення повинно бути типу Long). Далі ці повідомлення прогоняются через запит з тимчасовим вікном win: ext_timed (время_із_лога, період), яке використовує зовнішнє час для своєї роботи.

Відкриваємо вікна навстіж

У прикладах правил, які ми вже розглянули, використовувалося ковзне тимчасове вікно time. Крім цього вікна, Esper підтримує ряд інших цікавих вікон. Ось лише деякі з них:

  • win: length - накопичує заданий число подій;
  • win: time_batch - накопичує події протягом заданого інтервалу, після чого віддає їх для обробки;
  • win: time_accum - ковзне вікно, яке накопичує події до тих пір, поки протягом заданого часу не зробить жодного події;
  • win: keepall - зберігає всі події, що потрапили у вікно;
  • std: unique - додає в вікно тільки остання подія для унікального значення поля / полів або функції від цих значень, тобто якщо в параметрах вікна ми задаємо, що перевіряти унікальність слід по полю src_ip, то в підсумку в вікні будуть міститися останні події для кожного src_ip;
  • std: groupwin - групує події по полях або значенням функцій від цих полів;
  • stat: uni - розраховує різні статистичні показники для подій, що містяться у вікні: загальну суму, середнє, стандартне відхилення, дисперсію;
  • stat: correl - розраховує коефіцієнт кореляції між двома параметрами всередині потоку;
  • ext: time_order - впорядковує події за часом, навіть якщо старе подія прийшло пізніше, ніж нове.

Вікна можна комбінувати один з одним, при цьому події з одного вікна перетечуть в інше. Наприклад, якщо файрвол передає інформацію про кількість байтів, то порахувати загальний обсяг переданих даний, середній обсяг сесії протягом однієї години і вивести топ-10 можна було б за допомогою наступної ланцюжка вікон:

Ще одна цікава концепція, яка підтримується Esper, - іменовані вікна (Named Windows). Іменовані вікна є глобальними і можуть використовуватися декількома правилами одночасно. Для прикладу додамо до нашого тестового контуру контролер домену, з якого ми отримуємо події про аутентифікації користувачів з полями login і src_ip. Ми хочемо швидко обчислити логін шкідника, скануючого нашу мережу, і не витрачати час на пошук цієї інформації в логах з контролера. Так як в мережі використовується DHCP, ми хочемо, щоб в зв'язці login - src_ip містилися тільки актуальні дані. Зв'язка login - src_ip може бути корисна для правил, що використовують різні потоки подій (міжмережевий екран, IDS, проксі-сервер), тому створимо іменоване вікно, яке буде зберігати цю зв'язку без обмеження за часом:

Тепер все готово, щоб до кожної події сканування з раніше створеного потоку scanning_hosts прикрутити пов'язаний логін користувача:

Підключаємо зовнішні джерела

Esper не обмежується підтримкою стандартних СУБД, а дозволяє використовувати абсолютно будь-які джерела. Для цього необхідно реалізувати клас зі статичним методом, що повертає Java-клас, java.util.Map або масив об'єктів Object []. Завдяки такій гнучкості можна підтягувати дані звідки завгодно: з Redis, файлів, веб-ресурсів - загалом, використовувати будь-які джерела, з якими можна працювати на Java. Ось так міг би виглядати клас, який працює з Redis:

Запит, який зможе використовувати цей клас для виявлення коннектов з мережі Tor, прийме такий вигляд:

Ось так, доклавши трохи зусиль, можна інтегрувати Esper з різними інформаційними масивами, і це лише один з небагатьох прикладів розширення функціональності Esper за допомогою кастомних модулів.

Esper на службі кореляції

висновок

Обробка подій є наріжним каменем в самих різних областях: трейдингу, антіфроде, виявленні вторгнень і аномалій, моніторингу. Всі ці області об'єднує необхідність складної обробки подій з мінімальною затримкою. Відмінним рішенням для виконання цього завдання служить бібліотека Esper завдяки широким можливостям, простому синтаксису для опису правил і дуже хорошою розширюваності. Щоб попрактикуватися у написанні EPL-виразів і побачити результат їх роботи, можна скористатися веб-додатком. Якщо тобі цікаво, яким чином використовувати Esper в своєму додатку, зверни увагу на папку з прикладами всередині архіву з бібліотекою або дочекайся наступного номера, де ми перейдемо від теорії до практики і створимо наш мегакоррелятор з блек-джек і іншими пляшками. Як то кажуть, stay tuned!

Покажи цю статтю друзям:

Схожі статті