编写审核日志过滤器定义
过滤器定义是JSON
值。有关JSON
在MySQL中使用数据的信息,请参见“ JSON数据类型”。
过滤器定义具有以下形式,其中 ctions
指示了如何进行过滤:
{ "filter": ctions }
以下讨论描述了过滤器定义中允许的构造。
- 记录所有事件
- 记录特定事件类
- 记录特定事件子类
- 包容性日志和独占日志
- 测试事件字段值
- 阻止特定事件的执行
- 逻辑运算符
- 引用预定义变量
- 引用预定义函数
- 更换用户过滤器
记录所有事件
要显式启用或禁用所有事件的日志记录,请log
在过滤器中使用一个元素:
{ "filter": { "log": true } }
该log
值可以是true
或false
。
前面的过滤器可以记录所有事件。它等效于:
{ "filter": { } }
登录行为取决于log
价值,以及是否class
或event
指定项目:
- 随着
log
指定,则使用其给定值。 - 如果未
log
指定,则日志记录为true
未指定class
或未event
指定项目,false
否则为日志记录(在这种情况下,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
项目包含一个 bort
项目,它还可以指示是否阻止资格赛。有关详细信息,请参见阻止特定事件的执行。
表6.29“事件类和子类组合”描述了每个事件类的允许子类值。
表6.29事件类和子类组合
活动班 | 事件子类 | 描述 |
---|---|---|
connection | connect | 连接启动(成功或失败) |
connection | change_user | 会话期间使用不同的用户/密码进行用户重新认证 |
connection | disconnect | 连接终止 |
general | status | 一般操作信息 |
message | internal | 内部生成的消息 |
message | user | 讯息产生者 udit_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 |
表6.30“每个事件类和子类组合的日志和异常特性”描述了每个事件子类是否可以记录或中止。
表6.30每个事件类和子类组合的日志和中止特性
活动班 | 事件子类 | 可以记录 | 可以中止 |
---|---|---|---|
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" } } } } } }
每个事件都包含特定于事件类的字段,可以从过滤器内部访问这些字段以执行自定义过滤。
连接事件指示会话期间何时发生与连接有关的活动,例如用户连接到服务器或从服务器断开连接。表6.31“连接事件字段”指示连接事件的允许字段。
表6.31连接事件字段
栏位名称 | 栏位类型 | 描述 |
---|---|---|
status | 整数 | 活动状态: 0:好 否则:失败 |
connection_id | 无符号整数 | 连接ID |
user.str | string | 认证期间指定的用户名 |
user.length | 无符号整数 | 用户名长度 |
priv_user.str | string | 经过身份验证的用户名(帐户用户名) |
priv_user.length | 无符号整数 | 经过身份验证的用户名长度 |
external_user.str | string | 外部用户名(由第三方身份验证插件提供) |
external_user.length | 无符号整数 | 外部用户名长度 |
proxy_user.str | string | 代理用户名 |
proxy_user.length | 无符号整数 | 代理用户名长度 |
host.str | string | 连接的用户主机 |
host.length | 无符号整数 | 连接的用户主机长度 |
ip.str | string | 连接的用户IP地址 |
ip.length | 无符号整数 | 连接的用户IP地址长度 |
database.str | string | 连接时指定的数据库名称 |
database.length | 无符号整数 | 数据库名称长度 |
connection_type | 整数 | 连接类型: 或 或 或 或 或 或 |
这些值是符号伪常数,可以代替文字数字值给出。它们必须用字符串引号并且区分大小写。"::xxx"
常规事件指示操作的状态码及其详细信息。表6.32“常规事件字段”指示常规事件的允许字段。
表6.32常规事件字段
栏位名称 | 栏位类型 | 描述 |
---|---|---|
general_error_code | 整数 | 活动状态: 0:好 否则:失败 |
general_thread_id | 无符号整数 | 连接/线程ID |
general_user.str | string | 认证期间指定的用户名 |
general_user.length | 无符号整数 | 用户名长度 |
general_command.str | string | 指令名称 |
general_command.length | 无符号整数 | 命令名称长度 |
general_query.str | string | SQL语句文本 |
general_query.length | 无符号整数 | SQL语句文本长度 |
general_host.str | string | 主机名 |
general_host.length | 无符号整数 | 主机名长度 |
general_sql_command.str | string | SQL命令类型名称 |
general_sql_command.length | 无符号整数 | SQL命令类型名称长度 |
general_external_user.str | string | 外部用户名(由第三方身份验证插件提供) |
general_external_user.length | 无符号整数 | 外部用户名长度 |
general_ip.str | string | 连接的用户IP地址 |
general_ip.length | 无符号整数 | 连接用户IP地址长度 |
general_command.str
表示命令名:Query
,Execute
,Quit
,或Change user
。
与一般的事件general_command.str
字段设置为Query
或Execute
包含general_sql_command.str
设置为一个值,该值指定SQL命令的类型: lter_db
, lter_db_upgrade
, dmin_commands
,等等。这些值可以视为此语句显示的性能模式工具的最后一个组件:
mysql>SELECT NAME FROM performance_schem .setup_instrumentsWHERE 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 | ...
表访问事件提供有关特定表访问的信息。表6.33“表访问事件字段”指示表访问事件的允许字段。
表6.33表访问事件字段
栏位名称 | 栏位类型 | 描述 |
---|---|---|
connection_id | 无符号整数 | 事件连接ID |
sql_command_id | 整数 | SQL命令ID |
query.str | string | SQL语句文本 |
query.length | 无符号整数 | SQL语句文本长度 |
table_database.str | string | 与事件关联的数据库名称 |
table_database.length | 无符号整数 | 数据库名称长度 |
table_name.str | string | 与事件关联的表名 |
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
条款中引用的表)
阻止特定事件的执行
event
项目可以包括一个 bort
项目,该项目指示是否阻止资格事件的执行。例如, bort
启用编写阻止特定SQL语句执行的规则。
该 bort
项目必须出现在一个event
项目内。例如:
"event": { "name": qualifying event subclass names "abort": condition }
对于name
项目选择的事件子类, bort
操作是对还是错,取决于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
并非所有事件都可以被阻止(请参见表6.30,“每个事件类和子类组合的日志和异常特性”)。对于无法处理的事件,审核日志会将警告写入错误日志,而不是阻止警告。
如果试图定义一个使 bort
项目出现在event
项目以外的地方的过滤器,则会发生错误。
逻辑运算符
逻辑运算符( nd
,or
,not
)可被用log
物品。这允许构建更高级的过滤配置:
{ "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
项目,该项目针对给定值测试是否相等:
{ "filter": { "class": { "name": "general", "event": { "name": "status", "log": { "variable": { "name": "audit_log_connection_policy_value", "value": "::none" } } } } } }
每个预定义变量对应于一个系统变量。通过编写用于测试预定义变量的过滤器,您可以通过设置相应的系统变量来修改过滤器操作,而不必重新定义过滤器。例如,通过编写一个测试 udit_log_connection_policy_value
预定义变量值的过滤器,可以通过更改 udit_log_connection_policy
系统变量的值来修改过滤器操作。
该系统变量用于遗留模式审计日志(见第6.4.5.8,“传统模式下的审计日志过滤”)。使用基于规则的审核日志过滤时,这些变量保持可见(例如,使用),但是除非您编写包含引用它们的构造的过滤器,否则对它们的更改将无效。 udit_log_xxx_policy
SHOW VARIABLES
以下列表描述了允许的variable
项目预定义变量:
udit_log_connection_policy_value
该变量对应于
udit_log_connection_policy
系统变量的值。该值是无符号整数。表6.34“ audit_log_connection_policy_value的值”显示了允许的值和相应的udit_log_connection_policy
值。表6.34 audit_log_connection_policy_value的值
值 对应的audit_log_connection_policy值 0
要么"::none"
NONE
1
要么"::errors"
ERRORS
2
要么"::all"
ALL
这些值是符号伪常数,可以代替文字数字值给出。它们必须用字符串引号并且区分大小写。
"::xxx"
udit_log_policy_value
该变量对应于
udit_log_policy
系统变量的值。该值是无符号整数。表6.35“ audit_log_policy_value的值”显示了允许的值和相应的udit_log_policy
值。表6.35 audit_log_policy_value的值
值 对应的audit_log_policy值 0
要么"::none"
NONE
1
要么"::logins"
LOGINS
2
要么"::all"
ALL
3
要么"::queries"
QUERIES
这些值是符号伪常数,可以代替文字数字值给出。它们必须用字符串引号并且区分大小写。
"::xxx"
udit_log_statement_policy_value
该变量对应于
udit_log_statement_policy
系统变量的值。该值是无符号整数。表6.36“ audit_log_statement_policy_value值”显示了允许的值和相应的udit_log_statement_policy
值。表6.36 audit_log_statement_policy_value的值
值 对应的audit_log_statement_policy值 0
要么"::none"
NONE
1
要么"::errors"
ERRORS
2
要么"::all"
ALL
这些值是符号伪常数,可以代替文字数字值给出。它们必须用字符串引号并且区分大小写。
"::xxx"
引用预定义函数
要在log
条件中引用预定义的函数,请使用一个function
项目,该项目采用name
和 rgs
值分别指定函数名称及其参数:
{ "filter": { "class": { "name": "general", "event": { "name": "status", "log": { "function": { "name": "find_in_include_list", "args": [ { "string": [ { "field": "user.str" }, { "string": "@"}, { "field": "host.str" } ] } ] } } } } } }
name
项目中指定的函数应仅是函数名称,不带括号或参数列表。该 rgs
项目中的参数(如果有)必须按功能说明中列出的顺序给出。参数可以引用预定义的变量,事件字段或字符串或数字常量。
前面的过滤器根据是否在系统变量中找到当前用户来确定是否记录general
类status
事件 udit_log_include_accounts
。该用户是使用事件中的字段构造的。
下表描述了允许使用的function
项目预定义功能:
udit_log_exclude_accounts_is_null()
检查
udit_log_exclude_accounts
系统变量是否为NULL
。当定义与旧审计日志实现相对应的过滤器时,此功能将很有帮助。参数:
没有。
udit_log_include_accounts_is_null()
检查
udit_log_include_accounts
系统变量是否为NULL
。当定义与旧审计日志实现相对应的过滤器时,此功能将很有帮助。参数:
没有。
debug_sleep(millisec)
睡眠指定的毫秒数。在性能评估期间使用此功能。
debug_sleep()
仅适用于调试版本。参数:
millisec
:一个无符号整数,它指定要休眠的毫秒数。
find_in_exclude_list(account)
检查审核日志排除列表中是否存在帐户字符串(
udit_log_exclude_accounts
系统变量的值)。参数:
ccount
:一个字符串,用于指定用户帐户名称。
find_in_include_list(account)
检查审核日志包含列表(
udit_log_include_accounts
系统变量的值)中是否存在帐户字符串。参数:
ccount
:一个字符串,用于指定用户帐户名称。
string_find(text, substr)
检查
substr
值中是否包含该text
值。此搜索区分大小写。参数:
text
:要搜索的文本字符串。substr
:要在中搜索的子字符串text
。
更换用户过滤器
在某些情况下,可以动态更改过滤器定义。为此,请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" } } ] } } } } } }
当子过滤器中的 ctivate
元素的值为时,将激活一个新的过滤器true
。不允许 ctivate
在顶层使用filter
。
通过使用子ref
过滤器内的一项来引用原始过滤器,可以用原始过滤器替换新的过滤器id
。
显示的过滤器的运行方式如下:
- 该
main
过滤器等待table_access
的事件,无论是update
或delete
。 - 如果
update
ordelete
table_access
事件发生在temp_1
ortemp_2
表上,则将过滤器替换为内部过滤器(不带id
,因为无需显式引用它)。 - 如果发出命令结束的信号(
general
/status
事件),则会将一个条目写入审核日志文件,然后将过滤器替换为main
过滤器。
过滤器对于记录更新或删除temp_1
或temp_2
表中的任何内容的语句很有用,例如:
UPDATE temp_1, temp_3SET temp_1. =21, temp_3. =23;
该语句生成多个table_access
事件,但是审核日志文件将仅包含general
/status
条目。
注意
id
定义中使用的任何值仅针对该定义进行评估。它们与udit_log_filter_id
系统变量的值无关。