В современном мире кибербезопасности своевременное выявление и отслеживание актуальных уязвимостей становится жизненно важной задачей для организаций и специалистов по безопасности. Особенно актуально это для систем, работающих с большими объемами данных и динамично меняющейся информацией из различных источников, будь то новости, сообщения в социальных сетях или отчеты об инцидентах. Именно здесь наибольшее значение приобретают механизмы, позволяющие создавать трендовые фильтры — инструменты, которые способны быстро определять наиболее «горячие» темы или объекты, набирающие популярность за определённый промежуток времени. Одним из самых эффективных инструментов для работы с такими данными является Elasticsearch — распределённая платформа для поиска и аналитики, обладающая высокой скоростью обработки запросов и гибкими возможностями для агрегации данных. Недавно в области кибербезопасности был представлен новый метод построения трендовых фильтров на базе Elasticsearch, который решает ряд проблем, существовавших ранее, и предоставляет удобный механизм для фильтрации документов по популярности в заданном временном окне.
Традиционные подходы к выявлению трендов в Elasticsearch часто основывались на ранжировании всех документов по некоторому показателю активности или количества упоминаний. Однако данный способ не всегда удовлетворял специфическим требованиям: чаще было необходимо не просто упорядочить данные, а получить конкретный поднабор документов, соответствующих критерию «тренд» за выбранный период. Новая методика учитывает именно этот нюанс и предлагает фильтрующий подход, который возвращает только релевантные документы, а не весь список с ранжированием. Ключевой особенностью предлагаемого решения является использование структуры данных с вложенными (nested) массивами, где каждый элемент содержит информацию о количестве упоминаний (ссылках, упоминаниях) за определённую дату в виде пары «временная метка – значение». Такой подход позволяет эффективно хранить накопленные данные о трендах, сохраняя при этом возможность быстрого поиска и фильтрации.
Более того, для ускорения работы с временными окнами осуществлена предварительная агрегация данных внутри документа, то есть значения не просто представляют количество упоминаний за конкретный день, а являются накопленными суммами, включающими все значения с заданной временной точки и далее. Это решение позволяет отказаться от выполнения тяжелых агрегирующих запросов при каждом поиске – теперь достаточно простой вложенный запрос по диапазону времени и минимальному пороговому значению, что значительно повышает производительность. Помимо структуры данных и моделей запроса значительную сложность представляло определение порогового значения — того самого порога активности, который отличает трендовый документ от остального массива. Сложность в том, что эта величина должна динамически рассчитываться для заданного временного окна, учитывая распределение активности по всем документам. Для решения поставленной задачи был использован редко применяемый, но мощный инструмент Elasticsearch — Scripted Metric Aggregation.
Он позволяет выполнять несколько этапов вычислений с собственными скриптами, которые работают непосредственно на стороне сервера, оптимизируя нагрузку и позволяя выполнять очень гибкие вычисления. Скриптissage разбивается на четыре стадии — инициализация, обработка каждого документа, объединение результатов с разных шардов и финальное сведение, где происходит слияние данных и вычисление оптимального порога. В инициализационном шаге создаются структуры данных для хранения значений, в процессе обработки документов происходит чтение только тех вложенных элементов, которые соответствуют текущему временно́му окну, и фиксируются только первичные значения для каждого документа (чтобы избежать двойного включения и неверной агрегации). Затем на уровне шардов осуществляется подсчет частотности встречаемых значений активности. Финальный же скрипт объединяет результаты со всех шардов, формируя одну частотную таблицу.
Анализируя эту таблицу, он вычисляет некий целевой процент — например, 25% ведущих документов — и, проходя от максимального значения вниз, находит порог, при котором будет выбрано необходимое количество документов, удовлетворяющих критериям тренда. Так достигается баланс: не слишком множество документов попадает под фильтр, что исказило бы результаты, но и не слишком строгое ограничение не пропускает актуальные уязвимости. Сам запрос к Elasticsearch становится крайне простым: вложенный bool-запрос с двумя условиями в must — фильтр по времени и фильтр по значению, который пропускает только документы с накопленным количеством упоминаний выше рассчитанного порога. Такой компромисс между сложностью вычисления порога и простотой запроса по документам обеспечивает максимально быстрое выполнение поиска и легкую поддержку решения в производственной среде. Методика нашла применение в SecAlerts — сервисе, который информирует о новых уязвимостях и активных инцидентах.
Внедрение нового трендового фильтра позволило значительно повысить качество и релевантность результатов поиска, отсекая «шум» и акцентируя внимание на действительно важных и обсуждаемых в профессиональном сообществе проблемах информационной безопасности. Кроме того, концепция наглядно демонстрирует, как можно подойти к решению нетривиальной задачи с помощью нестандартных возможностей Elasticsearch и скриптов, не ограничиваясь лишь базовыми агрегатами и фильтрами. Общая архитектура решения также учитывает возможность кэширования вычисленного порога для каждого временного окна, что снижает нагрузку на систему — ведь порог не нужно пересчитывать при каждом запросе, он обновляется, например, раз в сутки, либо при значительном изменении данных. Это позволяет обслуживать большой поток запросов без ухудшения скорости работы сервиса. Новая методика построения трендовых фильтров имеет потенциал применения и в других областях, помимо кибербезопасности.