8.4.5.8 Написание определений фильтров аудита журнала
Определения фильтров являются JSON значениями. Для получения информации об использовании JSON данных в MySQL см. Раздел 13.5, «Тип данных JSON».
Определения фильтров имеют следующий вид, где actions указывает, как выполняется фильтрация:
{ "filter": actions }
Следующее обсуждение описывает разрешенные конструкции в определениях фильтров.
Ведение журнала всех событий
Чтобы явно включить или отключить ведение журнала всех событий, используйте элемент log в фильтре:
{
"filter": { "log": true }
}
Значение log может быть либо true, либо false.
Предшествующий фильтр включает ведение журнала всех событий. Он эквивалентен:
{
"filter": { }
}
Поведение ведения журнала зависит от значения log и наличия элементов class или event:
При указании
logиспользуется его заданное значение.Без указания
logведение журнала включено, если не указаны элементыclassилиevent, и выключено в противном случае (в этом случаеclassилиeventмогут включать свой собственный элементlog).
Ведение журнала определенных классов событий
Чтобы вести журнал событий определенного класса, используйте элемент class в фильтре, где поле name обозначает имя класса для ведения журнала:
{
"filter": {
"class": { "name": "connection" }
}
}
Значение name может быть connection, general или table_access для ведения журнала событий подключения, общих или доступа к таблицам соответственно.
Предшествующий фильтр включает ведение журнала событий в классе connection. Он эквивалентен следующему фильтру с явными элементами log:
{
"filter": {
"log": false,
"class": { "log": true,
"name": "connection" }
}
}
Для включения ведения журнала нескольких классов определите значение class как элемент массива JSON, который называет классы:
{
"filter": {
"class": [
{ "name": "connection" },
{ "name": "general" },
{ "name": "table_access" }
]
}
}
Когда несколько экземпляров данного элемента появляются на одном уровне в определении фильтра, значения элементов могут быть объединены в один экземпляр этого элемента в значении массива. Предшествующее определение можно записать так:
{
"filter": {
"class": [
{ "name": [ "connection", "general", "table_access" ] }
]
}
}
Регистрация конкретных подклассов событий
Для выбора конкретных подклассов событий используйте элемент event, содержащий элемент name, который указывает имена подклассов. По умолчанию события, выбранные элементом event, регистрируются. Например, этот фильтр позволяет регистрировать события для указанных подклассов:
{
"filter": {
"class": [
{
"name": "connection",
"event": [
{ "name": "connect" },
{ "name": "disconnect" }
]
},
{ "name": "general" },
{
"name": "table_access",
"event": [
{ "name": "insert" },
{ "name": "delete" },
{ "name": "update" }
]
}
]
}
}
Элемент event также может содержать явные элементы log для указания, следует ли регистрировать соответствующие события. Этот элемент event выбирает несколько событий и явно указывает поведение регистрации для них:
"event": [
{ "name": "read", "log": false },
{ "name": "insert", "log": true },
{ "name": "delete", "log": true },
{ "name": "update", "log": true }
]
Элемент event также может указывать, следует ли блокировать соответствующие события, если он содержит элемент abort. Подробнее см. Блокирование выполнения определенных событий.
Таблица 8.35, «Сочетания классов и подклассов событий» описывает разрешённые значения подклассов для каждого класса событий.
Таблица 8.35 Сочетания классов и подклассов событий
| Класс события | Подкласс события | Описание |
|---|---|---|
connection | connect | Инициализация соединения (успешная или неуспешная) |
connection | change_user | Повторная аутентификация пользователя с другими пользователем/паролем во время сессии |
connection | disconnect | Завершение соединения |
general | status | Общая информация об операциях |
message | internal | Внутренне сгенерированное сообщение |
message | user | Сообщение, сгенерированное функцией audit_api_message_emit_udf()
|
table_access | read | Выражения чтения таблицы, такие как SELECT или INSERT
INTO ... SELECT
|
table_access | delete | Выражения удаления таблицы, такие как DELETE или TRUNCATE TABLE
|
table_access | insert | Выражения вставки в таблицу, такие как INSERT или REPLACE
|
table_access | update | Выражения обновления таблицы, такие как UPDATE
|
Таблица 8.36, «Характеристики регистрации и прерывания по сочетанию класса и подкласса события» описывает, можно ли регистрировать или прерывать каждый подкласс события.
Таблица 8.36 Характеристики регистрации и прерывания по сочетанию класса и подкласса события
| Класс события | Подкласс события | Можно регистрировать | Можно прервать |
|---|---|---|---|
connection | connect | Да | Нет |
connection | change_user | Да | Нет |
connection | disconnect | Да | Нет |
general | status | Да | Нет |
message | internal | Да | Да |
message | user | Да | Да |
table_access | read | Да | Да |
table_access | delete | Да | Да |
table_access | insert | Да | Да |
table_access | update | Да | Да |
Регистрация по включению и исключению
Фильтр может быть определён в режиме включения или исключения:
Режим включения регистрирует только явным образом указанные элементы.
Режим исключения регистрирует всё, кроме явным образом указанных элементов.
Для выполнения регистрации по включению отключите регистрацию глобально и включите её для конкретных классов. Этот фильтр регистрирует события connect и disconnect в классе connection, а также события в классе general:
{
"filter": {
"log": false,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": true },
{ "name": "disconnect", "log": true }
]
},
{ "name": "general", "log": true }
]
}
}
Для выполнения регистрации по исключению включите регистрацию глобально и отключите её для конкретных классов. Этот фильтр регистрирует всё, кроме событий в классе general:
{
"filter": {
"log": true,
"class":
{ "name": "general", "log": false }
}
}
Этот фильтр регистрирует события change_user в классе connection, события message и события table_access, так как он не регистрирует всё остальное:
{
"filter": {
"log": true,
"class": [
{
"name": "connection",
"event": [
{ "name": "connect", "log": false },
{ "name": "disconnect", "log": false }
]
},
{ "name": "general", "log": false }
]
}
}
Значения полей событий тестирования
Для включения регистрации, основанной на определённых значениях полей события, укажите элемент field внутри элемента log, который указывает имя поля и ожидаемое значение:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"field": { "name": "general_command.str", "value": "Query" }
}
}
}
}
}
Каждое событие содержит поля, специфичные для класса события, к которым можно получить доступ внутри фильтра для выполнения пользовательской фильтрации.
Событие в классе connection указывает на то, что происходит активность, связанная с подключением, во время сессии, например, пользователь подключается или отключается от сервера. Таблица 8.37, «Поля событий подключения» указывает допустимые поля для событий connection.
Таблица 8.37 Поля событий подключения
| Имя поля | Тип поля | Описание |
|---|---|---|
status | целое число |
Состояние события: 0: OK В противном случае: Ошибка |
connection_id | беззнаковое целое число | Идентификатор подключения |
user.str | строка | Имя пользователя, указанное во время аутентификации |
user.length | беззнаковое целое число | Длина имени пользователя |
priv_user.str | строка | Имя аутентифицированного пользователя (имя пользователя учётной записи) |
priv_user.length | беззнаковое целое число | Длина имени аутентифицированного пользователя |
external_user.str | строка | Внешнее имя пользователя (предоставленное плагином аутентификации сторонних разработчиков) |
external_user.length | беззнаковое целое число | Длина внешнего имени пользователя |
proxy_user.str | строка | Имя пользователя прокси |
proxy_user.length | беззнаковое целое число | Длина имени пользователя прокси |
host.str | строка | Хост подключённого пользователя |
host.length | беззнаковое целое число | Длина хоста подключённого пользователя |
ip.str | строка | IP-адрес подключённого пользователя |
ip.length | беззнаковое целое число | Длина IP-адреса подключённого пользователя |
database.str | строка | Имя базы данных, указанное при подключении |
database.length | беззнаковое целое число | Длина имени базы данных |
connection_type | целое число |
Тип подключения: 0 или 1 или 2 или 3 или 4 или 5 или |
Значения ":: — это символические псевдоконстанты, которые могут быть указаны вместо числовых значений. Они должны быть представлены в виде строк и чувствительны к регистру. xxx"
Событие в классе general указывает код состояния операции и её подробности. Таблица 8.38, «Поля событий общего назначения» указывает допустимые поля для событий general.
Таблица 8.38 Поля событий общего назначения
| Имя поля | Тип поля | Описание |
|---|---|---|
general_error_code | целое число |
Состояние события: 0: OK В противном случае: Ошибка |
general_thread_id | беззнаковое целое число | Идентификатор подключения/потока |
general_user.str | строка | Имя пользователя, указанное во время аутентификации |
general_user.length | беззнаковое целое число | Длина имени пользователя |
general_command.str | строка | Имя команды |
general_command.length | беззнаковое целое число | Длина имени команды |
general_query.str | строка | Текст SQL-запроса |
general_query.length | беззнаковое целое число | Длина текста SQL-запроса |
general_host.str | строка | Имя хоста |
general_host.length | беззнаковое целое число | Длина имени хоста |
general_sql_command.str | строка | Имя типа SQL-команды |
general_sql_command.length | беззнаковое целое число | Длина имени типа SQL-команды |
general_external_user.str | строка | Внешнее имя пользователя (предоставленное плагином аутентификации сторонних разработчиков) |
general_external_user.length | беззнаковое целое число | Длина внешнего имени пользователя |
general_ip.str | строка | IP-адрес подключённого пользователя |
general_ip.length | беззнаковое целое число | Длина IP-адреса подключённого пользователя |
general_command.str указывает имя команды: Query, Execute, Quit или Change user.
Событие general с полем general_command.str, установленным на Query или Execute, содержит general_sql_command.str, установленное на значение, которое определяет тип SQL-команды: alter_db, alter_db_upgrade, admin_commands и так далее. Доступные значения general_sql_command.str можно увидеть как последние компоненты инструментов Performance Schema, отображаемые данным запросом:
mysql> SELECT NAME FROM performance_schema.setup_instruments
WHERE NAME LIKE 'statement/sql/%' ORDER BY NAME;
+---------------------------------------+
| NAME |
+---------------------------------------+
| statement/sql/alter_db |
| statement/sql/alter_db_upgrade |
| statement/sql/alter_event |
| statement/sql/alter_function |
| statement/sql/alter_instance |
| statement/sql/alter_procedure |
| statement/sql/alter_server |
...
Событие в классе table_access содержит информацию о специфическом типе доступа к таблице. Таблица 8.39, «Поля событий доступа к таблицам» указывает допустимые поля для событий table_access.
Таблица 8.39 Поля событий доступа к таблицам
| Имя поля | Тип поля | Описание |
|---|---|---|
connection_id | беззнаковое целое число | Идентификатор подключения события |
sql_command_id | целое число | Идентификатор SQL-команды |
query.str | строка | Текст SQL-запроса |
query.length | беззнаковое целое число | Длина текста SQL-запроса |
table_database.str | строка | Имя базы данных, связанное с событием |
table_database.length | беззнаковое целое число | Длина имени базы данных |
table_name.str | строка | Имя таблицы, связанное с событием |
table_name.length | беззнаковое целое число | Длина имени таблицы |
В следующем списке показано, какие запросы генерируют какие события доступа к таблицам:
-
Событие
read:SELECTINSERT ... SELECT(для таблиц, упомянутых в предложенииSELECT)REPLACE ... SELECT(для таблиц, упомянутых в предложенииSELECT)UPDATE ... WHERE(для таблиц, упомянутых в предложенииWHERE)HANDLER ... READ
-
Событие
delete:DELETETRUNCATE TABLE
-
Событие
insert:INSERTINSERT ... SELECT(для таблицы, упомянутой в предложенииINSERT)REPLACEREPLACE ... SELECT(для таблицы, упомянутой в предложенииREPLACE)LOAD DATALOAD XML
-
Событие
update:UPDATEUPDATE ... WHERE(для таблиц, упомянутых в предложенииUPDATE)
Блокирование выполнения определенных событий
Элементы могут включать элемент, указывающий, следует ли предотвращать выполнение соответствующих событий. Это позволяет создавать правила, блокирующие выполнение определенных SQL-запросов.
Теоретически пользователь с достаточными правами может ошибочно создать элемент фильтрации журнала аудита, который предотвращает доступ к системе себе и другим администраторам. Привилегия AUDIT_ABORT_EXEMPT позволяет запросам учетной записи пользователя всегда выполняться, даже если элемент abort будет их блокировать. Таким образом, учетные записи с этим правом могут быть использованы для восстановления доступа к системе после неправильной настройки аудита. Запрос всё равно записывается в журнале аудита, но вместо отклонения он разрешается благодаря этому привилегии.
Учетные записи, созданные с привилегией SYSTEM_USER, автоматически получают привилегию AUDIT_ABORT_EXEMPT при создании. Привилегия AUDIT_ABORT_EXEMPT также назначается существующим учетным записям с привилегией SYSTEM_USER при выполнении процедуры обновления, если у них еще нет этой привилегии.
Элемент abort должен появляться внутри элемента event. Например:
"event": {
"name": qualifying event subclass names
"abort": condition
}
Для подклассов событий, выбранных элементом name, действие abort равно true или false, в зависимости от оценки condition. Если условие оценивается как true, событие блокируется. В противном случае событие продолжает выполняться.
Спецификация condition может быть простой, такой как true или false, или более сложной, так что оценка зависит от характеристик события.
Этот фильтр блокирует INSERT, UPDATE и DELETE операторы:
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [ "insert", "update", "delete" ],
"abort": true
}
}
}
}
Этот более сложный фильтр блокирует те же операторы, но только для определённой таблицы (finances.bank_account):
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [ "insert", "update", "delete" ],
"abort": {
"and": [
{ "field": { "name": "table_database.str", "value": "finances" } },
{ "field": { "name": "table_name.str", "value": "bank_account" } }
]
}
}
}
}
}
Запросы, соответствующие фильтру и заблокированные им, возвращают ошибку клиенту:
ERROR 1045 (28000): Statement was aborted by an audit log filter
Не все события могут быть заблокированы (см. Таблица 8.36, «Логирование и приостановление по сочетаниям классов и подклассов событий»). Для событий, которые нельзя заблокировать, журнал аудита записывает предупреждение в журнал ошибок, а не блокирует их.
При попытке определить фильтр, в котором элемент abort появляется где-либо, кроме элемента event, возникает ошибка.
Логические операторы
Логические операторы (and, or, not) позволяют строить сложные условия, что обеспечивает более сложные настройки фильтрации.
Следующий элемент log регистрирует только события general с полями general_command, имеющими определённое значение и длину:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"or": [
{
"and": [
{ "field": { "name": "general_command.str", "value": "Query" } },
{ "field": { "name": "general_command.length", "value": 5 } }
]
},
{
"and": [
{ "field": { "name": "general_command.str", "value": "Execute" } },
{ "field": { "name": "general_command.length", "value": 7 } }
]
}
]
}
}
}
}
}
Ссылка на предопределенные переменные
Для ссылки на предопределённую переменную в условии log используйте элемент variable, который принимает элементы name и value и проверяет равенство именованной переменной заданному значению:
"variable": {
"name": "variable_name",
"value": comparison_value
}
Это верно, если variable_name имеет значение comparison_value, и ложно в противном случае.
Пример:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"variable": {
"name": "audit_log_connection_policy_value",
"value": "::none"
}
}
}
}
}
}
Каждая предопределённая переменная соответствует системной переменной. Написав фильтр, проверяющий предопределённую переменную, можно изменить работу фильтра, установив соответствующую системную переменную, не переопределяя сам фильтр. Например, написав фильтр, проверяющий значение предопределённой переменной audit_log_connection_policy_value, можно изменить работу фильтра, изменив значение системной переменной audit_log_connection_policy.
Системные переменные audit_log_ используются для устаревшего режима журнала аудита (см. Раздел 8.4.5.10, «Фильтрация журнала аудита в режиме обратной совместимости»). В режиме фильтрации журнала аудита на основе правил эти переменные остаются видимыми (например, с помощью xxx_policySHOW
VARIABLES), но изменения в них не имеют эффекта, пока не будут написаны фильтры, содержащие конструкции, которые ссылаются на них.
Следующий список описывает разрешённые предопределённые переменные для элементов variable:
-
audit_log_connection_policy_valueЭта переменная соответствует значению системной переменной
audit_log_connection_policy. Значение — целое без знака. Таблица 8.40, «Значения audit_log_connection_policy_value» показывает разрешённые значения и соответствующие значенияaudit_log_connection_policy.Таблица 8.40 Значения audit_log_connection_policy_value
Таблица 8.40 Значения audit_log_connection_policy_value Значение Соответствующее значение audit_log_connection_policy 0или"::none"NONE1или"::errors"ERRORS2или"::all"ALL
Значения
"::— символические псевдоконстанты, которые можно использовать вместо числовых значений. Они должны быть приведены в виде строк и чувствительны к регистру.xxx" -
audit_log_policy_valueЭта переменная соответствует значению системной переменной
audit_log_policy. Значение — целое без знака. Таблица 8.41, «Значения audit_log_policy_value» показывает разрешённые значения и соответствующие значенияaudit_log_policy....Значения
"::— символические псевдоконстанты, которые можно использовать вместо числовых значений. Они должны быть приведены в виде строк и чувствительны к регистру.xxx" - ...
Использование предопределенных функций
Для ссылки на предопределённую функцию в условии log, используйте элемент function, который принимает элементы name и args для указания имени функции и её аргументов соответственно:
"function": {
"name": "function_name",
"args": arguments
}
Элемент name должен содержать только имя функции без скобок или списка аргументов.
Элемент args должен удовлетворять этим условиям:
Если функция не принимает аргументы, элемент
argsне должен быть указан.Если функция принимает аргументы, необходим элемент
args, и аргументы должны быть указаны в порядке, указанном в описании функции. Аргументы могут ссылаться на предопределённые переменные, поля событий или строковые или числовые константы.
Если количество аргументов неверное или типы аргументов не соответствуют требованиям функции, возникает ошибка.
Пример:
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"log": {
"function": {
"name": "find_in_include_list",
"args": [ { "string": [ { "field": "user.str" },
{ "string": "@"},
{ "field": "host.str" } ] } ]
}
}
}
}
}
}
Предыдущий фильтр определяет, следует ли регистрировать события класса general status в зависимости от того, найден ли текущий пользователь в системной переменной audit_log_include_accounts. Этот пользователь конструируется с помощью полей в событии.
В следующем списке описаны разрешённые предопределённые функции для элементов function:
-
audit_log_exclude_accounts_is_null()Проверяет, является ли системная переменная
audit_log_exclude_accountsNULL. Эта функция может быть полезна при определении фильтров, соответствующих реализации журнала аудита старой версии.Аргументы:
Нет.
-
audit_log_include_accounts_is_null()Проверяет, является ли системная переменная
audit_log_include_accountsNULL. Эта функция может быть полезна при определении фильтров, соответствующих реализации журнала аудита старой версии.Аргументы:
Нет.
-
debug_sleep(millisec)Засыпает на указанное количество миллисекунд. Эта функция используется при измерении производительности.
debug_sleep()доступна только для отладочных сборок.Аргументы:
millisec: Беззнаковое целое число, определяющее количество миллисекунд для засыпания.
-
find_in_exclude_list(account)Проверяет, существует ли строка учётной записи в списке исключений журнала аудита (значение системной переменной
audit_log_exclude_accounts).Аргументы:
account: Строка, определяющая имя пользователя учётной записи.
-
find_in_include_list(account)Проверяет, существует ли строка учётной записи в списке включений журнала аудита (значение системной переменной
audit_log_include_accounts).Аргументы:
account: Строка, определяющая имя пользователя учётной записи.
-
query_digest([str])Поведение этой функции зависит от наличия аргумента:
Без аргумента,
query_digestвозвращает значение дайджеста утверждения, соответствующего тексту утверждения в текущем событии.С аргументом,
query_digestвозвращает булево значение, указывающее, равно ли аргумент текущему дайджесту утверждения.
Аргументы:
str: Этот аргумент необязателен. Если указан, он задаёт дайджест утверждения для сравнения с дайджестом утверждения в текущем событии.
Примеры:
Этот элемент
functionне содержит аргумента, поэтомуquery_digestвозвращает текущий дайджест утверждения в виде строки:"function": { "name": "query_digest" }Этот элемент
functionсодержит аргумент, поэтомуquery_digestвозвращает булево значение, указывающее, равно ли аргумент текущему дайджесту утверждения:"function": { "name": "query_digest", "args": "SELECT ?" } -
string_find(text, substr)Проверяет, содержится ли значение
substrв значенииtext. Этот поиск учитывает регистр.Аргументы:
text: Искомая строка текста.substr: Подстрока для поиска вtext.
Замена значений полей событий
Определения фильтров аудита поддерживают замену определённых полей событий аудита, чтобы записанные события содержали значение замены вместо исходного значения. Эта возможность позволяет записанным записям аудита включать дайджесты утверждений, а не буквальные утверждения, что может быть полезно для развертываний MySQL, в которых утверждения могут раскрывать конфиденциальные значения.
Замена полей в событиях аудита работает следующим образом:
Замена полей задаётся в определениях фильтров аудита, поэтому фильтрация журнала аудита должна быть включена, как описано в разделе 8.4.5.7 «Фильтрация журнала аудита».
-
Не все поля могут быть заменены. В таблице 8.43 «Поля событий, подлежащие замене» показаны, какие поля могут быть заменены в каких классах событий.
Таблица 8.43 Поля событий, подлежащие замене
Таблица 8.43 Поля событий, подлежащие замене Класс события Имя поля generalgeneral_query.strtable_accessquery.str
Замена является условной. Каждое указание замены в определении фильтра включает условие, позволяющее изменить заменяемое поле или оставить его без изменений, в зависимости от результата условия.
Если замена происходит, в указании замены указывается значение замены с помощью функции, разрешённой для этой цели.
Как показывает таблица 8.43 «Поля событий, подлежащие замене», в настоящее время единственными заменяемыми полями являются поля, содержащие текст утверждения (который встречается в событиях классов general и table_access). Кроме того, единственной разрешённой функцией для задания значения замены является query_digest. Это означает, что единственная разрешённая операция замены — замена буквального текста утверждения соответствующим дайджестом.
Поскольку замена полей происходит на ранней стадии аудита (во время фильтрации), выбор записи буквального текста утверждения или значений дайджеста применяется независимо от формата журнала, записанного позже (то есть независимо от того, генерирует ли плагин журнала аудита вывод XML или JSON).
Замена полей может происходить на различных уровнях детализации событий:
Для выполнения замены полей для всех событий в классе фильтруйте события на уровне класса.
Для выполнения замены на более детальном уровне включайте дополнительные элементы выбора событий. Например, вы можете выполнять замену полей только для определённых подклассов данного класса событий или только для событий, для которых поля обладают определёнными характеристиками.
В определении фильтра задайте замену полей, включив элемент print, имеющий следующий синтаксис:
"print": {
"field": {
"name": "field_name",
"print": condition,
"replace": replacement_value
}
}
В элементе print элемент field принимает эти три элемента, чтобы указать, происходит ли и как происходит замена:
name: поле, для которого (возможно) происходит замена.field_nameдолжно быть одним из тех, которые показаны в таблице 8.43 «Поля событий, подлежащие замене».-
print: условие, определяющее, сохранять ли исходное значение поля или заменить его:Если
conditionвычисляется какtrue, поле остаётся без изменений.Если
conditionвычисляется какfalse, происходит замена с использованием значения элементаreplace.
Для безусловной замены поля задайте условие так:
"print": false
replace: значение замены, которое следует использовать, когда условиеprintвычисляется какfalse. Укажитеreplacement_value, используя элементfunction.
Например, это определение фильтра применяется ко всем событиям класса general, заменяя буквальный текст утверждения его дайджестом:
{
"filter": {
"class": {
"name": "general",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
Предыдущий фильтр использует элемент print для безусловной замены буквального текста утверждения, содержащегося в general_query.str, его значением дайджеста:
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
Элементы print могут быть написаны по-разному, чтобы реализовать разные стратегии замены. Элемент replace, только что показанный, указывает заменяемый текст с помощью этого конструктора function, чтобы вернуть строку, представляющую текущий дайджест утверждения:
"function": {
"name": "query_digest"
}
Функция query_digest также может использоваться другим способом, как сравнительный оператор, возвращающий булево значение, что позволяет использовать её в условии print. Для этого укажите аргумент, который задаёт сравнительный дайджест утверждения:
"function": {
"name": "query_digest",
"args": "digest"
}
В этом случае, query_digest возвращает true или false в зависимости от того, совпадает ли текущий дайджест утверждения с сравнительным дайджестом. Используя query_digest таким образом, определения фильтров могут обнаруживать утверждения, соответствующие определённым дайджестам. Условие в следующем конструкторе истинно только для утверждений, имеющих дайджест, равный SELECT ?, тем самым производя замену только для утверждений, не соответствующих дайджесту:
"print": {
"field": {
"name": "general_query.str",
"print": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
Для выполнения замены только для утверждений, соответствующих дайджесту, используйте not для инвертирования условия:
"print": {
"field": {
"name": "general_query.str",
"print": {
"not": {
"function": {
"name": "query_digest",
"args": "SELECT ?"
}
}
},
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
Предположим, что журнал аудита должен содержать только дайджесты утверждений, а не буквальные утверждения. Для этого необходимо выполнить замену для всех событий, содержащих текст утверждения; то есть, для событий в классах general и table_access. В предыдущем определении фильтра показано, как безусловно заменить текст утверждения для событий класса general. Для выполнения того же самого для событий класса table_access используйте фильтр, похожий на него, но изменив класс с general на table_access и имя поля с general_query.str на query.str:
{
"filter": {
"class": {
"name": "table_access",
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
Объединение фильтров general и table_access приводит к единому фильтру, который выполняет замену для всех событий, содержащих текст утверждения:
{
"filter": {
"class": [
{
"name": "general",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
},
{
"name": "table_access",
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
]
}
}
Для выполнения замены только для некоторых событий в классе добавьте элементы в фильтр, которые более конкретно указывают, когда происходит замена. Следующий фильтр применяется к событиям класса table_access, но выполняет замену только для событий insert и update (оставляя события read и delete без изменений):
{
"filter": {
"class": {
"name": "table_access",
"event": {
"name": [
"insert",
"update"
],
"print": {
"field": {
"name": "query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
}
}
}
}
}
Этот фильтр выполняет замену для событий класса general, соответствующих перечисленным утверждениям управления учётными записями (в результате чего скрываются значения учетных данных и данных в утверждениях):
{
"filter": {
"class": {
"name": "general",
"event": {
"name": "status",
"print": {
"field": {
"name": "general_query.str",
"print": false,
"replace": {
"function": {
"name": "query_digest"
}
}
}
},
"log": {
"or": [
{
"field": {
"name": "general_sql_command.str",
"value": "alter_user"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "alter_user_default_role"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "create_role"
}
},
{
"field": {
"name": "general_sql_command.str",
"value": "create_user"
}
}
]
}
}
}
}
}
Дополнительную информацию о возможных значениях general_sql_command.str см. в разделе «Проверка значений полей событий».
Замена фильтра пользователя
В некоторых случаях определение фильтра можно динамически изменить. Для этого определите конфигурацию filter в существующей filter. Например:
{
"filter": {
"id": "main",
"class": {
"name": "table_access",
"event": {
"name": [ "update", "delete" ],
"log": false,
"filter": {
"class": {
"name": "general",
"event" : { "name": "status",
"filter": { "ref": "main" } }
},
"activate": {
"or": [
{ "field": { "name": "table_name.str", "value": "temp_1" } },
{ "field": { "name": "table_name.str", "value": "temp_2" } }
]
}
}
}
}
}
}
Новый фильтр активируется, когда элемент activate в подфильтре принимает значение true. Использование activate в верхнем уровне filter запрещено.
Новый фильтр можно заменить исходным, используя элемент ref внутри подфильтра для ссылки на исходный фильтр id.
Действие показанного фильтра таково:
Фильтр
mainожидает событийtable_access, либоupdate, либоdelete.Если событие
updateилиdeletetable_accessпроисходит в таблицеtemp_1илиtemp_2, фильтр заменяется внутренним (без необходимости явной ссылки, поскольку она не нужна).Если происходит сигнал окончания команды (событие
general/status), запись вносится в файл журнала аудита, и фильтр заменяется фильтромmain.
Фильтр полезен для записи заявлений, обновляющих или удаляющих что-либо из таблиц temp_1 или temp_2, например, такого:
UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;
Заявление генерирует несколько событий table_access, но в файле журнала аудита содержатся только записи general / status.
Любые значения id, используемые в определении, оцениваются только относительно этого определения. Они никак не связаны со значением системной переменной audit_log_filter_id.
© 2025 Oracle
Licensed under the GPLv2 License.