Я расскажу о том, что мы с командой сделали для поднятия сервиса по сбору событий и низкоуровневой телеметрии на примере MacOS: как готовили архитектуру, с какими проблемами столкнулись и как их решали.  Подробнее остановлюсь на возможностях osquery&Fleet и на том, какие must-have-события рекомендую собирать.

Немного о себе: я работаю в группе инфраструктурной безопасности в команде Ozon около двух лет.  До этого я уже имела опыт работы с MacOS-устройствами, поэтому у меня есть представление о том, что это за «фрукт».

План 

Что такое osquery и Fleet

Osquery — проект с открытым исходным кодом. По своей сути это полноценный фреймворк, который позволяет упростить низкоуровневый мониторинг ОС. Osquery подписывается на системные события и формирует SQL-like таблицы.

Таблицы предоставляют удобный доступ к следующей информации:

  • об установленных пакетах и ПО; 

  • о конфигурации системы; 

  • о пользователях;

а также позволяют проверить запущенные процессы, сетевые коннекты и т.д. 

Получение информации из таблиц осуществляется при помощи SQL-запросов. 

Для более эффективного контроля над выполнением запросов и использованием ресурсов мы запускаем osquery совместно с watchdog-процессом мониторинга. Если выполнение запроса потребляет слишком много ресурсов, watchdog «убивает» этот процесс исполнения запроса.

Чем больше устройств – тем выше ответственность сложнее справляться с большим парком устройств. И тут нам на помощь пришел…

Fleet — это инструмент для централизованного управления и конфигурации агентов osquery. Если устройство добавлено во Fleet, то изменять конфигурацию агентов становится намного проще, можно добавлять/изменять/удалять новые запросы. Также можно выполнять distributed queries, выполнение которых позволяет получать информацию условно «здесь и сейчас». 

Всё это необходимо для: 

  • довольно существенного расширения возможностей при расследовании инцидентов (компрометация устройства/учетной записи); 

  • помощи в инвентаризации устройств;

  • обогащения события при инцидентах;

  • облегчения реализации дополнительных автоматизированных мониторингов.

Как мы выбирали ресурсы для сервиса по сбору событий

Мы изначально планировали провести тестирование с подключением 3000 устройств, чтобы проверить работоспособность цепочки поставки событий, а также нагрузку на БД и ноды, поэтому, изучив все рекомендации в документации Fleet и в сообществе в Slack, выбрали, что будем деплоиться на нескольких нодах приложения и БД (MySQL), а Redis будет в K8S. И всё это для отказоустойчивости будет в разных ДЦ.

По ресурсам много не потребовалось: 2vCPU, до 20 Gb объем HDD на нодах приложения и около 8 Gb RAM. 

Для БД ресурсов взяли вдвое больше, чем для нод с приложением.

vCPU

Storage (Gb)

RAM

Количество нод/tasks

Наша конфигурация серверов

Приложение

2

16

8

2

База данных MySQL

4

64

16

2

Рекомендации по документации fleet

Приложение

1

-

4

10

База данных MySQL

2

16

-

-

В целом таких ресурсов вполне достаточно для нормальной работы сервиса, загрузка минимальная, плюс Fleet удобно масштабировать горизонтально — мы это учитывали. 

Архитектура поставки событий  

Если кратко, то у нас есть 2 балансера (один пользовательский, другой сервисный), потому что хотелось явно разграничить доступы и роли — кто/куда ходит.

На пользовательский балансер выдаётся гранулярный и контролируемый внутренний доступ (по сертификатам). На сервисном балансере есть доступная API endpoint— /collector, чтобы события от агентов поступали вне корпоративной сети. Надеюсь, вы ещё не потеряли нить.

Далее в цепочке события от /collector поступают в file.d и от file.d — в SIEM, как в конечную точку приёма всех событий.

Также есть 4 API endpoint:

  • /api/v1/osquery/enroll (для добавления устройств во Fleet);

  • /api/v1/osquery/config (для обновления и получения конфига Fleet);

  • /api/v1/distributed/read (для distributed query);

  • /api/v1/distributed/write (для distributed query). 

Оба балансера проксируются на ноды, где поднято приложение Fleet.

Плюсы такой схемы (почему я рада такому решению):

  • нет необходимости ставить агента file.d на систему, file.d сам будет преобразовывать JSON, который поступает от osquery, для дальнейшей отправки в SIEM, а также выполнять функцию фильтрации;

  • есть разграничение по sourcetype на входе балансера;

  • file.d в K8s удобно масштабировать, повышается отказоустойчивость;

  • появляется возможность тротлить события (отбрасывает события, если пропускная способность конвейера становится выше настроенного порогового значения) внутри file.d → не нагружать SIEM.

Балансер используется, потому что существуют возможности:

  • тестировать разные решения отправки событий; 

  • настроить API endpoint и отправлять события от разных источников в разные логически разделённые места хранения в SIEM;

  • балансировать нагрузку между нодами приложений.

file.d — внутренняя разработка Ozon Tech, написанная на Go. Это инструмент для построения конвейеров данных: чтения, обработки и вывода событий. В основном он разработан для чтения из файлов, но также поддерживает множество плагинов ввода/действия/вывода (input/action/output— https://github.com/ozontech/file.d/tree/master/plugin).

file.d по функционалу очень схож с другим инструментом конвейеров данных — Vector’ом от Datadog.

Конфигурация мониторингов

Мы хотели собирать только те события, которые нам нужны для реализации мониторингов, в том числе чтобы сократить объёмы логов и чтобы просто не собирать «мёртвый груз».

Конечно, первоначально глаза разбегаются и хочется собрать всё, и всё кажется нужным. Но когда мы собирали первую версию пакета, то столкнулись с тем, что событий становится слишком много, и мы, по прогнозам, приближались к тому, чтобы «налить» в SIEM слишком большой объём событий.

Далее кратко о конфигурации запросов.

В osquery доступно два основных типа логирования: snapshot, differential (и differential ignore removals).

Differential — это дифференциальные изменения между последним выполнением запроса и текущим выполнением. Каждая строка журнала представляет собой строку JSON, которая указывает, какие данные были добавлены/удалены.

Snapshot — это, если дословно, моментальный снимок набора результатов в «точный момент времени». Полный моментальный снимок записывается после каждого выполнения запроса. Необходимо понимать, что это будет большой объём данных.

Опираясь на эти рассуждения, применили следующий принцип выбора типа логирования: если таблица имеет большой объем данных или данные в ней меняются незначительно, то используется метод Differential, в остальных случаях применяется snapshot.

О периодичности запросов

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

В результате анализа рекомендую собирать в качестве минимального набора следующие события с примером конфигурации, это так называемый must-have: 

Что собирать 

(какие таблицы)

Режим логирования

Частота исполнения запроса (в секундах)

 Установленное ПО (apps) 

Snapshot

86400

.bash_history (shell_history)

Differential

900

Сетевые интерфейсы (interface_details)

Snapshot

86400

Сетевые коннекты(process_open_sockets/processes/users)

Differential

3600

События процессов (process_events)

Differential

3600

Автозапуск (startup_items, crontab)

Differential

900

Залогиненные пользователи (logged_in_users)

Snapshot

3600

Встроенные СЗИ MacOS (disk_encryption/sip_config/gatekeeper/alf)

Snapshot

86400

Управление конфигурацией через fleetctl и REST API

Web UI, конечно, прикольно, но хотелось бы уметь управлять Fleet’ом не через интерфейс, плюс иметь возможность добавления интеграций. 

Теперь кратко по каждому из инструментов. 

Fleetctl — это CLI, который ставится отдельно, но с его помощью можно, например: 

  • выполнить тот же функционал distributed queries; 

  • посмотреть информацию об уже имеющихся queries; 

  • посмотреть информацию о конфиге Fleet; 

  • изменить конфигурацию Fleet; 

  • есть возможность дебага Fleet.

Rest API — у Fleet есть классная API, с помощью которой можно сделать дополнительные интеграции и получить необходимую информацию. Например, интегрировать Fleet и SIEM для добавления информации о хостах в SIEM. 

А также:

  • выполнить distributed queries к конкретному устройству (да, по ID);

  • листить все хосты (а также удалять хосты, получать информацию о конкретном хосте);

  • получить список пользователей, политик, ПО и т.д. 

Заключение 

Все мы знаем, что, насколько ни была бы защищена инфраструктура компании, её главным узким и самым уязвимым местом являются сотрудники. Преднамеренное или непреднамеренное действие может привести к грустным последствиям, поэтому собираемые события и автоматизированные мониторинги могут помочь выявить «атаку» на раннем этапе или же помочь в расследовании Incident response team — проанализировать случившееся и не допустить повторное. 

Osquery и Fleet — прекрасная связка для мониторинга ОС. В текущих реалиях для задачи мониторинга безопасности такой open-source-инструмент поможет снизить риски компрометации инфраструктуры. 

А в следующей статье, уже с коллегой, мы расскажем больше про аналитику и набор алертов, которые были нами реализованы.

Stay tuned. :)

Комментарии (1)


  1. igor_suhorukov
    26.07.2023 18:30

    Насколько я помню, когда пробовал интеграцию QuestDB с osquery, не все события остаются при pull запросах в osquery, некоторая телеметрия может отправляться в центральное хранилище только демоном osqueryd. The daemon also uses OS eventing APIs to record monitored file and directory changes, hardware events, network events, and more.

    Как с этим дела у Fleet, он только в режиме pull работает и отправляет запросы на каждое из устройств?