Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Writing Audit Log Filter Definitions

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

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

过滤器定义具有以下形式,其中 actions 指示如何进行过滤:

{ "filter": actions }

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

记录所有事件

要明确启用或禁用所有事件的日志记录,请在过滤器中使用 log 项:

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

log 值可以是 truefalse

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

{
  "filter": { }
}

日志记录行为取决于 log 值和是否指定了 classevent 项:

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

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

记录特定事件类

要记录特定类的事件,请在过滤器中使用 class 项,其中的 name 字段指定要记录的类的名称:

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

名称值可以是 connectiongeneraltable_access,以记录连接、一般或表访问事件。

前面的过滤器启用了 connection 类的事件记录。它等同于以下具有明确 log 项的过滤器:

{
  "filter": {
    "log": false,
    "class": { "log": true,
               "name": "connection" }
  }
}

要启用多个类的记录,请将 class 值定义为一个 JSON 数组元素,命名要记录的类:

{
  "filter": {
    "class": [
      { "name": "connection" },
      { "name": "general" },
      { "name": "table_access" }
    ]
  }
}
Note

当多个实例出现在同一级别的过滤器定义中时,项值可以合并到单个实例中。前面的定义可以写成这样:

{
  "filter": {
    "class": [
      { "name": [ "connection", "general", "table_access" ] }
    ]
  }
}
记录特定事件子类

要选择特定事件子类,请使用包含 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.37,“事件类和子类组合” 描述了每个事件类的允许子类值。

表 8.37 事件类和子类组合

事件类 事件子类 描述
connection connect 连接初始化(成功或失败)
connection change_user 会话期间使用不同用户/密码重新认证
connection disconnect 连接终止
general status 一般操作信息
message internal 内部生成的消息
message user audit_api_message_emit_udf()生成的消息
table_access read 表读取语句,例如SELECTINSERT INTO ... SELECT
table_access delete 表删除语句,例如DELETETRUNCATE TABLE
table_access insert 表插入语句,例如INSERTREPLACE
table_access update 表更新语句,例如UPDATE

表 8.38,事件类和子类的日志和中止特征 描述了每个事件子类是否可以被日志或中止。

表 8.38 事件类和子类的日志和中止特征

事件类 事件子类 可以日志 可以中止
连接 连接
连接 更改用户
连接 断开连接
通用 状态
消息 内部
消息 用户
表访问 读取
表访问 删除
表访问 插入
表访问 更新

包括和排除日志

过滤器可以在包括或排除模式下定义:

  • 包括模式仅记录明确指定的项目。

  • 排除模式记录除明确指定的项目外的所有项目。

要执行包括日志,请禁用全局日志记录并启用特定类的日志记录。该过滤器记录 连接断开连接 事件在 连接 类中,以及 通用 类中的事件:

{
  "filter": {
    "log": false,
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect", "log": true },
          { "name": "disconnect", "log": true }
        ]
      },
      { "name": "general", "log": true }
    ]
  }
}

要执行排除日志,请启用全局日志记录并禁用特定类的日志记录。该过滤器记录除 通用 类外的所有事件:

{
  "filter": {
    "log": true,
    "class":
      { "name": "general", "log": false }
  }
}

该过滤器记录 更改用户 事件在 连接 类中, 消息 事件和 表访问 事件,通过 记录所有其他事件:

{
  "filter": {
    "log": true,
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect", "log": false },
          { "name": "disconnect", "log": false }
        ]
      },
      { "name": "general", "log": false }
    ]
  }
}
测试事件字段值

要启用基于特定事件字段值的日志记录,请指定 field 项 within the log 项,指示字段名称和其预期值:

{
  "filter": {
    "class": {
    "name": "general",
      "event": {
        "name": "status",
        "log": {
          "field": { "name": "general_command.str", "value": "Query" }
        }
      }
    }
  }
}

每个事件都包含特定于事件类的字段,这些字段可以从过滤器内部访问,以执行自定义过滤。

connection 类中,事件指示会话期间发生的连接相关活动,例如用户连接到或断开与服务器的连接。表 8.39,“连接事件字段” 指示了 connection 事件的允许字段。

表 8.39 连接事件字段

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

事件状态:

0:成功

否则:失败

connection_id 无符号整数 连接 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":Socket

3 或 "::named_pipe":命名管道

4 或 "::ssl":TCP/IP 加密

5 或 "::shared_memory":共享内存


"::xxx" 值是符号伪常量,可以代替数字值。它们必须作为字符串引用,并且区分大小写。

general 类中的事件指示操作的状态代码及其详细信息。表 8.40,“一般事件字段” 指示了 general 事件的允许字段。

表 8.40 一般事件字段

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

事件状态:

0: OK

否则:失败

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

一个 general 事件,其中 general_command.str 字段设置为 QueryExecute,包含 general_sql_command.str 字段,指定 SQL 命令类型:alter_dbalter_db_upgradeadmin_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.41,“表访问事件字段” 指示了 table_access 事件的允许字段。

表 8.41 表访问事件字段

字段名称 字段类型 描述
connection_id 无符号整数 事件连接 ID
sql_command_id 整数 SQL 命令 ID
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 子句中的表)

    • 替换

    • 替换 ... 选择 (for table referenced in 替换 clause

    • 加载数据

    • 加载 XML

  • 更新 事件:

    • 更新

    • 更新 ... WHERE (for tables referenced in 更新 clause)

阻止特定事件的执行

事件 项可以包括一个 abort 项,指示是否阻止合格的事件执行。abort 启用规则,以阻止特定 SQL 语句的执行。

Important

理论上,具有足够权限的用户可能会错误地创建一个 abort 项在审核日志过滤器中,从而阻止自己和其他管理员访问系统。AUDIT_ABORT_EXEMPT 权限可用于允许用户账户的查询始终执行,即使 abort 项阻止它们。具有该权限的账户可以因此用于在审核misconfiguration后恢复系统访问。查询仍将记录在审核日志中,但由于权限的存在,它将被允许执行。

具有 SYSTEM_USER 权限的账户在创建时自动分配 AUDIT_ABORT_EXEMPT 权限。当您执行升级过程时,如果没有现有的账户具有该权限,它也将被分配给具有 SYSTEM_USER 权限的现有账户。

The abort 项必须出现在 事件 项中。例如:

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

对于由 name 项选择的事件子类,abort 动作取决于 condition 评估结果。如果条件评估为 true,则事件将被阻止。否则,事件将继续执行。

The condition 规范可以简单地为 truefalse,或者它可以更复杂,以便评估取决于事件特征。

该过滤器阻止 INSERTUPDATEDELETE 语句:

{
  "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.38,“事件类和子类组合的日志和中止特征”)。对于不能被阻止的事件,审计日志将警告写入错误日志,而不是阻止它。

对于尝试定义一个过滤器,其中的 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 的值为 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.42,“audit_log_connection_policy_value 值”显示了允许的值和相应的audit_log_connection_policy值。

    表 8.42 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.43,“audit_log_policy_value 值”显示了允许的值和相应的audit_log_policy值。

    表 8.43 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系统变量的值。该值是一个无符号整数。表 8.44,“audit_log_statement_policy_value 值”显示了允许的值和对应的audit_log_statement_policy值。

    表 8.44 audit_log_statement_policy_value 值

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

    "::xxx" 值是符号伪常量,可以代替实际的数字值。它们必须作为字符串引用,并且区分大小写。

引用预定义函数

要在日志条件中引用预定义函数,请使用 function 项,指定函数名称和参数:

"function": {
  "name": "function_name",
  "args": arguments
}

名称项应指定函数名称,不包括括号或参数列表。

参数项必须满足以下条件:

  • 如果函数不需要参数,则不需要参数项。

  • 如果函数需要参数,则需要参数项,并且参数必须按照函数描述中的顺序提供。参数可以引用预定义变量、事件字段或字符串或数字常量。

如果参数数量不正确或参数类型不正确,将发生错误。

示例:

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "log": {
          "function": {
            "name": "find_in_include_list",
            "args": [ { "string": [ { "field": "user.str" },
                                    { "string": "@"},
                                    { "field": "host.str" } ] } ]
          }
        }
      }
    }
  }
}

前面的过滤器确定是否记录 generalstatus 事件,取决于当前用户是否在 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:该参数是可选的。如果提供了该参数,它指定了要与当前事件的语句摘要进行比较的语句摘要。

    示例:

    函数项不包含参数,因此query_digest返回当前语句摘要作为字符串:

    "function": {
      "name": "query_digest"
    }

    函数项包含一个参数,因此query_digest返回一个布尔值,指示参数是否等于当前语句摘要:

    "function": {
      "name": "query_digest",
      "args": "SELECT ?"
    }
  • string_find(text, substr)

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

    参数:

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

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

事件字段值替换

审核过滤器定义支持替换某些审核事件字段,以便记录的事件包含替换值,而不是原始值。这使得记录的审核记录可以包含语句摘要,而不是文字语句,这对 MySQL 部署非常有用,因为语句可能会暴露敏感值。

审核事件中的字段替换工作如下:

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

  • 并不是所有字段都可以被替换。表 8.45,“可替换的事件字段” 显示了哪些字段可以在哪些事件类中被替换。

    表 8.45 可替换的事件字段

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

  • 替换是有条件的。每个替换规则在过滤器定义中包括一个条件,启用或禁用可替换字段的更改,取决于条件结果。

  • 如果发生替换,替换规则将使用允许的函数指定替换值。

表 8.45,“可替换的事件字段”所示,当前唯一可替换的字段是包含语句文本的字段(出现在 generaltable_access 事件类中)。此外,唯一允许的函数是 query_digest。这意味着唯一允许的替换操作是将语句文字文本替换为对应的摘要。

因为字段替换发生在审核的早期阶段(在过滤期间),因此选择是否写入语句文字文本或摘要值适用于所有日志格式(无论审核日志插件生成 XML 或 JSON 输出)。

字段替换可以在不同的事件粒度级别上进行:

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

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

在过滤器定义中,通过包括一个 print 项来指定字段替换,该语法如下:

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

print 项中,其 field 项采用这三个项来指示是否和如何进行替换:

  • name:要进行替换的字段。field_name 必须是 表 8.45,“事件字段的替换” 中所示的其中之一。

  • print:确定是否保留原始字段值或进行替换的条件:

    • 如果 condition 评估为 true,则字段保持不变。

    • 如果 condition 评估为 false,则进行替换,使用 replace 项的值。

    要无条件地替换一个字段,请指定条件如下:

    "print": false
  • replace:当 print 条件评估为 false 时使用的替换值。使用 function 项指定 replacement_value

例如,这个过滤器定义适用于所有事件的 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 事件执行相同的操作,请使用类似的过滤器,但将类从 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"
            }
          }
        }
      }
    }
  }
}

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 时,新的过滤器将被激活。在顶级 filter 中使用 activate 不是允许的。

新的过滤器可以使用 ref 项在子过滤器中引用原始过滤器的 id,以将其替换为原始过滤器。

该过滤器的工作方式如下:

  • 主过滤器等待 table_access 事件,或者 updatedelete

  • 如果 updatedelete table_access 事件发生在 temp_1temp_2 表上,则过滤器将被替换为内部过滤器(没有 id,因为不需要明确引用它)。

  • 如果命令结束被信号(general / status 事件),则将写入审核日志文件,并将过滤器替换为 main 过滤器。

该过滤器有助于记录更新或从 temp_1temp_2 表中删除任何内容的语句,例如这个:

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

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

Note

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