Сквозной разбор — подключение «Acme SIEM»
Почему это важно. Предыдущие главы покрывали каждый этап изолированно. Эта глава соединяет их в единую сборку: вымышленный SIEM под названием Acme SIEM проходит от «не подключён» до рабочего экрана кейса и запущенного плейбука, используя только механизмы, которые существуют в продукте. Каждое имя экрана, кнопки и поля ниже — реальное. Пройдите её один раз против собственного тестового источника, и конвейер перестаёт быть абстрактным.
Сборка следует порядку из главы 1 §1.5: коннектор → образец данных → типы инцидентов → классификатор → кастомное поле → маппер → layout → плейбук → проверка.
9.1. Цель и пример алерта
Acme SIEM поднимает алерты аутентификации. Мы хотим два исхода:
- Алерт brute-force становится кейсом типа Brute Force Login.
- Алерт authentication-anomaly становится кейсом типа Authentication Anomaly.
В обоих экран кейса должен показать имя алерта, severity, когда он произошёл, внешнюю ссылку, нормализованную MITRE Technique и дедуплицированный список Tags; а на создании должен отработать небольшой плейбук.
Вот репрезентативный фид Acme SIEM — JSON-массив из двух событий (второе
отличается в основном по category), с полями на верхнем уровне и именованными в
стиле SIEM (sourceip, а не source.ip):
[
{
"alertid": "ACME-2026-004417",
"alertname": "Multiple failed logons then success",
"category": "brute_force",
"severity": "high",
"sourceip": "203.0.113.44",
"destinationip": "10.12.4.7",
"hostname": "FIN-WKS-118",
"username": "j.okafor",
"useremail": "j.okafor@acme.example",
"eventcount": 42,
"mitretechnique": " t1110 ",
"tags": ["auth", "", "brute-force", "auth"],
"detectedtime": "2026-07-17T09:14:22Z"
},
{
"alertid": "ACME-2026-004418",
"alertname": "Impossible-travel sign-in",
"category": "auth_anomaly",
"severity": "medium",
"sourceip": "198.51.100.9",
"destinationip": "10.12.4.7",
"hostname": "FIN-WKS-204",
"username": "s.haddad",
"useremail": "s.haddad@acme.example",
"eventcount": 1,
"mitretechnique": " t1078 ",
"tags": ["auth", "anomaly", "anomaly"],
"detectedtime": "2026-07-17T09:20:05Z"
}
]
Две детали намеренны: mitretechnique имеет окружающие пробелы и нижний регистр
(мы почистим его цепочкой трансформеров), а tags содержит пустую строку и
дубликат (мы почистим его фильтром).
9.2. Шаг 1 — создание коннектора и инстанса
Маршрут: /settings/connectors · Права: connectors.view,
connectors.manage
- Откройте Settings → Integrations → Connectors.
- В левом списке коннекторов кликните New Integration. В редакторе коннектора
задайте Name =
Acme SIEM, Type =SIEM, Source Key =acme_siemи добавьте поля схемы, которые нужны источнику (для REST-источника: URL API и ключ API). Сохраните коннектор. - Выберите Acme SIEM в списке; редактор инстанса откроется справа. Создайте
инстанс:
- Instance Name —
Acme SOC. - Source Instance Key —
acme-soc(без пробелов; это как алерты привязываются к этому инстансу). - Заполните секции схемы коннектора. Поля сгруппированы в Connect (учётные данные / URL), Collect (что тянуть), Runtime & network (прокси, таймаут, сертификат) и General.
- Задайте Source Reliability, если используете threat-скоринг (по умолчанию
B). - Кликните Advanced Settings, чтобы раскрыть Fetch interval, Active,
Use by default и Auto enrichment. Включите Active. Если Acme SIEM
будет опрашиваться, также включите fetch и задайте Fetch interval; если он
будет проталкивать в
/ingest, оставьте fetch выключенным.
- Instance Name —
- Кликните Test, чтобы проверить подключение (реальные коннекторы возвращают модальное окно статуса), затем Save (или Save & Exit).
Две входные двери. Инстанс с включённым fetch тянет алерты по своему интервалу; источник без цикла fetch может проталкивать в
POST /api/v1/ingest(§9.10). В любом случае алерт входит в тот же конвейер ingest, и применяются классификатор и маппер этого инстанса.
9.3. Шаг 2 — загрузка примера алерта в конструктор классификатора
Маршрут: /admin/incident-types · Права: incident_types.view,
incident_types.manage
Вам нужны реальные имена полей, прежде чем классифицировать или маппить, так что сначала загрузите образец.
- В области Collect редактора инстанса кликните New Classifier (это открывает конструктор классификатора для этого инстанса). Вы также можете дойти до него из Objects Setup → Incident Types → classifier.
- Наверху конструктора подтвердите Connector:
Acme SIEMи Instance:Acme SOC. - В Get data: выберите, как загрузить события:
- Pull from instance — забрать живые события (затем Pull).
- Generate sample — синтезировать события из формы коннектора.
- Paste JSON — кликните Load, и в диалоге Paste Sample Events вставьте массив из §9.1, затем Load.
- Левая панель заполняется загруженными событиями (используйте стрелки ◀ ▶, чтобы пролистывать их), а центральная панель показывает JSON-дерево события. Теперь у вас есть конкретные имена полей для работы.
9.4. Шаг 3 — создание двух типов инцидентов
Маршрут: /admin/incident-types?tab=classification&classificationTab=objects
Классификатор может маршрутизировать только к существующим типам инцидентов, так что создайте их сейчас.
- Откройте библиотеку объектов (Back to Classification & Mapping из классификатора, затем представление objects → Incidents).
- Кликните New Incident Type, задайте отображаемое имя Brute Force Login, сохраните.
- Повторите для Authentication Anomaly.
9.5. Шаг 4 — построение правил классификации
Обратно в конструкторе классификатора (Objects Setup → Incident Types → classifier):
- Дайте классификатору имя (напр.
Acme SIEM classifier) в поле имени. - В центральной панели — «Select the field that identifies the incident type» —
задайте поле классификатора. Кликните
categoryв JSON-дереве или наберите путь напрямую. SOARForge собирает отдельные значения этого поля по загруженным событиям: здесьbrute_forceиauth_anomaly. - Правая панель перечисляет ваши типы инцидентов под Incident Types. Перетащите значение brute_force на Brute Force Login, а auth_anomaly на Authentication Anomaly (каждый тип показывает зону Drop values here). Значение, оставленное несопоставленным, остаётся неклассифицированным.
- Задайте fallback: в Direct unclassified events to выберите fallback-тип инцидента (напр. Authentication Anomaly), чтобы несовпавший алерт всё же становился кейсом.
- Кликните Save Version. Появляется подтверждение «Classifier saved».
Классификатор решает тип первым. Ветки (Specific) входящего маппера на тип завязаны на это решение — так что если Specific-ветка, кажется, никогда не отрабатывает, проверьте, что классификатор действительно маршрутизирует алерт к этому типу, прежде чем подозревать маппер.
9.6. Шаг 5 — создание кастомного поля
Маршрут: /admin/incident-types?...classificationTab=objects → Incidents
Платформа поставляет много встроенных полей, но «MITRE Technique» — наше, чтобы его добавить.
- В библиотеке объектов выберите Incidents, откройте список полей и кликните New Incident Field.
- Задайте Field Type = Text, подпись =
MITRE Technique. Machine-имя генерируется за вас (напр.mitre_technique) — это ключ, на который ссылаются маппер и layout. - Сохраните. Поле теперь доступно как цель маппера и в библиотеке полей layout-а.
Создайте поле до того, как маппить или размещать его. Кастомное поле, которого не существует, не может быть целью маппера или элементом layout-а. Это самая частая ошибка «задом наперёд» (см. гл. 1).
9.7. Шаг 6 — маппинг полей во входящем маппере
Маршрут: /admin/incident-types → incoming mapper
Откройте входящий маппер инстанса (из области Collect инстанса, New Incoming Mapper / Open Incoming Mapping Editor, или через Objects Setup → Incident Types → incoming-mappers). Заголовок читается Incoming Mapping Editor.
Загрузите данные источника. Как в классификаторе, используйте элемент Data: (Pull instance / Schema/sample / Upload JSON), чтобы редактор знал имена полей источника.
Scope. Оставьте Scope: Common для маппингов, применимых к каждому типу инцидента; переключитесь на Specific и выберите Branch: (тип инцидента) для маппингов на тип. Для этого разбора смаппьте всё в Common.
Смаппьте шесть полей. Для каждого целевого поля задайте его путь источника (кликните поле в исходном JSON или наберите путь) и, где отмечено, добавьте трансформеры/фильтры:
| Целевое поле | Путь источника | Трансформеры / Фильтры |
|---|---|---|
| Name | alertname |
— |
| Severity | severity |
— |
| Occurred | detectedtime |
— |
| Source Ref | alertid |
— |
| MITRE Technique (custom) | mitretechnique |
Трансформеры: trim → toUpperCase |
| Tags | tags |
Фильтры: compact, unique |
- Для MITRE Technique откройте расширенное меню строки поля и под
Transformers кликните Add transformer дважды: сначала
trim(срезает окружающие пробелы), затемtoUpperCase(нормализуетt1110→T1110). Трансформеры гоняются по порядку, сверху вниз. - Для Tags откройте Add filter под разделом Where и добавьте
compact(отбрасывает пустую строку), затемunique(убирает дубликат), превращая["auth","","brute-force","auth"]в["auth","brute-force"].
Добавление не-встроенных целей. Вендорские поля без встроенного дома —
sourceip,hostname,username— можно добавить вводом Add custom incident field (e.g. email.subject) внизу списка целей, затем Add. Они попадают вcustom_fieldsкейса и адресуемы какincident.<key>.
Кликните Save Mapper.
Куда идут сопоставленные данные. Всё, что пишет маппер, попадает в колонку
custom_fields— никогда вraw_json, который хранит нетронутый оригинал. Подтвердите маппинг, сравнивincident.rawJSON.mitretechnique(что прибыло) с сопоставленнымincident.mitre_technique(что произвёл трансформер).
9.8. Шаг 7 — размещение поля на layout-е
Маршрут: /admin/layouts · Права: layouts.view, layouts.manage
- Откройте Objects Setup → Layouts и отредактируйте layout, привязанный к Brute Force Login (или создайте один для типа инцидента).
- В Layout Builder найдите библиотеку полей слева. Наберите
MITREв Search fields, чтобы найти MITRE Technique. - Перетащите поле из библиотеки на секцию холста. Подправьте его подпись/видимость в панели свойств справа при необходимости.
- Кликните Save. (Используйте 📋 History, чтобы откатиться при необходимости.)
Повторите для layout-а Authentication Anomaly, если хотите видеть поле на обоих типах.
9.9. Шаг 8 — сборка минимального плейбука
Маршрут: /playbooks · Право: cases.view (модуль: cases)
Плейбук из четырёх узлов: start, ветвление по severity, извлечение индикаторов, оставить заметку.
- Откройте Playbooks и кликните, чтобы создать новый плейбук. Редактор показывает Node Palette слева, холст посередине и панель Properties справа (она появляется, когда выбран узел).
- На холсте уже есть узел Start (Flow Control). Перетащите эти из палитры на
холст:
- Из Logic → Condition.
- Из Actions → Extract Indicators.
- Из Flow Control → Note.
- Соедините узлы, перетаскивая от ручки-выхода одного узла к входу следующего: Start → Condition, затем выход True Condition → Extract Indicators → Note. (У узла Condition есть выходы True / False; проложите False к Note тоже, если хотите, чтобы оба пути заканчивались там.)
- Выберите каждый узел и настройте его в панели Properties — например,
настройте Condition проверять
${incident.severity}равноhighи подтвердите, что узел Extract Indicators гоняется против кейса. - Назовите плейбук (напр.
Acme SIEM triage) и Save (можно добавить change note при сохранении версии).
Что и когда гоняется. Этот плейбук — часть контента, как любая другая; прикрепите его к post-processing типа инцидента или запустите с кейса. Его результаты пишутся в колонку
context_outputsкейса, где их могут читать виджеты layout-а и другие автоматизации.
9.10. Шаг 9 — сквозная проверка
Отправьте один тестовый алерт и проследите его через конвейер.
Протолкните тестовый алерт. Если инстанс не опрашивает, отправьте POST-ом brute-force событие на эндпоинт ingest.
source— это Source Key коннектора, аsourceInstance— Source Instance Key инстанса, так что платформа применяет классификатор и маппер этого инстанса:curl -X POST https://<your-host>/api/v1/ingest \ -H "Content-Type: application/json" \ -H "X-Ingest-API-Key: <your-ingest-api-key>" \ -d '{ "source": "acme_siem", "sourceInstance": "acme-soc", "sourceRef": "ACME-2026-004417", "payload": { "alertid": "ACME-2026-004417", "alertname": "Multiple failed logons then success", "category": "brute_force", "severity": "high", "sourceip": "203.0.113.44", "hostname": "FIN-WKS-118", "username": "j.okafor", "mitretechnique": " t1110 ", "tags": ["auth", "", "brute-force", "auth"], "detectedtime": "2026-07-17T09:14:22Z" } }'Эндпоинт возвращает
202 Accepted— кейса ещё нет; он строится мгновением позже из очередиsoar.ingest.Подтвердите кейс. Через несколько секунд откройте Cases. Новый кейс должен появиться с типом Brute Force Login (классификатор маршрутизировал
category: "brute_force").Проверьте поля. На экране кейса: Name = имя алерта, Severity = high, Occurred = detected time, а ваш кастомный MITRE Technique =
T1110(обрезан и в верхнем регистре) — виден, потому что вы поместили его на layout. Tags должны читатьсяauth,brute-force(пустое и дубликат убраны).Проверьте плейбук. Подтвердите, что плейбук отработал (его выводы на кейсе) и что индикаторы вроде source IP извлечены.
Если что-то из этого не так, пройдите конвейер по порядку: неверный тип →
классификатор; пустое/некорректное поле → маппер (сравните с incident.rawJSON);
поле отсутствует на экране → layout; плейбук не отработал → его привязка/триггер.
Распространённые ошибки
202прочитан как «кейс создан». Вызов ingest принимается асинхронно. Ищите кейс мгновением позже, а не в HTTP-ответе.- Поля образца под обёрткой. В этом разборе поля алерта на верхнем уровне, так
что поле классификатора —
category, а источник маппера —sourceip. Если ваш реальный источник вкладывает всё подpayload, ваши пути становятсяpayload.category/payload.sourceip— всегда читайте реальное JSON-дерево в конструкторе, а не предполагайте. - Поле классификатора с одним значением. Классификатор маршрутизирует отдельные
значения одного поля. Если у каждого загруженного события одна и та же
category, вы получаете одну корзину и не можете разбить на два типа — выберите поле, которое действительно варьируется, или загрузите различающиеся события. - Маппинг в поле, которого ещё нет. Создайте кастомное поле MITRE Technique до маппинга в него и до размещения на layout-е; иначе оно не предлагается как цель или элемент layout-а.
- Путаница трансформер vs фильтр.
trimиtoUpperCase— трансформеры (они переформовывают значение) и живут под Add transformer;compactиunique— фильтры (они оставляют/отбрасывают элементы в списке) и живут под Add filter. Применение фильтра списка к скаляру или строкового трансформера к массиву не делает ничего полезного. - Рассинхрон source key на
/ingest. Еслиsourceв payload не совпадает с Source Key коннектора, платформа не может привязать алерт к классификатору и мапперу этого инстанса, и откатывается к дефолтам. - Редактирование layout-а до того, как маппер заполнит поле. Размещённое поле отрисовывается пустым, пока маппер его действительно не запишет — сначала проверьте маппинг, затем доверяйте layout-у.