Documentation Home
MySQL 8.0 参考手册  / 第 6 章 安全  / 6.4 安全组件和插件  / 6.4.5 MySQL企业审计  /  6.4.5.8 编写审计日志过滤器定义

6.4.5.8 编写审计日志过滤器定义

过滤器定义是JSON 值。有关 JSON在 MySQL 中使用数据的信息,请参阅 第 11.5 节,“JSON 数据类型”

过滤器定义具有这种形式,其中 actions指示过滤是如何发生的:

{ "filter": actions }

以下讨论描述了过滤器定义中允许的构造。

记录所有事件

要显式启用或禁用所有事件的日志记录,请使用 log过滤器中的一个项目:

{
  "filter": { "log": true }
}

log值可以是 truefalse

前面的过滤器启用所有事件的日志记录。它相当于:

{
  "filter": { }
}

记录行为取决于log值以及是否class指定 了event项目:

  • 如果指定,则使用log其给定值。

  • 如果没有log指定,则记录是 true如果没有指定classevent项目, false否则(在这种情况下, classevent可以包括他们自己的log项目)。

记录特定事件类

要记录特定类的事件,请使用 class过滤器中的一个项目,其 name字段表示要记录的类的名称:

{
  "filter": {
    "class": { "name": "connection" }
  }
}

name值可以是 connectiongeneraltable_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项目)。有关详细信息,请参阅 阻止执行特定事件

表 6.35 “事件类和子类组合” 描述了每个事件类允许的子类值。

表 6.35 事件类和子类组合

事件类 事件子类 描述
connection connect 连接启动(成功或不成功)
connection change_user 在会话期间使用不同的用户名/密码重新进行用户身份验证
connection disconnect 连接终止
general status 一般操作信息
message internal 内部生成的消息
message user 消息生成者 audit_api_message_emit_udf()
table_access read 读表语句,例如SELECTor INSERT INTO ... SELECT
table_access delete 表删除语句,例如DELETE orTRUNCATE TABLE
table_access insert 表插入语句,例如INSERT orREPLACE
table_access update 表更新语句,如UPDATE

表 6.36 “每个事件类和子类组合的记录和中止特征”描述了每个事件子类是否可以记录或中止。

表 6.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中的 事件:connectionmessagetable_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指示在会话期间何时发生与连接相关的活动,例如用户连接到服务器或从服务器断开连接。 表 6.37,“连接事件字段”指示事件的允许字段connection

表 6.37 连接事件字段

字段名称 字段类型 描述
status 整数

事件状态:

0:好的

否则:失败

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指示操作的状态代码及其详细信息。 表 6.38,“通用事件字段”指出了事件的允许字段general

表 6.38 一般事件字段

字段名称 字段类型 描述
general_error_code 整数

事件状态:

0:好的

否则:失败

general_thread_id 无符号整数 连接/线程 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指示命令名称:QueryExecuteQuitChange user

字段设置为 或 包含设置为指定 SQL 命令类型的值 的general事件 : 、、、 等等 。可用 值可以看作是此语句显示的 Performance Schema 工具的最后一个组件: general_command.strQueryExecutegeneral_sql_command.stralter_dbalter_db_upgradeadmin_commandsgeneral_sql_command.str

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提供有关对表的特定类型访问的信息。 表 6.39,“表访问事件字段” 指出了事件的允许字段 table_access

表 6.39 表访问事件字段

字段名称 字段类型 描述
connection_id 无符号整数 事件连接 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 ... SELECTSELECT(对于子句 中引用的表格)

    • REPLACE ... SELECTSELECT(对于子句 中引用的表格)

    • UPDATE ... WHEREWHERE(对于子句 中引用的表格)

    • HANDLER ... READ

  • delete事件:

    • DELETE

    • TRUNCATE TABLE

  • insert事件:

    • INSERT

    • INSERT ... SELECT(对于INSERT子句中引用的表格)

    • REPLACE

    • REPLACE ... SELECT(对于REPLACE子句 中引用的表

    • LOAD DATA

    • LOAD XML

  • update事件:

    • UPDATE

    • UPDATE ... WHEREUPDATE(对于子句 中引用的表格)

阻止特定事件的执行

eventitems 可以包括 abort指示是否阻止执行合格事件的项目。 abort允许编写阻止特定 SQL 语句执行的规则。

重要的

理论上,具有足够权限的用户可能会错误地abort 在审计日志过滤器中创建一个项目,从而阻止他们自己和其他管理员访问系统。从 MySQL 8.0.28 开始,该 AUDIT_ABORT_EXEMPT 权限可用于允许用户帐户的查询始终执行,即使某个abort 项目会阻止它们也是如此。因此,具有此权限的帐户可用于在审计配置错误后重新获得对系统的访问权限。该查询仍记录在审计日志中,但由于特权而被允许,而不是被拒绝。

在 MySQL 8.0.28 或更高版本中创建的具有 SYSTEM_USER权限的帐户在创建AUDIT_ABORT_EXEMPT 时会自动分配权限。 当您使用 MySQL 8.0.28 或更高版本执行升级过程时,如果现有帐户没有 分配该权限,该 AUDIT_ABORT_EXEMPT权限也会分配给具有该 权限的现有帐户。SYSTEM_USER

abort项目必须出现在 event项目内。例如:

"event": {
  "name": qualifying event subclass names
  "abort": condition
}

对于name 项目选择的事件子类,abort动作是真还是假,取决于condition评估。如果条件评估为真,则事件被阻止。否则,事件继续执行。

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

并非所有事件都可以被阻止(请参阅 表 6.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项目,它采用 项目namevalue测试命名变量与给定值的相等性:

"variable": {
  "name": "variable_name",
  "value": comparison_value
}

如果variable_name具有 value则为 true comparison_value,否则为 false。

例子:

{
  "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

系统 变量用于遗留模式审计日志(请参阅 第 6.4.5.10 节,“遗留模式审计日志过滤”)。使用基于规则的审计日志过滤,这些变量保持可见(例如,使用),但对它们的更改没有效果,除非您编写包含引用它们的构造的过滤器。 audit_log_xxx_policySHOW VARIABLES

以下列表描述了variable项目允许的预定义变量:

  • audit_log_connection_policy_value

    该变量对应于 audit_log_connection_policy 系统变量的值。该值是一个无符号整数。 表 6.40,“audit_log_connection_policy_value 值” 显示了允许的值和相应的 audit_log_connection_policy 值。

    表 6.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系统变量的值。该值是一个无符号整数。 表 6.41 “audit_log_policy_value 值”显示了允许的值和相应的 audit_log_policy值。

    表 6.41 audit_log_policy_value 值

    价值 对应的 audit_log_policy 值
    0或者"::none" NONE
    1或者"::logins" LOGINS
    2或者"::all" ALL
    3或者"::queries" QUERIES

    这些 值是可以给出的符号伪常量,而不是文字数值。它们必须作为字符串引用并且区分大小写。 "::xxx"

  • audit_log_statement_policy_value

    该变量对应于 audit_log_statement_policy 系统变量的值。该值是一个无符号整数。 表 6.42,“audit_log_statement_policy_value 值” 显示了允许的值和相应的 audit_log_statement_policy 值。

    表 6.42 audit_log_statement_policy_value 值

    价值 对应的 audit_log_statement_policy 值
    0或者"::none" NONE
    1或者"::errors" ERRORS
    2或者"::all" ALL

    这些 值是可以给出的符号伪常量,而不是文字数值。它们必须作为字符串引用并且区分大小写。 "::xxx"

引用预定义函数

要在条件中引用预定义函数log ,请使用一个function项目,它采用 nameargs项目分别指定函数名称及其参数:

"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类事件。该用户是使用事件中的字段构建的。 statusaudit_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 ?"
    }

    这个函数是在 MySQL 8.0.26 中添加的。

  • string_find(text, substr)

    检查substr值是否包含在text值中。此搜索区分大小写。

    参数:

    • text: 要搜索的文本字符串。

    • substr: 要在 中搜索的子字符串text

事件字段值的替换

从 MySQL 8.0.26 开始,审计过滤器定义支持替换某些审计事件字段,以便记录的事件包含替换值而不是原始值。此功能使记录的审计记录能够包含语句摘要而不是文字语句,这对于语句可能公开敏感值的 MySQL 部署非常有用。

审计事件中的字段替换是这样工作的:

  • 字段替换在审核过滤器定义中指定,因此必须启用审核日志过滤,如第 6.4.5.7 节“审核日志过滤”中所述。

  • 并非所有字段都可以替换。 表 6.43 “需要替换的事件字段”显示了哪些字段在哪些事件类中是可替换的。

    表 6.43 需要替换的事件字段

    事件类 字段名称
    general general_query.str
    table_access query.str

  • 更换是有条件的。过滤器定义中的每个替换规范都包含一个条件,允许根据条件结果更改或保持可替换字段不变。

  • 如果发生替换,则替换规范使用为此目的允许的函数指示替换值。

表 6.43“需要替换的事件字段”所示,目前唯一可替换的字段是包含语句文本的字段(出现在 generaltable_access 类的事件中)。此外,唯一允许指定替换值的函数是 query_digest. 这意味着唯一允许的替换操作是用相应的摘要替换语句文字文本。

因为字段替换发生在早期审计阶段(在过滤期间),所以无论稍后写入的日志格式如何(即,审计日志插件是否生成 XML 或 JSON 输出),都可以选择是写入语句文字文本还是摘要值。

字段替换可以发生在事件粒度的不同级别:

  • 要对类中的所有事件执行字段替换,请在类级别过滤事件。

  • 要在更细粒度的基础上执行替换,请包括其他事件选择项。例如,您可以仅对给定事件类的特定子类执行字段替换,或者仅在字段具有特定特征的事件中执行字段替换。

在过滤器定义中,通过包含print具有以下语法的项目来指定字段替换:

"print": {
  "field": {
    "name": "field_name",
    "print": condition,
    "replace": replacement_value
  }
}

printitem内部,它的 fielditem取这三个item来表示replacement是否发生以及如何发生:

  • name:(可能)发生替换的字段。 field_name必须是 表 6.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返回 truefalse取决于当前语句摘要是否与比较摘要相同。使用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"
      }
    }
  }
}

假设您希望审计日志只包含语句摘要而不包含文字语句。为此,您必须对所有包含语句文本的事件执行替换;即generaltable_access类中的事件。早期的过滤器定义展示了如何无条件地替换general事件的语句文本。要对 table_access事件执行相同的操作,请使用类似的过滤器,但将类从更改generaltable_access,将字段名称从 general_query.str更改为 query.str

{
  "filter": {
    "class": {
      "name": "table_access",
      "print": {
        "field": {
          "name": "query.str",
          "print": false,
          "replace": {
            "function": {
              "name": "query_digest"
            }
          }
        }
      }
    }
  }
}

generaltable_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类中的事件,但仅对insertupdate事件执行替换(保留 readdelete事件不变):

{
  "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

  • 如果updateor delete table_access 事件发生在temp_1or temp_2表上,过滤器将替换为内部过滤器(没有id,因为不需要显式引用它)。

  • 如果发出命令结束信号 ( general/ status event ),则会将一个条目写入审计日志文件,并用过滤器替换main 过滤器。

过滤器对于记录从temp_1temp_2表中更新或删除任何内容的语句很有用,例如:

UPDATE temp_1, temp_3 SET temp_1.a=21, temp_3.a=23;

该语句生成多个 table_access事件,但审计日志文件仅包含general/ status条目。

笔记

定义中使用的任何id值仅根据该定义进行评估。audit_log_filter_id它们与系统变量 的值无关 。