ГосСОПКА REST API 2024: аутентификация по сертификату и передача инцидентов через Ansible
НКЦКИ расширил REST API ГосСОПКА для субъектов КИИ. Разбираем структуру запроса, аутентификацию по клиентскому сертификату и автоматизацию отправки через Ansible playbook.
ГосСОПКА расширила REST API для автоматической передачи сведений об инцидентах субъектами КИИ
НКЦКИ в ноябре обновил документацию по API ГосСОПКА: добавили несколько новых эндпоинтов, уточнили схему объектов и немного облегчили жизнь тем, кто хочет передавать инциденты не руками через веб-кабинет, а автоматически. Мы как раз заканчивали аналогичную задачу у нескольких клиентов - и заодно посмотрели, что изменилось и что это значит для тех, кто ещё не подключился.
Если коротко: API стал чуть более внятным, но количество нюансов в аутентификации и формате никуда не делось. Рассказываем, как это выглядит изнутри.
Что добавили в API
Основное изменение - это расширение набора методов для работы с инцидентами. Раньше API позволял отправить инцидент и получить статус приёма. Теперь появились методы для обновления уже переданного инцидента (PATCH), получения списка своих инцидентов с фильтрацией по статусу и периоду, а также метод для прикрепления файлов (артефактов, скриншотов, логов) к уже созданному инциденту.
Это полезно: прежде update-сценарий вынуждал либо создавать новый объект, либо идти в веб-интерфейс руками. Теперь можно нормально вести инцидент от начала до закрытия через одну точку входа.
Структура запроса на создание инцидента
Базовый POST-запрос выглядит так:
POST /api/v2/incidents
Content-Type: application/json
Тело в JSON, ключевые поля:
title- краткое наименование, до 200 символов; лучше сразу в читаемом виде, потому что именно оно попадает в реестрdescription- развёрнутое описание события; поддерживает простой текст, без разметкиdetected_atиoccurred_at- метки времени в ISO 8601, обязательно с суффиксомZ(UTC); локальное время API не принимает, возвращает 422severity- одно из четырёх значений:low,medium,high,critical; от этого поля зависит приоритет обработки на стороне НКЦКИcategory- тип инцидента из закрытого справочника; список значений есть в документации, но он периодически пополняется - стоит проверять актуальную версиюaffected_objects- массив объектов с описанием затронутых активов: IP, hostname, тип объекта КИИ
Из практики: самая частая ошибка на первом запуске - формат detected_at. Передаёшь 2024-11-15T10:30:00+03:00, API отвечает 422 без внятного объяснения. Переводишь в UTC и добавляешь Z - проходит. Это поведение сохранилось и в новой версии, документация теперь явно про это написала, но всё равно ловим на каждом втором проекте.
Аутентификация: клиентский сертификат
Это самая нетривиальная часть, и тут всё осталось как было: API ГосСОПКА работает с двусторонним TLS. Сервер проверяет клиентский сертификат, выданный при регистрации субъекта в личном кабинете НКЦКИ.
Что нужно иметь:
- Клиентский сертификат (
.crtили.pem) и приватный ключ к нему - получаете при регистрации, храните в защищённом хранилище - Корневой сертификат НКЦКИ для проверки серверной стороны - скачивается с портала, обновляется редко, но следить стоит
- Цепочка промежуточных сертификатов - если она есть, нужно передавать полностью; без этого TLS-рукопожатие может падать на разных клиентах по-разному
При запросе через curl это выглядит так:
curl -X POST https://api.gosopka.gov.ru/api/v2/incidents \
--cert /path/to/client.crt \
--key /path/to/client.key \
--cacert /path/to/nktsci-ca.crt \
-H "Content-Type: application/json" \
-d @incident.json
На проде ключи и сертификаты держим в HashiCorp Vault или, если клиент без Vault, в зашифрованном Ansible vault-файле. Никаких plaintext-ключей в репозитории - это не обсуждается.
Ansible: плейбук для автоматической отправки
Для автоматизации мы используем Ansible playbook, который вызывается из pipeline при появлении нового инцидента. Задача забирает данные из SIEM (у нас это MaxPatrol или Kaspersky SIEM, в зависимости от клиента), формирует JSON и отправляет в ГосСОПКА.
Ключевой фрагмент - задача отправки через ansible.builtin.uri:
- name: Send incident to GosSOPKA
ansible.builtin.uri:
url: "{{ gosopka_api_url }}/api/v2/incidents"
method: POST
client_cert: "{{ gosopka_cert_path }}"
client_key: "{{ gosopka_key_path }}"
ca_path: "{{ gosopka_ca_path }}"
body_format: json
body:
title: "{{ incident.title }}"
description: "{{ incident.description }}"
detected_at: "{{ incident.detected_at | to_datetime | strftime('%Y-%m-%dT%H:%M:%SZ') }}"
occurred_at: "{{ incident.occurred_at | to_datetime | strftime('%Y-%m-%dT%H:%M:%SZ') }}"
severity: "{{ incident.severity }}"
category: "{{ incident.category }}"
affected_objects: "{{ incident.affected_objects }}"
status_code: [200, 201]
validate_certs: true
register: gosopka_response
no_log: true
no_log: true здесь обязателен - иначе в логи Ansible попадут содержимое тела с деталями инцидента и заголовки, включая путь к сертификату.
Дата-фильтр to_datetime | strftime('%Y-%m-%dT%H:%M:%SZ') - это наш способ гарантировать UTC-формат вне зависимости от timezone хоста, на котором запускается плейбук. Без этого на серверах с московским временем инцидент создавался с неверными метками.
После успешной отправки сохраняем gosopka_response.json.id - это идентификатор инцидента в системе НКЦКИ, он нужен для последующих PATCH-запросов при обновлении статуса.
Мониторинг канала
Отдельная задача, которую часто упускают: сам канал передачи нужно мониторить независимо от логики отправки инцидентов.
Мы добавляем в мониторинг три вещи:
- Срок действия клиентского сертификата - за 30 дней до истечения alert в Zabbix; если сертификат протухнет, передача молча перестанет работать
- Доступность API-endpoint - простой HTTP-чек с клиентским сертификатом раз в 5 минут; если API недоступен, инцидент нужно поставить в очередь и отправить позже
- Лог неуспешных отправок - отдельный файл, куда пишутся все 4xx/5xx ответы с телом запроса; без этого разобраться что пошло не так через неделю практически нереально
Очередь при недоступности - отдельная история. У нас простой вариант: Ansible пишет неотправленные инциденты в файл на диске, повторная задача смотрит в этот файл по расписанию. Не самое элегантное решение, зато прозрачное и без внешних зависимостей.
Что в итоге
Интеграция с ГосСОПКА через REST API решаема, новые возможности API (обновление и прикрепление артефактов) делают её немного более полноценной. Основные грабли - это формат дат и аккуратная работа с сертификатами - никуда не делись.
Если у вас КИИ первой категории и автоматической передачи инцидентов ещё нет - сейчас хороший момент это поправить: ручная отчётность через веб-форму всё меньше устраивает регулятора. О том, как мы выстраиваем подобные интеграции, можно спросить напрямую.