Перейти к основному содержимому
Версия: 4.5.X

Плагин http-scraping

Введение

Плагин http-scraping позволяет отправлять HTTP-запросы на различные хосты и создавать событие на основе возвращаемого ответа. Если сравнивать этот плагин с функционалом HTTP-коллектора, то можно представить их как подходы pull и push.

"Push" - подход HTTP-коллектора работает следующим образом: источник, у которого есть событие, сам посылает его на коллектор (т.е. событие "проталкивается" на коллектор).

"Pull" - подход плагина http-scraping же работает иначе: источник, у которого есть событие, отдает его по HTTP. Коллектор с плагином делает запрос на сервер-источник, чтобы это событие получить (т.е. событие "извлекается" коллектором).

Помимо создания событий на основе тела ответа данный плагин также может быть полезен, чтобы отслеживать задержку ответа либо следить за состоянием TLS-сертификатов сервера.

Конфигурация

Конфигурация плагина состоит из объекта http-scraping, в котором имеется два поля:

  1. targets - список целей для HTTP-запросов. Схожих с scrape_config в Prometheus. Их структура будет описана далее.
  2. include-response-headers - список заголовков ответа, которые будут включены в сформированное событие.

Вложенность в объект http-scraping требуется для идентификации плагина.

Конфигурация цели включает в себя множество полей. Рассмотрим их:

  • headers - заголовки запроса в виде словаря "строка-строка".
  • query - query-параметры URL, в конфигурации задаются как словарь, где ключом является строка, а значением - либо строка, либо массив строк.
  • url - URL запроса.
  • body - тело запроса.
  • method - метод запроса. По умолчанию равен GET.
  • username - имя пользователя для Basic Auth.
  • password - пароль пользователя для Basic Auth.
  • bearer-token-file - путь к файлу с токеном для авторизации (для авторизации на основе токенов)
  • tls - параметры TLS. Схожи с параметрами в конфигурационных файлах сервисов KOMRAD с единственным исключением: вместо того, чтобы указывать, выключен ли TLS (disable: false), здесь указывается, включен ли он (enable: true).
  • period - частота запросов в виде time.Duration. Задается строкой по типу "2s", "5h" и т.п.
  • timeout - таймаут для запроса, задается в виде time.Duration
  • deduplication0 - подход к дедупликации событий. Рассмотрим его позже.

Пример конфигурации:

http-scraping:
include-response-headers:
- Date
- Expires
targets:
- headers:
Cookie: "session=session_key"
query:
plain_param: param
list_param:
- param1
- param2
url: example.com/api/path
body: '{"hello": "world"}'
method: POST
tls:
enabled: true
TrustedCA: "/path/to/cert"
system-pool: true
period: 15s
timeout: 3m
deduplication: none

Дедупликация событий

Для дедупликации событий в цели можно использовать параметр deduplication в конфигурации одной цели. Основной механизм работы дедупликации - плагин запоминает определенный параметр ответа цели, который в дальнейшем сравнивается с аналогичным параметром нового ответа. Если они совпадают - новое событие не создается. Далее перечислены возможные стратегии дедупликации:

СтратегияПринцип работы
noneДедупликация отсутствует
bodyСобытия дедуплицируются на основе тела ответа
response_codeСобытия дедуплицируются на основе кода состояния ответа
errorСобытия дедуплицируются на основе произошедшей (или нет) ошибки

Например, мы дедуплицируем события на основе кода состояния ответа. Допустим, у нас следующая последовательность кодов ответа: 200 500 500 200 200. Тогда в результате получим 3 события: 200 500 200, т.к. вторые (и так далее) события убираются.

Парсинг ответа

Плагин парсит множество полей, связанных с HTTP-соединением. В таблице ниже перечислены извлекаемые поля:

ПолеЗначениеКогда добавляется к событию
ECS.Destination.AddressАдрес сервераПри создании подключения
(обычно TCP)
ECS.Destination.DomainДомен сервераПри начале DNS-запроса
ECS.Destination.IPIP сервераВ конце DNS-запроса
ECS.Event.DurationДлительность запросаПосле получения ответа
ECS.Event.StartВремя начала запросаПосле получения ответа
ECS.Event.EndВремя конца запроса
(время получения ответа)
После получения ответа
ECS.HTTP.ResponseBodyContentТело ответаПосле получения ответа
ECS.HTTP.ResponseBodyBytesРазмер тела ответа в байтахПосле получения ответа
ECS.HTTP.VersionВерсия HTTPПосле получения ответа
ECS.HTTP.Header.*Значения заголовков, заданных в поле include-response-headersПосле получения ответа
ECS.TLS.VersionВерсия TLSПосле получения ответа
ECS.TLS.CipherАлгоритм шифрования TLSПосле получения ответа
ECS.TLS.ResumedБыло ли соединение TLS возобновленоПосле получения ответа
ECS.TLS.EstablishedБыло ли соединение TLS успешно установленоПосле получения ответа
ECS.TLS.ServerIssuerИздатель сертификата сервераПосле получения ответа либо при неудачном рукопожатии TLS
ECS.TLS.ServerNotAfterВремя окончания сертификата сервераПосле получения ответа либо при неудачном рукопожатии TLS
ECS.TLS.ServerNotBeforeВремя начала действия сертификата сервераПосле получения ответа либо при неудачном рукопожатии TLS
ECS.TLS.ServerSubjectСубъект сертификата сервераПосле получения ответа либо при неудачном рукопожатии TLS

Примеры

Сбор логов аудита Jira

Поскольку плагин http-scraping не имеет сложную логику построения запросов (например, на основе шаблонов, использующих предыдущий ответ) и не сохраняет в долговечном месте информацию, то полноценный сбор логов без потерь организовать невозможно. Но пока есть базовый вариант, позволяющий ухватить их часть. Попробуем описать, как это сделать.

Для начала вам нужны права администратора, чтобы получить доступ к логам аудита (самому их можно посмотреть в Администрирование -> Система -> Журнал). Как только права получены, необходимо выпустить персональный токен доступа. Для этого переходим в свой профиль и открываем вкладку Персональные токены доступа. В этой вкладке нажимаем кнопку Создать токен, и далее задаем токену имя и срок действия. После создания копируем токен и сохраняем его в файл, он нам понадобиться.

Далее создаем плагин со следующим содержанием:

http-scraping:
targets:
- query:
limit: 1
url: 'https://jira.npo-echelon.ru/rest/auditing/1.0/events'
method: GET
bearer-token-file: "путь к сохраненному файлу с токеном"
period: 30s
timeout: 1m
deduplication: body

После этого включаем плагин на коллекторе, после чего с заданной периодичностью (если есть новые записи в логе) будем получать события. Можем попробовать добавить парсер для них. Чтобы это сделать, я использую плагин json в processors, созданный с помощью эвристического анализа (и слегка измененный мною):

processors:
- module: json
patterns:
- expr: entities.0.affectedObjects
to: AffectedObjects
- expr: entities.0.author.avatarUri
to: AuthorAvatarUri
- expr: entities.0.author.id
to: AuthorId
- expr: entities.0.author.name
to: AuthorName
- expr: entities.0.author.type
to: AuthorType
- expr: entities.0.author.uri
to: AuthorUri
- expr: entities.0.changedValues
to: ChangedValues
- expr: entities.0.method
to: Method
- expr: entities.0.source
to: Source
- expr: entities.0.system
to: System
- expr: entities.0.timestamp
to: Timestamp
- expr: entities.0.type.action
to: TypeAction
- expr: entities.0.type.actionI18nKey
to: TypeActionI18NKey
- expr: entities.0.type.category
to: TypeCategory
- expr: entities.0.type.categoryI18nKey
to: TypeCategoryI18NKey

После этого получим события, в которых есть информация как о HTTP-ответе (задержка ответа, код состояния, сертификат и т.д.), так и информация о самом логе. Эту информацию можно использовать дальше для фильтрации и корреляции.

Проверка здоровья сервиса

В разработке сервисов есть паттерн "проверки здоровья" (healthcheck), помогающий узнать, работает ли сервис исправно или есть какие-то неполадки. Для этого в HTTP API добавляется дополнительный маршрут (обычно, его называют /health), который в нормальной ситуации возвращает код состояния 200 и какую-то информацию (например, о состоянии системы). Если информации нет, можно возвращать просто какой-либо текст (например, текст кода состояния).

Можем использовать плагин http-scraping для того, чтобы создавать события, когда сервис нездоров. В качестве примера используем сам KOMRAD. Для сбора информации о здоровье используем следующий конфиг:

http-scraping:
targets:
- url: 'https://npo-echelon-komrad.ru/api/health'
method: GET
tls:
enabled: true
TrustedCA: "{путь к CA сертификату}"
system-pool: true
period: 30s
timeout: 15s
deduplication: response_code

Чтобы отфильтровывать события с успешным кодом возврата, можем использовать плагин if:

processors:
- module: if
cel:
- event.vars("ECS.HTTP.ResponseStatusCode") != 200

Обнаружение истечения срока действия TLS-сертификата

Плагин http-scraping можно использовать для обнаружения истекших сертификатов. Для этих целей можно использовать любой URL, например, для проверки здоровья из предыдущего примера.

Для примера возьмём проверку сертификатов на KOMRAD, используя ту же ручку.

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

http-scraping:
targets:
- url: 'https://npo-echelon-komrad.ru/health'
method: GET
tls:
enabled: true
TrustedCA: "{путь к сгенерированному корневому сертификату}"
period: 15s
timeout: 5s

После запуска плагина будем получать события, где в поле ECS.TLS.ServerNotAfter будет указана дата окончания действия сертификата. Можем использовать ее для фильтрации и корреляции. Например, можем использовать плагин deny для отсечения событий с сертификатами с долгим сроком валидности:

processors:
- module: deny
cel:
- event.vars("ECS.TLS.ServerNotAfter") != null && (event.vars("ECS.TLS.ServerNotAfter") - now() > duration("72h"))
- module: assign
assign:
- target: CertIsGoingToBeExpired
cel: "true"

В данном плагине deny отсеиваются все события, оставшийся срок действия сертификата которых превышает три дня. Также с помощью модуля assign добавляется поле, указывающее на скорое истечение сертификата.

После применения плагинов http-scraping и deny мы будем получать только те события от http-scraping, в которых срок действия сертификата подходит к концу.

Отслеживание высокой задержки HTTP-запросов

С помощью плагина http-scraping совместно с deny или assign можно отслеживать высокую задержку HTTP-ответа от сервера. Для этого в конфигурации необходимо "нацелить" http-scraping на нужный URL. Например:

http-scraping:
targets:
- url: http://npo-echelon-komrad.ru:health/
method: GET
body: Hello HTTP body!
period: 20s

В данном случае я написал простой сервер, который при запросе на "/" с методом POST засыпает на две секунды, а затем возвращает тело запроса в ответе. Чтобы отследить высокую задержку, можно написать еще один плагин. Я решил использовать assign, чтобы обогатить событие новым полем:

processors:
- module: assign
assign:
- target: HighLatency
cel: event.vars("ECS.Event.Duration") != null && event.vars("ECS.Event.Duration") > duration("1s")

Этот плагин записывает в поле HighLatency то, длился ли запрос больше одной секунды.