Сбор логов из облачного хранилища LogEntries

Исторически так сложилось, что многие части ИТ инфраструктуры сегодня можно получать как сервисы. Тут и Active Directory, и почта, и сбор и хранение журналов событий. Об одном из таких сервисов и пойдет дальше речь.

Вернее даже не о самом сервисе, а о том, как можно тянуть из него журналы событий для обработки в свой SIEM.

1. Вместо вступления

Итак, виновник сегодняшней статьи – Logentries (далее — LE), сервис сбора и хранения журналов событий. Его явным плюсом является удобство интеграции с приложениями, также работающими в «облаках», например, Heroku, Amazon и других. Скорость поиска тоже радует, но возможности в части корреляции событий, их обогащения оставляют желать лучшего, ведь это всего лишь сервис сбора и хранения, но никак не обработки журналов событий. Как быть если журналы, хранящиеся в LE необходимо обрабатывать в рамках выполнения процессов управления инцидентами ИБ?

Очевидно, забирать журналы событий из LE и отправлять их в SIEM систему. У LE есть специальный API, который позволяет получать журналы событий посредством HTTP запросов, им-то я и воспользовался для решения поставленной задачи.

Путь был тернист и сперва я экспериментировал с LIVE TAIL API, но он упорно закрывал сессию после выполнения 480 запросов. Необходимо было рестартовать весь скрипт. Плюс, если в каком-то запросе происходил сбой, то информация, считай, терялась, т.к. этот API не имеет никакого механизма контроля состояния (точки последнего прочитанного события).

В итоге свой выбор я остановил на GET Query. Разработанный коннектор (назову его так) базируется на python скрипте, опубликованного самими разработчиками Logentries. Схема работы коннектора показана на рисунке 1.

Рисунок 1 – Работа коннектора Logentries

Коннектор с некоторой периодичностью выполняет запросы к API Logentries, получает журналы событий и передает их демону syslog, который в свою очередь может отправлять события на указанный сервер (или напрямую в SIEM). Периодичность выполнения запросов указывается в конфигурации коннектора и по-умолчанию составляет 1 минуту.

В описанном решении коннектор устанавливается на отдельном сервере под управлением ОС Linux. Тестирование проводилось на ОС CentOS 7 версии, однако на других дистрибутивах он тоже должен работать. Необходимыми условиями для его работы являются наличие:

  • python7;
  • модулей requests, time, datetime, sys, re, syslog.

Все файлы коннектора лежат на github.

2. Архитекура коннектора

Коннектор включает в себя следующие компоненты:

  • le_query.py;
  • tail_run.sh;
  • tail_watcher.sh;
  • apps_list.txt.

Наглядно архитектура изображена на рисунке 2. Далее о каждом из компонентов по-порядку.

Рисунок 2 – Архитектура коннектора

2.1. le_query.py

Данный компонент выполняет всю «грязную работу». При запуске ему передаются следующие параметры:

  • apikey – ключ API, уникальный для каждого аккаунта в Logentries;
  • logkey – ключ лога приложения внутри аккаунта Logentries, уникальный для каждого лога;
  • leql query – запрос в формате leql, который позволяет получать не весь лог, а только интересующие нас событий, например “where(ssh)”;
  • appname – имя приложения чей лог получаем (не обязательно должно соответствовать имени в Logentries);
  • workdir – рабочая директория скрипта (например “/usr/local/le_get_api”);
  • event_count – максимальное количество событий, получаемых в одном запросе(лимит Logentries составляет 500 — офф. документация);
  • timeout — таймаут перед следующим запросом.

Будучи запущен данный скрипт читает лог одного приложения из LE, выполняет дедупликацию событий и передает их демону syslog. Для того, чтобы читать сразу лог нескольких приложений был создан управляющий скрипт tail_run.sh.

2.2. tail_run.sh

Данный компонент коннектора являетсяя управляющим модулем, который читает конфигурационный файл apps_list.txt и согласно указанным в нем параметрам выполняет запуск необходимого количества экземпляров le_query.py. Запускает он их не одновременно, а с паузой в несколько секунд, чтобы минимизировать вероятность выполнения одновременных запросов в LE несколькими экземплярами le_query.py, что может привести к ошибкам и перебоям в работе. Также данный модуль запускает процесс «наблюдатель» tail_watcher.sh, который проверяет наличие работающих процессов le_query.py и в случае их отсутствия выполняет перезапуск.

2.3. tail_watcher.sh

Данный компонент не подразумевает взаимодействие с пользователем. Он стартует вместе с экземплярами le_query.py в момент старта коннектора и останавливается в момент выключения коннектора управляющим модулем tail_run.sh.

2.4. apps_list.txt

Этот модуль представляет собой конфигурационный файл, в котором указывается сколько экземпляров le_query.py необходимо запускать а также указываются индивидуальные параметры каждого экземпляра.

Каждая строка конфигурационного файла соответствует одному экземпляру le_query.py, читающему один лог приложения в LE. Через запятую в строке указываются 5 параметров:

apikey,logkey,leql query,appname,event_count,timeout,comment

Пример:

abcdef12-1234-abcd-ef12-0123456789ab,abcd1234-1234-abcd-1234-aaaaaabbbbbb,where(/.*/),Application_1,400,60,Comment Application 1

abcdef12-0000-dddd-ef12-0123456789ab,dddd7734-1234-abcd-1212-aaaaaacccccc,where(/ssh/),Application_2,300,30,Comment Application 2

Параметр appname не обязательно должен соответствовать названию лога в Logentries, он может быть любым, НО не должен содержать пробелы. Параметр comment также произвольный и может содержать пробелы.

3. Как пользоваться

  1. Скачать коннектор с github;
  2. Поместить папку коннектора(le_get_api) в удобное место(по-умолчанию /usr/local) на машину, на которой он будет работать;
  3. Исправить параметр wdir в файлах tail_run.sh и tail_watcher.sh чтобы он указывал на ту директорию, в которую вы поместили файлы коннектора(по-умолчанию /usr/local/le_get_api);
  4. Заполнить конфигурационный файл apps_list.txt;
  5. Запускать коннектор из его домашней папки с помощью ./tail_run.sh start, останавливать с помощью ./tail_run.sh stop.

4. Траблшутинг

В случае удачного старта коннектора должны появиться процессы le_query.py в количестве равном числу читаемых логов LE. Проверить наличие этих процессов можно так:

ps –ef|grep le_query|grep –v grep

Коннектор пишет краткую информацию о своей работе в syslog. События можно найти так:

grep “le_query” /var/log/messages

5. Заключение

На данный момент актуальная версия коннектора 1.0 1.1. Она успешно протестирована на небольших потоках событий – около 10-20 eps

Планируется развитие коннектора,  в частности:

  • оптимизация под бОльшие потоки событий;
  • оптимизация скрипта tail_watcher для слежения за каждым экземпляром le_query.py в отдельности;
  • [СДЕЛАНО] оптимизация скрипта le_query.py для обработки ошибок http соединения (404, 502);
  • добавление удобства конфигурирования времени ожидания между запуском экземпляов le_query.py (в данной версии 7 секунд по-умолчанию);
  • [СДЕЛАНО] добавление удобства конфигурирования периодичности забора логов из LE (сейчас по-умолчанию 1 минута);
  • [СДЕЛАНО] улучшение функции логирования работы самого коннектора.