Как строить сканирование активов в MaxPatrol VM. Ч.4 — Автоматизация по API. Ч.0 — авторизация

Мы с Вами просканировали основные типы активов. Можно выпустить гайды по сканированию сетевого оборудования и виртуализации, но здесь мне нечего добавить поверх официальной документации. Так что, мы переходим к большому пласту автоматизации через API, да еще и с примерами!
Все примеры кода будут на Python. Я уже давно не пишу на С++/С#. Любителей Go прошу понять и простить, за то что я не настолько модный.

Разговор про API начнем с авторизации, получения Bearer-токена и headers, которые будем использовать для каждого API-запроса.
Авторизацию в API MPVM можно выполнять 3 способами:
Я буду приводить пример для локальной УЗ. Связано это с тем, что код я написал давно, а вендор удалил документацию про авторизацию для версий новее 2.7 (27.2).

Закончив школу, я растерял способность описывать «что нам хотел сказать автор в этом произведении?». А в компаниях, где я работаю, не согласовывают ставку штатного предсказателя документации.

Так что используем проверенные временем наработки.
Вообще, с автоматизацией у меня всё закрутилось-завертелось, только когда Алексей Леонов(@avleonov) выложил в свой GitHub пример скрипта по выгрузке json из MPVM. Только посмотрев на рабочий пример, я понял, как приложить к этому API свои руки. Спасибо, Алексей!
Поделюсь материалами, которыми можно дополнительно воспользоваться при создании автоматизации:

Права УЗ
Т.к. вендор в документации не описывает набор привилегий, то отвечать на этот вопрос мне пришлось методом научного тыка. В компоненте MC для УЗ прописываем базовый минимум привилегий:
Management and Configuration:
Пользователь - для получения Bearer-токена. Используем стандартную роль.
Конечно же, для набора привилегий в MaxPatrol 10 нужно будет создать роль в MC. Ограничения на объекты в MP10 настраиваются сугубо индивидуально.
MaxPatrol 10:
Активы:
Уязвимости - для выгрузок информации о CVE.
Создание, просмотр, изменение, удаление - для автоматизации создания динамических групп активов.
Просмотр - для просмотра списка активов.
Общее:
Расширенные полномочия - для «активации» кнопки «Экспорт» отчетов из MPVM.
Сбор данных:
Задачи - для автоматизации создания задач сканирования:
Создание, просмотр, изменение, удаление.
Просмотр.
Профили:
Просмотр - для указания профилей сканирования при создании задачи сканирования.
Инфраструктура - в некоторых API-запросах нужно указывать «scope», т.e. идентификатор инфраструктуры. Его можно получить через API-запрос.

Получение Bearer-токена авторизации
Все запросы в MPVM работают с указанием Bearer-токена. Для его получения мы отправляем POST-запрос с нашими кредами, в ответ получаем сам токен. Логин-пароль считываем из .env-файла с секретами.
.env мы не коммитим в Git.
ClientSecret-параметр уникален для каждой инсталляции, его забираем, с сервера с установленной ролью Core.
import requests
from dotenv import load_dotenv, find_dotenv
from os import getenv
from ... import MPVM_HTTPS_VERIFY, mpvm_base_url # импорт из файла с глобальными параметрами: путь к полной цепочке сертификации в формате .pem и URL
load_dotenv(find_dotenv()) # Ищем .env
def vm_authentificate(mpvm_base_url): # mpvm_base_url = https://fqdn
url = mpvm_base_url + ":3334/connect/token" # Локейшен авторизации
headers = {
"content-type": "application/x-www-form-urlencoded",
}
data = {
"username": getenv("MPVM_USER"), # Подставляем логин из .env
"password": getenv("MPVM_PASSWORD"), # Подставляем пароль из .env
"client_id": "mpx", # Идентификатор приложения. Подробности в оф. документации.
"client_secret": getenv("MPVM_CLIENT_SECRET"), # ClientSecret param from /var/lib/deployer/role_instances/Core/params.yaml
"grant_type": "password", # Указываем тип авторизации. Локальные логин-пароль. Для доменной и токена тип авторизации неизвестен. Теоретически описание здесь - https://help.ptsecurity.com/ru-RU/projects/siem/8.4/help/3678991755
"response_type": "id_token",
"scope": "mpx.api",
}
try:
x = requests.post(url, data=data, headers=headers, verify=MPVM_HTTPS_VERIFY)
except (ConnectionError, requests.exceptions.ConnectionError) as err:
return None
token = x.json()["access_token"]
return token
И получаем ответ от MPVM:
{
"access_token": "495A2...",
"expires_in": 86400,
"token_type": "Bearer",
"scope": "mpx.api idmgr.api"
}
Как можно заметить, время жизни токена 86400 секунд = 24 часа. Т.е. нам не нужно перезапрашивать токен на время работы скрипта.
Headers
HTTP-заголовки универсальны для каждого API-запроса.
bearer_token = vm_authentificate(mpvm_base_url)
if bearer_token != None:
headers = {
"authority": mpvm_base_url,
"accept": "application/json, text/plain, */*",
"content-type": "application/json;charset=UTF-8",
"authorization": "Bearer " + bearer_token,
}
Собственно, на этом всё. Мы успешно авторизовались в MPVM. И теперь можем выполнять любые API-запросы, подставляя headers.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.