Справочник по синтаксису EQL
Основной синтаксис
Запросы EQL требуют категории события и условия соответствия. Ключевое слово where соединяет их.
event_category where condition
Категория события — это индексированное значение поля категории события. По умолчанию API поиска EQL использует поле event.category из Elastic Common Schema (ECS). Вы можете указать другое поле категории события, используя параметр API event_category_field.
Например, следующий запрос EQL соответствует событиям с категорией события process и значением process.name равным svchost.exe:
process where process.name == "svchost.exe"
Соответствие любой категории события
Чтобы сопоставить события любой категории, используйте ключевое слово any. Также можно использовать ключевое слово any, чтобы искать документы без поля категории события.
Например, следующий запрос EQL соответствует любым документам со значением поля network.protocol равным http:
any where network.protocol == "http"
Экранирование категории события
Используйте двойные кавычки (") или тройные двойные кавычки ("""), чтобы экранировать категории событий, которые:
- Содержат специальный символ, такой как дефис (
-) или точка (.) - Содержат пробел
- Начинаются с цифры
".my.event.category" "my-event-category" "my event category" "6eventcategory" """.my.event.category""" """my-event-category""" """my event category""" """6eventcategory"""
Экранирование имени поля
Используйте обратные кавычки (`) для экранирования имён полей, которые:
- Содержат дефис (
-) - Содержат пробел
- Начинаются с цифры
`my-field` `my field` `6myfield`
Используйте двойные обратные кавычки (``), чтобы экранировать любые обратные кавычки (`) в имени поля.
my`field -> `my``field`
Условия
Условие состоит из одного или нескольких критериев, которым должно соответствовать событие. Вы можете указать и объединить эти критерии, используя следующие операторы. Большинство операторов EQL по умолчанию чувствительны к регистру.
Операторы сравнения
< <= == : != >= >
-
<(меньше) - Возвращает
true, если значение слева от оператора меньше значения справа. В противном случае возвращаетfalse. -
<=(меньше или равно) - Возвращает
true, если значение слева от оператора меньше или равно значению справа. В противном случае возвращаетfalse. -
==(равно, чувствительно к регистру) - Возвращает
true, если значения слева и справа от оператора равны. В противном случае возвращаетfalse. Подстановки не поддерживаются. -
:(равно, нечувствительно к регистру) - Возвращает
true, если строки слева и справа от оператора равны. В противном случае возвращаетfalse. Может использоваться только для сравнения строк. Поддерживает подстановки и поиск в списках. -
!=(не равно, чувствительно к регистру) - Возвращает
true, если значения слева и справа от оператора не равны. В противном случае возвращаетfalse. Подстановки не поддерживаются. -
>=(больше или равно) - Возвращает
true, если значение слева от оператора больше или равно значению справа. В противном случае возвращаетfalse. При сравнении строк оператор использует лексикографический порядок, чувствительный к регистру. -
>(больше) - Возвращает
true, если значение слева от оператора больше значения справа. В противном случае возвращаетfalse. При сравнении строк оператор использует лексикографический порядок, чувствительный к регистру.
= не поддерживается как оператор равенства. Используйте == или : вместо него.
Ключевые слова для сравнения шаблонов
my_field like "VALUE*" // case-sensitive wildcard matching my_field like~ "value*" // case-insensitive wildcard matching my_field regex "VALUE[^Z].?" // case-sensitive regex matching my_field regex~ "value[^z].?" // case-insensitive regex matching
-
like(чувствительно к регистру) - Возвращает
true, если строка слева от ключевого слова соответствует шаблону подстановки справа. Поддерживает поиск в списках. Может использоваться только для сравнения строк. Для сравнения строк, нечувствительного к регистру, используйтеlike~. -
regex(чувствительно к регистру) - Возвращает
true, если строка слева от ключевого слова соответствует регулярному выражению справа. Для поддерживаемого синтаксиса регулярных выражений см. Синтаксис регулярных выражений. Поддерживает поиск в списках. Может использоваться только для сравнения строк. Для сравнения строк, нечувствительного к регистру, используйтеregex~.
Ограничения для сравнений
Вы не можете объединять сравнения. Вместо этого используйте логический оператор между сравнениями. Например, foo < bar <= baz не поддерживается. Однако, вы можете переписать выражение как foo < bar and bar <= baz, что поддерживается.
Вы также не можете сравнивать одно поле с другим полем, даже если поля изменены с помощью функции.
Пример
Следующий запрос EQL сравнивает значение поля process.parent_name со статическим значением foo. Это сравнение поддерживается.
Однако, запрос также сравнивает значение поля process.parent.name со значением поля process.name. Это сравнение не поддерживается и вернёт ошибку для всего запроса.
process where process.parent.name == "foo" and process.parent.name == process.name
Вместо этого вы можете переписать запрос, чтобы сравнить оба поля process.parent.name и process.name со статическими значениями.
process where process.parent.name == "foo" and process.name == "foo"
Логические операторы
and or not
-
and - Возвращает
trueтолько если условие слева и справа оба возвращаютtrue. В противном случае возвращаетfalse. -
or - Возвращает
true, если одно из условий слева или справаtrue. В противном случае возвращаетfalse. -
not - Возвращает
true, если условие справаfalse.
Операторы поиска в списках
my_field in ("Value-1", "VALUE2", "VAL3") // case-sensitive
my_field in~ ("value-1", "value2", "val3") // case-insensitive
my_field not in ("Value-1", "VALUE2", "VAL3") // case-sensitive
my_field not in~ ("value-1", "value2", "val3") // case-insensitive
my_field : ("value-1", "value2", "val3") // case-insensitive
my_field like ("Value-*", "VALUE2", "VAL?") // case-sensitive
my_field like~ ("value-*", "value2", "val?") // case-insensitive
my_field regex ("[vV]alue-[0-9]", "VALUE[^2].?", "VAL3") // case-sensitive
my_field regex~ ("value-[0-9]", "value[^2].?", "val3") // case-insensitive -
in(чувствительно к регистру) - Возвращает
true, если значение содержится в предоставленном списке. Для сравнения, нечувствительного к регистру, используйтеin~. -
not in(чувствительно к регистру) - Возвращает
true, если значение не содержится в предоставленном списке. Для сравнения, нечувствительного к регистру, используйтеnot in~. -
:(нечувствительно к регистру) - Возвращает
true, если строка содержится в предоставленном списке. Может использоваться только для сравнения строк. -
like(чувствительно к регистру) - Возвращает
true, если строка соответствует шаблону подстановки в предоставленном списке. Может использоваться только для сравнения строк. Для сравнения, нечувствительного к регистру, используйтеlike~. -
regex(чувствительно к регистру) - Возвращает
true, если строка соответствует шаблону регулярного выражения в предоставленном списке. Для поддерживаемого синтаксиса регулярных выражений см. Синтаксис регулярных выражений. Может использоваться только для сравнения строк. Для сравнения, нечувствительного к регистру, используйтеregex~.
Математические операторы
+ - * / %
-
+(сложение) - Добавляет значения слева и справа от оператора.
-
-(вычитание) - Вычитает значение справа от оператора из значения слева.
-
*(умножение) - Умножает значения слева и справа от оператора.
-
/(деление) -
Делит значение слева от оператора на значение справа.
Если и делимое, и делитель являются целыми числами, операция деления (
\) округляет любые возвращаемые числа с плавающей запятой до ближайшего целого числа вниз. Чтобы избежать округления, преобразуйте либо делимое, либо делитель в число с плавающей запятой.Пример
Полеprocess.args_count— это целое числовое полеlong, содержащее количество аргументов процесса.Пользователь, вероятно, ожидает, что следующий запрос EQL будет соответствовать только событиям со значением поля
process.args_countравным4.process where ( 4 / process.args_count ) == 1
Однако запрос EQL соответствует событиям со значением поля
process.args_countравным либо3, либо4.Для событий со значением поля
process.args_countравным3, операция деления возвращает число с плавающей запятой1.333..., которое округляется до1.Чтобы соответствовать только событиям со значением поля
process.args_countравным4, преобразуйте либо делимое, либо делитель в число с плавающей запятой.Следующий запрос EQL изменяет целое число
4на эквивалентное число с плавающей запятой4.0.process where ( 4.0 / process.args_count ) == 1
-
%(остаток от деления) - Делит значение слева от оператора на значение справа. Возвращает только остаток.
Соответствие любому условию
Чтобы соответствовать событиям только по категории события, используйте условие where true.
Например, следующий запрос EQL соответствует всем событиям file:
file where true
Чтобы соответствовать любому событию, можно объединить ключевое слово any с условием where true:
any where true
Необязательные поля
По умолчанию запрос EQL может содержать только поля, которые существуют в наборе данных, по которому вы выполняете поиск. Поле существует в наборе данных, если оно имеет явное, динамическое или временное сопоставление. Если запрос EQL содержит поле, которого нет, он возвращает ошибку.
Если вы не уверены, существует ли поле в наборе данных, используйте оператор ?, чтобы пометить поле как необязательное. Если необязательное поле не существует, запрос заменяет его значением null вместо возврата ошибки.
Пример
В следующем запросе поле user.id является необязательным.
network where ?user.id != null
Если поле user.id существует в наборе данных, по которому вы выполняете поиск, запрос соответствует всем событиям network, которые содержат значение поля user.id. Если поле user.id не существует в наборе данных, EQL интерпретирует запрос как:
network where null != null
В этом случае запрос не соответствует ни одному событию.
Проверка наличия поля
Чтобы соответствовать событиям, содержащим любое значение для поля, сравните поле с null с помощью оператора !=:
?my_field != null
Чтобы соответствовать событиям, не содержащим значения поля, сравните поле с null с помощью оператора ==:
?my_field == null
Строки
Строки заключены в двойные кавычки (").
"hello world"
Строки в одинарных кавычках (') не поддерживаются.
Символы экранирования в строке
При использовании в строке специальные символы, такие как возврат каретки или двойная кавычка ("), должны быть экранированы предшествующей обратной косой чертой (\).
"example \r of \" escaped \n characters"
| Последовательность экранирования | Литеральный символ |
|---|---|
| Перевод строки (символ новой строки) |
| Возврат каретки |
| Табуляция |
| Обратная косая черта ( |
| Двойная кавычка ( |
Можно экранировать символы Юникода, используя шестнадцатеричную последовательность экранирования \u{XXXXXXXX}. Шестнадцатеричное значение может иметь длину от 2 до 8 символов и регистронезависимо. Значения, длина которых меньше 8 символов, дополняются нулями. Эти последовательности экранирования можно использовать для включения непечатаемых или символов справа налево (RTL) в ваши строки. Например, можно экранировать символ маркировки справа налево (RLM) как \u{200f}, \u{200F} или \u{0000200f}.
Символ одинарной кавычки (') зарезервирован для использования в будущем. Нельзя использовать экранированную одинарную кавычку (\') для литеральных строк. Используйте экранированную двойную кавычку (\").
Необработанные строки
Необработанные строки рассматривают специальные символы, такие как обратные косые черты (\), как литеральные символы. Необработанные строки заключены в три двойные кавычки (""").
"""Raw string with a literal double quote " and blackslash \ included"""
Необработанная строка не может содержать три последовательные двойные кавычки ("""). Вместо этого используйте обычную строку с последовательностью экранирования \".
"String containing \"\"\" three double quotes"
Подстановочные знаки
Для сравнения строк с помощью оператора : или ключевого слова like можно использовать подстановочные знаки * и ? для соответствия определённым шаблонам. Подстановочный знак * соответствует нулю или более символам:
my_field : "doc*" // Matches "doc", "docs", or "document" but not "DOS" my_field : "*doc" // Matches "adoc" or "asciidoc" my_field : "d*c" // Matches "doc" or "disc" my_field like "DOC*" // Matches "DOC", "DOCS", "DOCs", or "DOCUMENT" but not "DOS" my_field like "D*C" // Matches "DOC", "DISC", or "DisC"
Подстановочный знак ? соответствует ровно одному символу:
my_field : "doc?" // Matches "docs" but not "doc", "document", or "DOS" my_field : "?doc" // Matches "adoc" but not "asciidoc" my_field : "d?c" // Matches "doc" but not "disc" my_field like "DOC?" // Matches "DOCS" or "DOCs" but not "DOC", "DOCUMENT", or "DOS" my_field like "D?c" // Matches "DOC" but not "DISC"
Оператор : и ключевое слово like также поддерживают подстановочные знаки в поиске в списках:
my_field : ("doc*", "f*o", "ba?", "qux")
my_field like ("Doc*", "F*O", "BA?", "QUX") Последовательности
Вы можете использовать последовательности EQL для описания и поиска упорядоченной серии событий. Каждый элемент последовательности — это категория события и условие события, заключённые в квадратные скобки ([ ]). События перечислены в хронологическом порядке, начиная с самого последнего.
sequence [ event_category_1 where condition_1 ] [ event_category_2 where condition_2 ] ...
Пример
Следующий запрос EQL по последовательности соответствует следующей серии событий:
-
Начинается с события с:
- Категорией события
file - Значением поля
file.extensionравнымexe
- Категорией события
- За которым следует событие с категорией события
process
sequence [ file where file.extension == "exe" ] [ process where true ]
with maxspan оператор
Вы можете использовать with maxspan, чтобы ограничить последовательность заданным интервалом времени. Все события в соответствующей последовательности должны произойти в течение этого интервала, начиная с временной метки первого события.
maxspan принимает аргументы временных значений.
sequence with maxspan=30s [ event_category_1 where condition_1 ] by field_baz [ event_category_2 where condition_2 ] by field_bar ...
Пример
Следующий запрос по последовательности использует значение maxspan равное 15m (15 минут). События в соответствующей последовательности должны произойти в течение 15 минут с момента временной метки первого события.
sequence with maxspan=15m [ file where file.extension == "exe" ] [ process where true ]
Пропущенные события
Используйте !, чтобы соответствовать пропущенным событиям: событиям в заданном интервале времени, которые не соответствуют заданному условию.
sequence with maxspan=1h [ event_category_1 where condition_1 ] ![ event_category_2 where condition_2 ] [ event_category_3 where condition_3 ] ...
Операторы пропущенных событий могут использоваться в начале, в конце и/или в середине последовательности в любом сочетании с положительными операторами. Последовательность может содержать несколько операторов пропущенных событий, но должна содержать по крайней мере один положительный оператор. with maxspan является обязательным, когда присутствуют операторы пропущенных событий.
Пример
Следующий запрос по последовательности находит события входа в систему, за которыми не следует событие выхода в течение 5 секунд.
sequence by host.name, user.name with maxspan=5s [ authentication where event.code : "4624" ] ![ authentication where event.code : "4647" ]
by ключевое слово
Используйте ключевое слово by в запросе последовательности, чтобы соответствовать только событиям, которые имеют одинаковые значения, даже если эти значения находятся в разных полях. Эти общие значения называются ключами объединения. Если ключ объединения должен находиться в одном и том же поле во всех событиях, используйте sequence by.
sequence by field_foo [ event_category_1 where condition_1 ] by field_baz [ event_category_2 where condition_2 ] by field_bar ...
Пример
Следующий запрос последовательности использует ключевое слово by, чтобы ограничить соответствующие события:
- События с одинаковым значением поля
user.name - События с значением поля
file, равным значению поляfile.pathследующего событияprocess.
sequence [ file where file.extension == "exe" ] by user.name, file.path [ process where true ] by user.name, process.executable
Поскольку поле user.name общее для всех событий в последовательности, его можно включить, используя sequence by. Следующая последовательность эквивалентна предыдущей.
sequence by user.name [ file where file.extension == "exe" ] by file.path [ process where true ] by process.executable
Вы можете объединить sequence by и with maxspan, чтобы ограничить последовательность как значениями полей, так и временным интервалом.
sequence by field_foo with maxspan=30s [ event_category_1 where condition_1 ] [ event_category_2 where condition_2 ] ...
Пример
Следующий запрос последовательности использует sequence by и with maxspan, чтобы соответствовать только последовательности событий, которые:
- Имеют одинаковые значения поля
user.name - Происходят в течение
15m(15 минут) от первого соответствующего события
sequence by user.name with maxspan=15m [ file where file.extension == "exe" ] [ process where true ]
Дополнительные поля by
По умолчанию ключ объединения должен быть значением поля, которое не является null. Для разрешения null ключей объединения используйте оператор ? для обозначения поля by как необязательное. Это также полезно, если вы не уверены, содержит ли анализируемый вами набор данных поле by.
Пример
Следующий запрос последовательности использует sequence by для ограничения соответствующих событий до:
- Событий с одинаковым значением поля
process.pid, исключаяnullзначения. Если полеprocess.pidотсутствует в анализируемом наборе данных, запрос возвращает ошибку. - Событий с одинаковым значением поля
process.entity_id, включаяnullзначения. Если событие не содержит полеprocess.entity_id, его значение поляprocess.entity_idсчитаетсяnull. Это относится даже в том случае, если полеprocess.pidотсутствует в анализируемом наборе данных.
sequence by process.pid, ?process.entity_id [process where process.name == "regsvr32.exe"] [network where true]
Ключевое слово until
Вы можете использовать ключевое слово until, чтобы указать событие истечения срока действия для последовательности. Если это событие истечения срока действия происходит между соответствующими событиями в последовательности, последовательность истекает и не считается совпадением. Если событие истечения срока действия происходит после соответствующих событий в последовательности, последовательность все еще считается совпадением. Событие истечения срока действия не включается в результаты.
sequence [ event_category_1 where condition_1 ] [ event_category_2 where condition_2 ] ... until [ event_category_3 where condition_3 ]
Пример
В наборе данных содержатся следующие последовательности событий, сгруппированные по общим идентификаторам:
A, B A, B, C A, C, B
Следующий запрос EQL ищет в наборе данных последовательности, содержащие событие A, за которым следует событие B. Событие C используется как событие истечения срока действия.
sequence by ID A B until C
Запрос соответствует последовательностям A, B и A, B, C, но не A, C, B.
Ключевое слово until может быть полезным при поиске последовательностей процессов в журнале событий Windows.
В Windows идентификатор процесса (PID) уникален только во время работы процесса. После завершения процесса его PID может быть повторно использован.
Вы можете искать последовательность событий с одинаковым значением PID, используя ключевые слова by и sequence by.
Пример
Следующий запрос EQL использует ключевое слово sequence by, чтобы соответствовать последовательности событий, которые имеют одинаковое значение поля process.pid.
sequence by process.pid [ process where event.type == "start" and process.name == "cmd.exe" ] [ process where file.extension == "exe" ]
Однако из-за повторного использования PID это может привести к совпадению последовательности, содержащей события от разных процессов. Чтобы предотвратить ложные срабатывания, вы можете использовать ключевое слово until, чтобы завершить последовательности соответствия до события завершения процесса.
Следующий запрос EQL использует ключевое слово until, чтобы завершить последовательности до событий process со значением поля event.type равным stop. Эти события указывают на то, что процесс был завершён.
sequence by process.pid [ process where event.type == "start" and process.name == "cmd.exe" ] [ process where file.extension == "exe" ] until [ process where event.type == "stop" ]
Выражение with runs
Используйте выражение with runs, чтобы последовательно выполнять те же критерии событий в запросе последовательности. Например:
sequence [ process where event.type == "creation" ] [ library where process.name == "regsvr32.exe" ] with runs=3 [ registry where true ]
эквивалентно:
sequence [ process where event.type == "creation" ] [ library where process.name == "regsvr32.exe" ] [ library where process.name == "regsvr32.exe" ] [ library where process.name == "regsvr32.exe" ] [ registry where true ]
Значение runs должно находиться в диапазоне от 1 до 100 (включительно).
Вы можете использовать выражение with runs с ключевым словом by. Например:
sequence [ process where event.type == "creation" ] by process.executable [ library where process.name == "regsvr32.exe" ] by dll.path with runs=3
Примеры
Вы можете использовать примеры EQL для описания и сопоставления хронологически неупорядоченного ряда событий. Все события в примере имеют одинаковое значение для одного или нескольких полей, которые указываются с помощью ключевого слова by (ключи объединения). Каждый элемент в примере — это категория события и условие события, заключенные в квадратные скобки ([ ]). События перечислены в порядке соответствия фильтрам.
sample by join_key [ event_category_1 where condition_1 ] [ event_category_2 where condition_2 ] ...
Пример
Следующий запрос EQL с помощью примера возвращает до 10 примеров с уникальными значениями для host. Каждый пример состоит из двух событий:
-
Начинается с события с:
- Категорией события
file - Значением поля
file.extensionравнымexe
- Категорией события
- За которым следует событие с категорией события
process
sample by host [ file where file.extension == "exe" ] [ process where true ]
Запросы с примерами не учитывают хронологический порядок событий. Выражения with maxspan и with runs, а также ключевое слово until не поддерживаются.
Функции
Вы можете использовать функции EQL для преобразования типов данных, выполнения математических операций, обработки строк и т. д. Список поддерживаемых функций см. в Справочнике по функциям.
Функции, нечувствительные к регистру
Большинство функций EQL по умолчанию чувствительны к регистру. Чтобы сделать функцию нечувствительной к регистру, используйте оператор ~ после имени функции:
stringContains(process.name,".exe") // Matches ".exe" but not ".EXE" or ".Exe" stringContains~(process.name,".exe") // Matches ".exe", ".EXE", or ".Exe"
Влияние функций на производительность поиска
Использование функций в запросах EQL может привести к замедлению скорости поиска. Если вы часто используете функции для преобразования индексированных данных, вы можете ускорить поиск, выполнив эти изменения во время индексирования вместо этого. Однако это часто означает замедление скорости индексирования.
Пример
Индекс содержит поле file.path. file.path содержит полный путь к файлу, включая расширение файла.
При выполнении поисковых запросов EQL пользователи часто используют функцию endsWith с полем file.path для сопоставления расширений файлов:
file where endsWith(file.path,".exe") or endsWith(file.path,".dll")
Хотя это работает, это может быть повторяющимся действием и может замедлить скорость поиска. Чтобы ускорить поиск, вы можете сделать следующее вместо этого:
- Добавьте новое поле,
file.extension, в индекс. Полеfile.extensionбудет содержать только расширение файла из поляfile.path. - Используйте конвейер загрузки с процессором
grokили другим инструментом предподготовки для извлечения расширения файла из поляfile.pathперед индексированием. - Индексируйте извлеченное расширение файла в поле
file.extension.
Эти изменения могут замедлить индексирование, но позволяют ускорить поиск. Пользователи могут использовать поле file.extension вместо нескольких вызовов функции endsWith:
file where file.extension in ("exe", "dll") Мы рекомендуем проверить и выполнить тестирование производительности любых изменений в индексировании перед развертыванием их в рабочей среде. См. Настройка для скорости индексирования и Настройка для скорости поиска.
Трубы
Трубы EQL фильтруют, агрегируют и пост-обрабатывают события, возвращаемые запросом EQL. Вы можете использовать трубы для сужения результатов запроса EQL или для повышения их специфичности.
Трубы разделяются символом (|).
event_category where condition | pipe
Пример
Следующий запрос EQL использует трубу tail для возврата только 10 самых последних событий, соответствующих запросу.
authentication where agent.id == 4624 | tail 10
Вы можете передать вывод одной команды обработки данных в другую. Это позволяет использовать несколько команд обработки данных с одним запросом.
Список поддерживаемых команд обработки данных см. в Справочнике по командам обработки данных.
Ограничения
EQL имеет следующие ограничения.
EQL использует параметр fields
EQL извлекает значения полей с помощью параметра fields API поиска. Любые ограничения на параметр fields также применяются к запросам EQL. Например, если параметр _source отключен для любого возвращаемого поля или на уровне индекса, значения получить невозможно.
Сравнение полей
Вы не можете использовать операторы сравнения EQL для сравнения одного поля с другим. Это относится даже в том случае, если поля изменены с помощью функции.
Поля типа текста не поддерживаются
Поиск EQL не поддерживает поля типа text. Чтобы выполнить поиск по полю типа text, используйте параметр Query DSL filter API поиска EQL.
Поиск EQL по вложенным полям
Вы не можете использовать EQL для поиска значений поля типа nested или подполей поля nested. Однако потоки данных и индексы, содержащие соответствия nested, в остальном поддерживаются.
Отличия от синтаксиса Endgame EQL
Синтаксис EQL Elasticsearch отличается от синтаксиса Endgame EQL следующим образом:
- В Elasticsearch EQL большинство операторов чувствительны к регистру. Например,
process_name == "cmd.exe"не эквивалентноprocess_name == "Cmd.exe". - В Elasticsearch EQL функции чувствительны к регистру. Чтобы сделать функцию нечувствительной к регистру, используйте
~, напримерendsWith~(process_name, ".exe"). - Для сравнения на равенство без учета регистра используйте оператор
:.*и?— это символы подстановки. - Операторы
==и!=не расширяют символы подстановки. Например,process_name == "cmd*.exe"интерпретирует*как буквенную звездочку, а не как символ подстановки. - Для сопоставления с символами подстановки используйте ключевое слово
likeпри чувствительности к регистру иlike~при отсутствии чувствительности к регистру. Оператор:эквивалентенlike~. - Для сопоставления с регулярными выражениями используйте
regexилиregex~. -
=нельзя заменить оператором==. - Строки в одинарных кавычках (
') не поддерживаются. Используйте двойные кавычки ("). -
?"и?'не обозначают сырые строки. Используйте тройные двойные кавычки ("""). Elasticsearch EQL не поддерживает:
Функции массивов:
- Функцию
match - Объединения
Ключевые слова, связанные с происхождением событий:
child ofdescendant ofevent of
Следующие команды обработки данных:
Как запросы последовательности обрабатывают совпадения
Запросы последовательностей не находят все потенциальные совпадения для последовательности. Этот подход слишком медленный и дорогостоящий для больших наборов данных событий. Вместо этого запрос последовательности обрабатывает ожидающие совпадения последовательности как конечный автомат:
- Каждый элемент события в запросе последовательности является состоянием в автомате.
- Только одна ожидающая последовательность может находиться в каждом состоянии одновременно.
- Если две ожидающие последовательности находятся в одном состоянии одновременно, последняя последовательность перезаписывает предыдущую.
- Если запрос включает
byполя, запрос использует отдельный конечный автомат для каждого уникального значения поляby.
Пример
Набор данных содержит следующие события process в порядке возрастания хронологического времени:
{ "index" : { "_id": "1" } }
{ "user": { "name": "root" }, "process": { "name": "attrib" }, ...}
{ "index" : { "_id": "2" } }
{ "user": { "name": "root" }, "process": { "name": "attrib" }, ...}
{ "index" : { "_id": "3" } }
{ "user": { "name": "elkbee" }, "process": { "name": "bash" }, ...}
{ "index" : { "_id": "4" } }
{ "user": { "name": "root" }, "process": { "name": "bash" }, ...}
{ "index" : { "_id": "5" } }
{ "user": { "name": "root" }, "process": { "name": "bash" }, ...}
{ "index" : { "_id": "6" } }
{ "user": { "name": "elkbee" }, "process": { "name": "attrib" }, ...}
{ "index" : { "_id": "7" } }
{ "user": { "name": "root" }, "process": { "name": "attrib" }, ...}
{ "index" : { "_id": "8" } }
{ "user": { "name": "elkbee" }, "process": { "name": "bash" }, ...}
{ "index" : { "_id": "9" } }
{ "user": { "name": "root" }, "process": { "name": "cat" }, ...}
{ "index" : { "_id": "10" } }
{ "user": { "name": "elkbee" }, "process": { "name": "cat" }, ...}
{ "index" : { "_id": "11" } }
{ "user": { "name": "root" }, "process": { "name": "cat" }, ...} Запрос последовательности EQL выполняет поиск в наборе данных:
sequence by user.name [process where process.name == "attrib"] [process where process.name == "bash"] [process where process.name == "cat"]
Элементы события запроса соответствуют следующим состояниям:
- Состояние A:
[process where process.name == "attrib"] - Состояние B:
[process where process.name == "bash"] - Завершено:
[process where process.name == "cat"]
Для поиска совпадающих последовательностей запрос использует отдельные конечные автоматы для каждого уникального значения user.name. Основываясь на наборе данных, вы можете ожидать два конечных автомата: один для пользователя root и один для elkbee.
Ожидающие совпадения последовательностей перемещаются по состояниям каждого автомата следующим образом:
{ "index" : { "_id": "1" } }
{ "user": { "name": "root" }, "process": { "name": "attrib" }, ...}
// Creates sequence [1] in state A for the "root" user.
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | [1] | | | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "2" } }
{ "user": { "name": "root" }, "process": { "name": "attrib" }, ...}
// Creates sequence [2] in state A for "root", overwriting sequence [1].
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | [2] | | | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "3" } }
{ "user": { "name": "elkbee" }, "process": { "name": "bash" }, ...}
// Nothing happens. The "elkbee" user has no pending sequence to move
// from state A to state B.
//
// +-----------------------"elkbee"-----------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | | | | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "4" } }
{ "user": { "name": "root" }, "process": { "name": "bash" }, ...}
// Sequence [2] moves out of state A for "root".
// State B for "root" now contains [2, 4].
// State A for "root" is empty.
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ --> +-----------+ +------------+ |
// | | | | [2, 4] | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "5" } }
{ "user": { "name": "root" }, "process": { "name": "bash" }, ...}
// Nothing happens. State A is empty for "root".
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | | | [2, 4] | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "6" } }
{ "user": { "name": "elkbee" }, "process": { "name": "attrib" }, ...}
// Creates sequence [6] in state A for "elkbee".
//
// +-----------------------"elkbee"-----------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | [6] | | | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "7" } }
{ "user": { "name": "root" }, "process": { "name": "attrib" }, ...}
// Creates sequence [7] in state A for "root".
// Sequence [2, 4] remains in state B for "root".
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | [7] | | [2, 4] | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "8" } }
{ "user": { "name": "elkbee" }, "process": { "name": "bash" }, ...}
// Sequence [6, 8] moves to state B for "elkbee".
// State A for "elkbee" is now empty.
//
// +-----------------------"elkbee"-----------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ --> +-----------+ +------------+ |
// | | | | [6, 8] | | | |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "9" } }
{ "user": { "name": "root" }, "process": { "name": "cat" }, ...}
// Sequence [2, 4, 9] is complete for "root".
// State B for "root" is now empty.
// Sequence [7] remains in state A.
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ --> +------------+ |
// | | [7] | | | | [2, 4, 9] |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "10" } }
{ "user": { "name": "elkbee" }, "process": { "name": "cat" }, ...}
// Sequence [6, 8, 10] is complete for "elkbee".
// State A and B for "elkbee" are now empty.
//
// +-----------------------"elkbee"-----------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ --> +------------+ |
// | | | | | | [6, 8, 10] |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
{ "index" : { "_id": "11" } }
{ "user": { "name": "root" }, "process": { "name": "cat" }, ...}
// Nothing happens.
// The machines for "root" and "elkbee" remain the same.
//
// +------------------------"root"------------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | [7] | | | | [2, 4, 9] |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
//
// +-----------------------"elkbee"-----------------------+
// | +-----------+ +-----------+ +------------+ |
// | | State A | | State B | | Complete | |
// | +-----------+ +-----------+ +------------+ |
// | | | | | | [6, 8, 10] |
// | +-----------+ +-----------+ +------------+ |
// +------------------------------------------------------+
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/eql-syntax.html