Общее описание #
Backend Suri Oculus — это высокопроизводительный REST API, написанный на C++ (C++17) с использованием фреймворка Pistache. Его задачи:
получать и отдавать события Suricata из Redis;
управлять правилами Suricata;
запускать/останавливать и перезагружать Suricata и вспомогательные демоны;
работать с индикаторами компрометации (IoC) и генерировать на их основе правила;
предоставлять статистику и состояние системы;
строить карту сети по данным Suricata.
Backend рассчитан как на «большие» серверы, так и на слабые машины с ограниченной памятью и CPU.
Запуск и сервис #
Backend может запускаться двумя способами:
Прямой запуск бинарника
Достаточно выполнить:oculus-serverЧерез сервис systemd
Устанавливается как сервис и управляется командами:systemctl start oculus-server systemctl stop oculus-server systemctl status oculus-server
По умолчанию HTTP-API слушает порт 8080 (TCP), но этот параметр можно изменить при сборке или через окружение.
Веб-клиент использует отдельный конфигурационный файл:
// config.js
export const backendUrl = 'http://backend_ip:8080'; // Замените backend_ip на IP/hostname сервера
Если вы меняете порт или прячете backend за nginx, достаточно обновить backendUrl.
Архитектура и Pistache #
Основной компонент — класс Server, который инкапсулирует Pistache::Http::Endpoint и Pistache::Rest::Router:
Server::Server(Pistache::Address addr)— создаёт HTTP-endpoint.Server::setupRoutes()— регистрирует все маршруты.Server::run()— инициализирует endpoint и запускает HTTP-сервер.
Ключевые моменты Pistache:
Router —
Pistache::Rest::Routesсвязывает HTTP-метод + путь с функцией-обработчиком.Endpoint —
httpEndpoint.init(Pistache::Http::Endpoint::options().threads(2));
Используется пул потоков (по умолчанию 2). Число потоков можно увеличивать на более мощных системах.Обработчики — реализация логики вынесена в классы:
Events— работа с событиями и временными рядами;Rules— управление правилами Suricata, перезапуск Suricata, управление демоном;Threats— управление IoC и IoC-правилами;Stats— статистика и состояние;Net— построение карты сети.
CORS и preflight-запросы #
Backend рассчитан на работу с браузерным клиентом с другого origin (другой порт/хост).
Для этого реализована поддержка CORS и отдельный обработчик preflight:
void handlePreflightRequest(const Pistache::Rest::Request &request,
Pistache::Http::ResponseWriter response)
{
Rules::addCORSHeaders(response);
response.send(Pistache::Http::Code::Ok);
}
Для всех POST-маршрутов, вызываемых из JavaScript, настроены соответствующие OPTIONS-маршруты, чтобы браузер мог корректно выполнять preflight-проверки.
Обзор HTTP-API #
Ниже — обзор маршрутов, сгруппированных по функциональным областям.
Все ответы — JSON, если не оговорено иное.
1. События (Events API) #
Пространство имён: Events
Назначение: доступ к событиям Suricata в Redis и базовая аналитика.
Базовые операции
GET /events/:event_type
Получить все события указанного типа (alert,flow,dns,http,tls,ssh,ftpи т.д.).GET /events/count/:event_type
Вернуть количество событий данного типа.GET /events/:event_type/:event_id
Получить конкретное событие по его ID.GET /events/search/:flow_id
Найти событие поflow_id.DELETE /events/delete/:event_type
Удалить все события указанного типа (используется для обслуживания и очистки).
CORS:OPTIONS /events/delete/:event_type.GET /events/find/:event_type
Поиск событий по параметрам (временной интервал, IP, порты и т.п.).GET /events/check/:event_type
Получить события заданного типа за последние N часов (timeshift).
Используется веб-клиентом для временных выборок.GET /events/fast
Отдаёт содержимоеfast.log.
Агрегированные представления
GET /events/alertsmap
Сжатое представление alert-событий для дашбордов/карт.GET /events/alertssignatures
Агрегация alert-ов по сигнатурам (топ-сигнатуры).GET /events/alertsbyhours
Количество alert-ов по часам.GET /events/anomaliesbyhours
Количество аномалий по часам (по данным AI-модуля).GET /events/flowsbyhours
Количество flow-событий по часам.GET /events/dnsbyhours
Количество DNS-событий по часам.GET /events/tlsbyhours
Количество TLS-событий по часам.GET /events/httpbyhours
Количество HTTP-событий по часам.GET /events/sshbyhours
Количество SSH-событий по часам.GET /events/ftpbyhours
Количество FTP-событий по часам.
Эти маршруты используются веб-клиентом для построения графиков «события/час» по категориям.
2. Правила и управление Suricata #
Пространство имён: Rules
Назначение: полный цикл работы с правилами Suricata и управление процессами Suricata/daemon.
Получение и поиск правил
GET /rules— вывести все правила.GET /rules/:sid— найти правило поsid.GET /rules/action/:action— фильтр по действию (alert,drop,rejectи т.д.).GET /rules/status/:status— фильтр по статусу (включено/выключено).GET /rules/protocol/:proto— фильтр по протоколу (tcp,udp,icmp, …).GET /rules/search— поиск правил по нескольким параметрам.GET /rules/signature/:signature— поиск по тексту сигнатуры.GET /rules/duplicated/:sid— поиск дубликатов правил с тем жеsid.
Модификация и валидация правил
POST + OPTIONS (для CORS):
POST /rules/toggle/— переключить статус правила (enable/disable).POST /rules/add/— добавить новое правило.POST /rules/validate/— проверить правило на корректность.POST /rules/delete/— удалить правило(а).POST /rules/update/— массовое обновление правил.POST /validate_rule_endpoint— альтернативная точка для валидации, используется веб-клиентом.
Дополнительные правила
GET /rules/additional/status/— состояние файла дополнительных правил (additional.rules).POST /rules/additional/update/— обновить файл дополнительных правил.
Управление Suricata
GET /suricata/reload/— перезагрузка конфигурации и правил Suricata.GET /rules/reload/blocking— блокирующая перезагрузка правил.GET /rules/reload/nonblocking— неблокирующая перезагрузка.GET /suricata/start/— запуск Suricata.GET /suricata/stop/— остановка Suricata.GET /suricata/update/— обновление файлов правил и перезагрузка.
Управление демоном
GET /daemon/start/— запуск вспомогательного демона (лог-перемещение, запись в Redis и т.д.).GET /daemon/stop/— остановка демона.
3. Угрозы и индикаторы компрометации (IoC) #
Пространство имён: Threats
Назначение: управление IoC и связанными с ними правилами.
Жизненный цикл IoC
GET /ioc/download/— загрузить свежие IoC с внешнего источника (ThreatFox).GET /ioc/filter/:n_days— выбрать IoC за последниеn_days.GET /ioc/— показать все IoC.GET /ioc/ioc_type/:ioc_type— фильтр по типу (IP, домен, URL и т.п.).GET /ioc/ioc_id/:id— получить IoC по ID.GET /ioc/ioc_status/:status— фильтр по статусу (enabled/disabled и др.).POST /ioc/toggle/— переключить статус IoC.
Правила на основе IoC
GET /ioc/fetch/— сформировать файлы правил Suricata из текущих IoC.GET /ioc/rules/status/— состояние файлов IoC-правил.POST /ioc/rules/modify/— изменить статус файлов IoC-правил (включить/выключить наборы).
4. Статистика и состояние #
Пространство имён: Stats
Назначение: мониторинг Suricata и ресурсов хоста.
GET /stats/— общая сводка статистики.GET /stats/pkts/— счётчики по пакетам.GET /stats/alerts/— счётчики по alert-событиям.GET /stats/cpu/— загрузка CPU.GET /stats/vm/— виртуальная память.GET /stats/pm/— физическая память.GET /stats/histogramm/— данные для гистограмм (используются в графиках).GET /suricata/running/— проверка, запущен ли процесс Suricata.GET /stats/update/— время последнего обновления статистики.
5. Карта сети #
Пространство имён: Net
Назначение: построение карты сети на основе данных Suricata.
GET /net/map/— текущая карта сети (узлы, связи, роли).GET /net/historicalmap/— историческая карта сети за более длительный период.
Конфигурационный файл (/etc/oculus/config++.conf) #
Конфигурация backend’а хранится в файле:
/etc/oculus/config++.conf
Файл делится на блоки main и settings.
Блок main #
application:
{
main:
{
title = "OCULUS SERVER";
version = "0.8.2";
date = "10 April 2024";
};
title— название приложения.version— версия backend’а.date— дата сборки/релиза.
Блок settings #
settings:
{
main_key = "suricata";
keys = ("alert", "flow", "http", "dns", "dhcp", "fileinfo", "stats", "tls");
valid_duration = 24;
redis_connect = «redis://127.0.0.1/»;
rules_file = «/var/lib/suricata/rules/suricata.rules»;
tmp_rule_file = «/home/fil/suricata_validate_rule.rules»;
suricata_conf = «/etc/suricata/suricata.yaml»;
additional_rules = «/var/lib/suricata/rules/additional.rules»;
ioc_full_link = «https://threatfox-api.abuse.ch/export/json/full/»;
ioc_full_file_path = «/var/lib/suricata»;
ioc_full_file_name = «/var/lib/suricata/full.json»;
ioc_local_file_name = «/var/lib/suricata/ioc.json»;
ioc_domain_rules = «/var/lib/suricata/rules/ioc_domain.rules»;
ioc_url_rules = «/var/lib/suricata/rules/ioc_url.rules»;
ioc_ip_rules = «/var/lib/suricata/rules/ioc_ip.rules»;
ioc_domains_lst = «/var/lib/suricata/ioc_domains.lst»;
fast_file = «/var/log/suricata/fast.log»;
};
};
Кратко по параметрам:main_key,keys— пространство имён ключей в Redis, под которыми хранятся события Suricata.valid_duration— срок «актуальности» данных/кеша (в часах).redis_connect— строка подключения к Redis.rules_file— основной файл правил Suricata.tmp_rule_file— временный файл для проверки правил перед применением.suricata_conf— путь кsuricata.yaml.additional_rules— файл дополнительных локальных правил.ioc_full_link— URL источника IoC (ThreatFox).ioc_full_file_path,ioc_full_file_name,ioc_local_file_name— файлы с «сырыми» и обработанными IoC.ioc_*_rules— файлы правил Suricata, сгенерированные из IoC (IP/домен/URL).ioc_domains_lst— простой список доменов из IoC.fast_file— путь кfast.log.
Любые изменения путей файлов или настроек Redis должны быть отражены в этом конфигурационном файле.
Конфигурация веб-клиента (config.js) #
В последних версиях веб-клиента для указания backend’а используется файл:
// config.js
export const backendUrl = 'http://backend_ip:8080';
Рекомендации:
Используйте
http://илиhttps://в зависимости от вашей схемы развёртывания.При наличии reverse-proxy можно использовать, например:
export const backendUrl = 'https://suri-oculus.example.com/api';Backend поддерживает CORS, поэтому веб-клиент и API могут находиться на разных портах и даже на разных хостах.