• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 编写审核日志过滤器定义

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

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

    { "filter": ctions }
    

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

    • 记录所有事件
    • 记录特定事件类
    • 记录特定事件子类
    • 包容性日志和独占日志
    • 测试事件字段值
    • 阻止特定事件的执行
    • 逻辑运算符
    • 引用预定义变量
    • 引用预定义函数
    • 更换用户过滤器
    记录所有事件

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

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

    log值可以是truefalse

    前面的过滤器可以记录所有事件。它等效于:

    {
    "filter": { }
    }
    

    登录行为取决于log价值,以及是否classevent指定项目:

    • 随着log指定,则使用其给定值。
    • 如果未log指定,则日志记录为true未指定class或未event指定项目,false否则为日志记录(在这种情况下,class或者event可以包括自己的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项目包含一个 bort项目,它还可以指示是否阻止资格赛。有关详细信息,请参见阻止特定事件的执行。

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

    表6.29事件类和子类组合

    活动班事件子类描述
    connectionconnect连接启动(成功或失败)
    connectionchange_user会话期间使用不同的用户/密码进行用户重新认证
    connectiondisconnect连接终止
    generalstatus一般操作信息
    messageinternal内部生成的消息
    messageuser讯息产生者 udit_api_message_emit_udf()
    table_accessread表读取语句,例如SELECTINSERT INTO ... SELECT
    table_accessdelete表删除语句,例如DELETETRUNCATE TABLE
    table_accessinsert表插入语句,例如INSERTREPLACE
    table_accessupdate表更新语句,例如UPDATE

    表6.30“每个事件类和子类组合的日志和异常特性”描述了每个事件子类是否可以记录或中止。

    表6.30每个事件类和子类组合的日志和中止特性

    活动班事件子类可以记录可以中止
    connectionconnect没有
    connectionchange_user没有
    connectiondisconnect没有
    generalstatus没有
    messageinternal
    messageuser
    table_accessread
    table_accessdelete
    table_accessinsert
    table_accessupdate

    包容性日志和独占日志

    可以以包含或排除模式定义过滤器:

    • 包含模式仅记录明确指定的项目。
    • 独占模式记录除明确指定的项目以外的所有内容。

    要执行包含性日志记录,请全局禁用日志记录并启用特定类的日志记录。此过滤器过滤类中的日志connectdisconnect事件,以及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.strstring认证期间指定的用户名
    user.length无符号整数用户名长度
    priv_user.strstring经过身份验证的用户名(帐户用户名)
    priv_user.length无符号整数经过身份验证的用户名长度
    external_user.strstring外部用户名(由第三方身份验证插件提供)
    external_user.length无符号整数外部用户名长度
    proxy_user.strstring代理用户名
    proxy_user.length无符号整数代理用户名长度
    host.strstring连接的用户主机
    host.length无符号整数连接的用户主机长度
    ip.strstring连接的用户IP地址
    ip.length无符号整数连接的用户IP地址长度
    database.strstring连接时指定的数据库名称
    database.length无符号整数数据库名称长度
    connection_type整数

    连接类型:

    "::undefined":未定义

    "::tcp/ip":TCP / IP

    "::socket":插座

    "::named_pipe":命名管道

    "::ssl":具有加密功能的TCP / IP

    "::shared_memory":共享内存

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

    常规事件指示操作的状态码及其详细信息。表6.32“常规事件字段”指示常规事件的允许字段。

    表6.32常规事件字段

    栏位名称栏位类型描述
    general_error_code整数

    活动状态:

    0:好

    否则:失败

    general_thread_id无符号整数连接/线程ID
    general_user.strstring认证期间指定的用户名
    general_user.length无符号整数用户名长度
    general_command.strstring指令名称
    general_command.length无符号整数命令名称长度
    general_query.strstringSQL语句文本
    general_query.length无符号整数SQL语句文本长度
    general_host.strstring主机名
    general_host.length无符号整数主机名长度
    general_sql_command.strstringSQL命令类型名称
    general_sql_command.length无符号整数SQL命令类型名称长度
    general_external_user.strstring外部用户名(由第三方身份验证插件提供)
    general_external_user.length无符号整数外部用户名长度
    general_ip.strstring连接的用户IP地址
    general_ip.length无符号整数连接用户IP地址长度

    general_command.str表示命令名:QueryExecuteQuit,或Change user

    与一般的事件general_command.str字段设置为QueryExecute包含general_sql_command.str设置为一个值,该值指定SQL命令的类型: lter_db lter_db_upgrade dmin_commands,等等。这些值可以视为此语句显示的性能模式工具的最后一个组件:

    mysql> SELECT NAME FROM performance_schem .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             |
    ...
    

    表访问事件提供有关特定表访问的信息。表6.33“表访问事件字段”指示表访问事件的允许字段。

    表6.33表访问事件字段

    栏位名称栏位类型描述
    connection_id无符号整数事件连接ID
    sql_command_id整数SQL命令ID
    query.strstringSQL语句文本
    query.length无符号整数SQL语句文本长度
    table_database.strstring与事件关联的数据库名称
    table_database.length无符号整数数据库名称长度
    table_name.strstring与事件关联的表名
    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规范可以是一样简单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
    

    并非所有事件都可以被阻止(请参见表6.30,“每个事件类和子类组合的日志和异常特性”)。对于无法处理的事件,审核日志会将警告写入错误日志,而不是阻止警告。

    如果试图定义一个使 bort项目出现在event项目以外的地方的过滤器,则会发生错误。

    逻辑运算符

    逻辑运算符( ndornot)可被用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_policySHOW 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项目中的参数(如果有)必须按功能说明中列出的顺序给出。参数可以引用预定义的变量,事件字段或字符串或数字常量。

    前面的过滤器根据是否在系统变量中找到当前用户来确定是否记录generalstatus事件 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的事件,无论是updatedelete
    • 如果updateor deletetable_access事件发生在temp_1or temp_2表上,则将过滤器替换为内部过滤器(不带id,因为无需显式引用它)。
    • 如果发出命令结束的信号(general/status事件),则会将一个条目写入审核日志文件,然后将过滤器替换为main过滤器。

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

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

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

    注意

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