Spec-Zone.ru › MySQL 9.2

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" ] }
    ]
  }
}
END_OF_DOCUMENT_MARKER
Регистрация конкретных подклассов событий

Для выбора конкретных подклассов событий используйте элемент 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 Сочетания классов и подклассов событий

Таблица 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 Характеристики регистрации и прерывания по сочетанию класса и подкласса события

Таблица 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 Поля событий подключения

Таблица 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 или "::undefined": Не определено

1 или "::tcp/ip": TCP/IP

2 или "::socket": Сокет

3 или "::named_pipe": Имя канала

4 или "::ssl": TCP/IP с шифрованием

5 или "::shared_memory": Общая память


Значения "::xxx" — это символические псевдоконстанты, которые могут быть указаны вместо числовых значений. Они должны быть представлены в виде строк и чувствительны к регистру.

Событие в классе general указывает код состояния операции и её подробности. Таблица 8.38, «Поля событий общего назначения» указывает допустимые поля для событий general.

Таблица 8.38 Поля событий общего назначения

Таблица 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 Поля событий доступа к таблицам

Таблица 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:

    • SELECT

    • INSERT ... SELECT (для таблиц, упомянутых в предложении SELECT)

    • REPLACE ... SELECT (для таблиц, упомянутых в предложении SELECT)

    • UPDATE ... WHERE (для таблиц, упомянутых в предложении WHERE)

    • HANDLER ... READ

  • Событие delete:

    • DELETE

    • TRUNCATE TABLE

  • Событие insert:

    • INSERT

    • INSERT ... SELECT (для таблицы, упомянутой в предложении INSERT)

    • REPLACE

    • REPLACE ... SELECT (для таблицы, упомянутой в предложении REPLACE)

    • LOAD DATA

    • LOAD XML

  • Событие update:

    • UPDATE

    • UPDATE ... 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_xxx_policy используются для устаревшего режима журнала аудита (см. Раздел 8.4.5.10, «Фильтрация журнала аудита в режиме обратной совместимости»). В режиме фильтрации журнала аудита на основе правил эти переменные остаются видимыми (например, с помощью SHOW 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" NONE
    1 или "::errors" ERRORS
    2 или "::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_accounts NULL. Эта функция может быть полезна при определении фильтров, соответствующих реализации журнала аудита старой версии.

    Аргументы:

    Нет.

  • audit_log_include_accounts_is_null()

    Проверяет, является ли системная переменная audit_log_include_accounts NULL. Эта функция может быть полезна при определении фильтров, соответствующих реализации журнала аудита старой версии.

    Аргументы:

    Нет.

  • 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 Поля событий, подлежащие замене
    Класс события Имя поля
    general general_query.str
    table_access query.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 или delete table_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.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/audit-log-filter-definitions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API