MySQL8-中文参考-十五-

MySQL8 中文参考(十五)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

原文:dev.mysql.com/doc/refman/8.0/en/audit-log-disabling.html

8.4.5.9 禁用审计日志

audit_log_disable变量在 MySQL 8.0.28 中引入,允许禁用所有连接和已连接会话的审计日志记录。audit_log_disable变量可以在 MySQL 服务器选项文件中设置,在命令行启动字符串中设置,或者在运行时使用SET语句设置;例如:

SET GLOBAL audit_log_disable = true;

audit_log_disable设置为 true 会禁用审计日志插件。当audit_log_disable重新设置为false时(默认设置),插件将重新启用。

使用audit_log_disable = true启动审计日志插件会生成警告(ER_WARN_AUDIT_LOG_DISABLED),并显示以下消息:Audit Log is disabled. Enable it with audit_log_disable = false. 将audit_log_disable设置为 false 也会生成警告。当audit_log_disable设置为 true 时,审计日志函数调用和变量更改会生成会话警告。

设置audit_log_disable的运行时值需要AUDIT_ADMIN权限,除了通常需要设置全局系统变量运行时值的SYSTEM_VARIABLES_ADMIN权限(或已弃用的SUPER权限)。

原文:dev.mysql.com/doc/refman/8.0/en/audit-log-legacy-filtering.html

8.4.5.10 遗留模式审计日志过滤

注意

此部分描述了遗留审计日志过滤,适用于安装了audit_log插件但没有规则过滤所需的审计表和函数的情况。

遗留模式审计日志过滤已在 MySQL 8.0.34 中弃用。

审计日志插件可以过滤审计事件。这使您可以控制基于事件来源账户或事件状态将审计事件写入审计日志文件。连接事件和语句事件的状态过滤是分开进行的。

  • 按账户进行遗留事件过滤

  • 按状态进行遗留事件过滤

按账户进行遗留事件过滤

要根据发起账户过滤审计事件,请在服务器启动或运行时设置以下系统变量中的一个(而不是两个)。这些已弃用的变量仅适用于遗留审计日志过滤。

  • audit_log_include_accounts:要包含在审计日志中的账户。如果设置了此变量,则只对这些账户进行审计。

  • audit_log_exclude_accounts:要排除在审计日志中的账户。如果设置了此变量,则除了这些账户外,所有其他账户都会被审计。

任一变量的值可以是NULL,或包含一个或多个以*user_name*@*host_name*格式逗号分隔的账户名字符串。默认情况下,这两个变量都是NULL,在这种情况下,不进行账户过滤,对所有账户进行审计。

audit_log_include_accountsaudit_log_exclude_accounts的修改仅影响在修改后创建的连接,而不影响现有连接。

示例:要仅为user1user2本地主机账户启用审计日志记录,请像这样设置audit_log_include_accounts系统变量:

SET GLOBAL audit_log_include_accounts = 'user1@localhost,user2@localhost';

audit_log_include_accountsaudit_log_exclude_accounts只能同时有一个为非NULL

  • 如果设置了audit_log_include_accounts,服务器会将audit_log_exclude_accounts设置为NULL

  • 如果您尝试设置audit_log_exclude_accounts,除非audit_log_include_accountsNULL,否则会出现错误。在这种情况下,您必须首先通过将其设置为NULL来清除audit_log_include_accounts

-- This sets audit_log_exclude_accounts to NULL
SET GLOBAL audit_log_include_accounts = *value*;

-- This fails because audit_log_include_accounts is not NULL
SET GLOBAL audit_log_exclude_accounts = *value*;

-- To set audit_log_exclude_accounts, first set
-- audit_log_include_accounts to NULL
SET GLOBAL audit_log_include_accounts = NULL;
SET GLOBAL audit_log_exclude_accounts = *value*;

如果检查任一变量的值,请注意SHOW VARIABLESNULL显示为空字符串。要将NULL显示为NULL,请改用SELECT

mysql> SHOW VARIABLES LIKE 'audit_log_include_accounts';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| audit_log_include_accounts |       |
+----------------------------+-------+
mysql> SELECT @@audit_log_include_accounts;
+------------------------------+
| @@audit_log_include_accounts |
+------------------------------+
| NULL                         |
+------------------------------+

如果用户名或主机名需要引用,因为它包含逗号、空格或其他特殊字符,请使用单引号引用。如果变量值本身用单引号引用,则每个内部单引号都要加倍或用反斜杠转义。以下语句分别为本地root账户启用审计日志记录,并且虽然引用样式不同,但是等效的:

SET GLOBAL audit_log_include_accounts = 'root@localhost';
SET GLOBAL audit_log_include_accounts = '''root''@''localhost''';
SET GLOBAL audit_log_include_accounts = '\'root\'@\'localhost\'';
SET GLOBAL audit_log_include_accounts = "'root'@'localhost'";

如果启用了ANSI_QUOTES SQL 模式,则最后一个语句将无效,因为在该模式下,双引号表示标识符引用,而不是字符串引用。

按状态进行传统事件过滤

要根据状态过滤审计事件,请在服务器启动或运行时设置以下系统变量。这些已弃用的变量仅适用于传统审计日志过滤。对于 JSON 审计日志过滤,不同的状态变量适用;请参阅 Audit Log Options and Variables。

  • audit_log_connection_policy:连接事件的记录策略

  • audit_log_statement_policy:语句事件的记录策略

每个变量都可以取值ALL(记录所有相关事件;这是默认值)、ERRORS(仅记录失败事件)或NONE(不记录事件)。例如,要记录所有语句事件但仅记录失败的连接事件,请使用以下设置:

SET GLOBAL audit_log_statement_policy = ALL;
SET GLOBAL audit_log_connection_policy = ERRORS;

另一个策略系统变量audit_log_policy可用,但不像audit_log_connection_policyaudit_log_statement_policy那样提供更多控制。它只能在服务器启动时设置。

注意

自 MySQL 8.0.34 起,audit_log_policy传统模式系统变量已弃用。

在运行时,它是一个只读变量。它可以取ALL(记录所有事件;这是默认值)、LOGINS(记录连接事件)、QUERIES(记录语句事件)或NONE(不记录事件)的值。对于这些值中的任何一个,审计日志插件都会记录所有选定的事件,不区分成功或失败。在启动时使用audit_log_policy的工作方式如下:

  • 如果您未设置audit_log_policy或将其设置为默认值ALL,则对于audit_log_connection_policyaudit_log_statement_policy的任何显式设置均按照指定的方式应用。如果未指定,则它们默认为ALL

  • 如果您将audit_log_policy设置为非ALL值,则该值优先,并用于设置audit_log_connection_policyaudit_log_statement_policy,如下表所示。如果您还将这些变量中的任一设置为非默认值ALL,服务器将向错误日志写入消息,指示它们的值被覆盖。

    启动时的 audit_log_policy 值 结果的 audit_log_connection_policy 值 结果的 audit_log_statement_policy 值
    LOGINS ALL NONE
    QUERIES NONE ALL
    NONE NONE NONE

原文:dev.mysql.com/doc/refman/8.0/en/audit-log-reference.html

8.4.5.11 审计日志参考

以下各节提供了 MySQL 企业审计元素的参考:

  • 审计日志表

  • 审计日志功能

  • 审计日志选项和变量参考

  • 审计日志选项和变量

  • 审计日志状态变量

要安装审计日志表和功能,请使用第 8.4.5.2 节,“安装或卸载 MySQL 企业审计”中提供的说明。除非安装了这些对象,否则audit_log插件将以传统模式运行(在 MySQL 8.0.34 中已弃用)。请参阅第 8.4.5.10 节,“传统模式审计日志过滤”。

审计日志表

MySQL 企业审计使用mysql系统数据库中的表来持久存储过滤器和用户帐户数据。只有具有该数据库权限的用户才能访问这些表。要使用不同的数据库,请在服务器启动时设置audit_log_database系统变量。这些表使用InnoDB存储引擎。

如果这些表缺失,audit_log插件将以(已弃用的)传统模式运行。请参阅第 8.4.5.10 节,“传统模式审计日志过滤”。

audit_log_filter表存储过滤器定义。该表具有以下列:

  • 名称

    过滤器名称。

  • FILTER

    与过滤器名称相关联的过滤器定义。定义存储为JSON值。

audit_log_user表存储用户帐户信息。该表具有以下列:

  • 用户

    帐户的用户名部分。对于帐户user1@localhostUSER部分是user1

  • HOST

    帐户的主机名部分。对于帐户user1@localhostHOST部分是localhost

  • FILTERNAME

    分配给帐户的过滤器名称。过滤器名称将帐户与audit_log_filter表中定义的过滤器关联起来。

审计日志功能

本节描述了每个审计日志功能的目的、调用顺序和返回值。有关这些功能可以在何种条件下调用的信息,请参阅第 8.4.5.7 节,“审计日志过滤”。

每个审计日志函数都会返回一个字符串,指示操作是否成功。OK表示成功。ERROR: *message*表示失败。

截至 MySQL 8.0.19,审计日志函数将字符串参数转换为utf8mb4,并且字符串返回值为utf8mb4字符串。在 MySQL 8.0.19 之前,审计日志函数将字符串参数视为二进制字符串(这意味着它们不区分大小写),并且字符串返回值为二进制字符串。

如果从mysql客户端调用审计日志函数,则二进制字符串结果将使用十六进制表示,具体取决于--binary-as-hex的值。有关该选项的更多信息,请参见第 6.5.1 节,“mysql — MySQL 命令行客户端”。

可用的审计日志函数包括:

  • audit_log_encryption_password_get([*keyring_id*])

    此函数从 MySQL 钥匙环中获取审计日志加密密码,必须启用,否则将出现错误。可以使用任何钥匙环组件或插件;有关说明,请参见第 8.4.4 节,“MySQL 钥匙环”。

    没有参数时,函数将检索当前加密密码作为二进制字符串。可以给定参数以指定要检索的哪个审计日志加密密码。参数必须是当前密码或存档密码的钥匙环 ID。

    有关审计日志加密的更多信息,请参见加密审计日志文件。

    参数:

    keyring_id:从 MySQL 8.0.17 开始,这个可选参数表示要检索的密码的钥匙环 ID。最大允许长度为 766 字节。如果省略,函数将检索当前密码。

    在 MySQL 8.0.17 之前,不允许有任何参数。该函数始终检索当前密码。

    返回值:

    成功的密码字符串(最多 766 字节),或失败时为NULL和错误。

    示例:

    检索当前密码:

    mysql> SELECT audit_log_encryption_password_get();
    +-------------------------------------+
    | audit_log_encryption_password_get() |
    +-------------------------------------+
    | secret                              |
    +-------------------------------------+
    

    要通过 ID 检索密码,可以通过查询性能模式keyring_keys表来确定存在哪些审计日志钥匙环 ID:

    mysql> SELECT KEY_ID FROM performance_schema.keyring_keys
           WHERE KEY_ID LIKE 'audit_log%'
           ORDER BY KEY_ID;
    +-----------------------------+
    | KEY_ID                      |
    +-----------------------------+
    | audit_log-20190415T152248-1 |
    | audit_log-20190415T153507-1 |
    | audit_log-20190416T125122-1 |
    | audit_log-20190416T141608-1 |
    +-----------------------------+
    mysql> SELECT audit_log_encryption_password_get('audit_log-20190416T125122-1');
    +------------------------------------------------------------------+
    | audit_log_encryption_password_get('audit_log-20190416T125122-1') |
    +------------------------------------------------------------------+
    | segreto                                                          |
    +------------------------------------------------------------------+
    
  • audit_log_encryption_password_set(*password*)

    将当前审计日志加密密码设置为参数,并将密码存储在 MySQL 钥匙环中。截至 MySQL 8.0.19,密码存储为utf8mb4字符串。在 MySQL 8.0.19 之前,密码以二进制形式存储。

    如果启用了加密,此函数将执行一个日志文件旋转操作,重命名当前日志文件,并开始一个新的日志文件,使用密码加密。必须启用密钥环,否则将出现错误。可以使用任何密钥环组件或插件;有关说明,请参见第 8.4.4 节,“MySQL 密钥环”。

    有关审计日志加密的更多信息,请参见加密审计日志文件。

    参数:

    password: 密码字符串。最大允许长度为 766 字节。

    返回值:

    成功返回 1,失败返回 0。

    示例:

    mysql> SELECT audit_log_encryption_password_set(*password*);
    +---------------------------------------------+
    | audit_log_encryption_password_set(*password*) |
    +---------------------------------------------+
    | 1                                           |
    +---------------------------------------------+
    
  • audit_log_filter_flush()

    调用任何其他过滤函数会立即影响操作审计日志过滤,并更新审计日志表。如果您改为直接修改这些表的内容,使用诸如INSERTUPDATEDELETE等语句,更改不会立即影响过滤。要刷新更改并使其生效,请调用audit_log_filter_flush()

    警告

    只有在直接修改审计表后,才应使用audit_log_filter_flush()来强制重新加载所有过滤器。否则,应避免使用此函数。实际上,这是使用UNINSTALL PLUGININSTALL PLUGIN卸载和重新加载audit_log插件的简化版本。

    audit_log_filter_flush()会影响所有当前会话,并将它们从先前的过滤器中分离。当前会话不再被记录,除非它们断开连接并重新连接,或执行更改用户操作。

    如果此函数失败,将返回错误消息,并且审计日志将被禁用,直到下一次成功调用audit_log_filter_flush()

    参数:

    无。

    返回值:

    一个指示操作是否成功的字符串。OK表示成功。ERROR: *message*表示失败。

    示例:

    mysql> SELECT audit_log_filter_flush();
    +--------------------------+
    | audit_log_filter_flush() |
    +--------------------------+
    | OK                       |
    +--------------------------+
    
  • audit_log_filter_remove_filter(*filter_name*)

    给定一个过滤器名称,从当前过滤器集中移除该过滤器。过滤器不存在也不会报错。

    如果已删除的过滤器分配给任何用户帐户,则这些用户将停止被过滤(它们将从audit_log_user表中删除)。停止过滤包括这些用户的任何当前会话:它们将从过滤器中分离,并且不再被记录。

    参数:

    • filter_name:指定过滤器名称的字符串。

    返回值:

    一个指示操作是否成功的字符串。OK表示成功。ERROR: *message*表示失败。

    示例:

    mysql> SELECT audit_log_filter_remove_filter('SomeFilter');
    +----------------------------------------------+
    | audit_log_filter_remove_filter('SomeFilter') |
    +----------------------------------------------+
    | OK                                           |
    +----------------------------------------------+
    
  • audit_log_filter_remove_user(*user_name*)

    给定用户账户名称,使用户不再分配到过滤器。如果用户没有分配过滤器,则不会出错。用户的当前会话过滤保持不受影响。如果存在默认账户过滤器,则使用默认账户过滤器过滤用户的新连接,否则不记录。

    如果名称为%,则函数会移除用于没有明确分配过滤器的任何用户账户的默认账户过滤器。

    参数:

    • user_name:用户账户名称,以*user_name*@*host_name*格式的字符串表示,或者使用%表示默认账户。

    返回值:

    一个指示操作是否成功的字符串。OK表示成功。ERROR: *message*表示失败。

    示例:

    mysql> SELECT audit_log_filter_remove_user('user1@localhost');
    +-------------------------------------------------+
    | audit_log_filter_remove_user('user1@localhost') |
    +-------------------------------------------------+
    | OK                                              |
    +-------------------------------------------------+
    
  • audit_log_filter_set_filter(*filter_name*, *definition*)

    给定过滤器名称和定义,将过滤器添加到当前过滤器集中。如果过滤器已经存在并且被当前会话使用,那么这些会话将与过滤器分离,并且不再记录。这是因为新的过滤器定义具有与先前 ID 不同的新过滤器 ID。

    参数:

    • filter_name:指定过滤器名称的字符串。

    • definition:指定过滤器定义的JSON值。

    返回值:

    一个指示操作是否成功的字符串。OK表示成功。ERROR: *message*表示失败。

    示例:

    mysql> SET @f = '{ "filter": { "log": false } }';
    mysql> SELECT audit_log_filter_set_filter('SomeFilter', @f);
    +-----------------------------------------------+
    | audit_log_filter_set_filter('SomeFilter', @f) |
    +-----------------------------------------------+
    | OK                                            |
    +-----------------------------------------------+
    
  • audit_log_filter_set_user(*user_name*, *filter_name*)

    给定用户账户名称和过滤器名称,将过滤器分配给用户。用户只能分配一个过滤器,因此如果用户已经分配了过滤器,则分配将被替换。用户的当前会话过滤保持不受影响。新连接将使用新的过滤器进行过滤。

    作为特例,名称%代表默认账户。该过滤器用于来自没有明确分配过滤器的任何用户账户的连接。

    参数:

    • user_name:用户账户名称,以*user_name*@*host_name*格式的字符串表示,或者使用%表示默认账户。

    • filter_name:指定过滤器名称的字符串。

    返回值:

    一个指示操作是否成功的字符串。OK表示成功。ERROR: *message*表示失败。

    示例:

    mysql> SELECT audit_log_filter_set_user('user1@localhost', 'SomeFilter');
    +------------------------------------------------------------+
    | audit_log_filter_set_user('user1@localhost', 'SomeFilter') |
    +------------------------------------------------------------+
    | OK                                                         |
    +------------------------------------------------------------+
    
  • audit_log_read([*arg*])

    读取审计日志并返回一个JSON 字符串结果。如果审计日志格式不是JSON,则会出错。

    没有参数或者一个JSON 哈希参数时,audit_log_read() 从审计日志中读取事件,并返回一个包含审计事件数组的JSON 字符串。哈希参数中的项会影响读取过程,稍后会描述。返回数组中的每个元素都是一个以JSON 哈希表示的事件,除了最后一个元素可能是一个JSON null 值,表示没有更多事件可供读取。

    使用由JSON null 值组成的参数时,audit_log_read() 将关闭当前读取序列。

    有关审计日志读取过程的更多详细信息,请参见第 8.4.5.6 节,“读取审计日志文件”。

    参数:

    要获取最近写入事件的书签,请调用audit_log_read_bookmark()

    arg: 参数是可选的。如果省略,函数将从当前位置读取事件。如果存在,参数可以是一个JSON null 值以关闭读取序列,或者一个JSON 哈希。在哈希参数中,项是可选的,并控制读取操作的方面,例如从哪个位置开始读取或者要读取多少事件。以下项是重要的(其他项将被忽略):

    • start: 审计日志中要读取的第一个事件的位置。位置以时间戳给出,并且从时间戳值之后发生的第一个事件开始读取。start 项的格式如下,其中value是一个字面时间戳值:

      "start": { "timestamp": "*value*" }
      

      start 项自 MySQL 8.0.22 版本开始允许使用。

    • timestampid: 要读取的第一个事件在审计日志中的位置。timestampid 项一起构成一个书签,唯一标识特定事件。如果audit_log_read() 参数包含任一项,则必须同时包含两项才能完全指定位置,否则会出错。

    • max_array_length: 从日志中读取的最大事件数。如果省略此项,则默认读取到日志末尾或者直到读取缓冲区已满为止。

    要指定给audit_log_read()的起始位置,传递一个包含start项或由时间戳id项组成的书签的哈希参数。如果哈希参数同时包含start项和书签,则会出现错误。

    如果哈希参数未指定起始位置,则从当前位置继续读取。

    如果时间戳值不包含时间部分,则假定时间部分为00:00:00

    返回值:

    如果调用成功,返回值是包含审核事件数组的JSON字符串,或者如果将其作为参数传递以关闭读取序列,则返回JSON null值。如果调用失败,返回值为NULL,并出现错误。

    示例:

    mysql> SELECT audit_log_read(audit_log_read_bookmark());
    +-----------------------------------------------------------------------+
    | audit_log_read(audit_log_read_bookmark())                             |
    +-----------------------------------------------------------------------+
    |  {"timestamp":"2020-05-18 22:41:24","id":0,"class":"connection", ... |
    +-----------------------------------------------------------------------+
    mysql> SELECT audit_log_read('null');
    +------------------------+
    | audit_log_read('null') |
    +------------------------+
    | null                   |
    +------------------------+
    

    注意:

    在 MySQL 8.0.19 之前,字符串返回值是二进制的[JSON字符串。有关将这些值转换为非二进制字符串的信息,请参见第 8.4.5.6 节,“读取审计日志文件”。

  • audit_log_read_bookmark()

    返回一个表示最近写入的审计日志事件的JSON字符串书签。如果审计日志格式不是JSON,则会出现错误。

    书签是一个包含时间戳id项的JSON哈希,用于唯一标识审核日志中事件的位置。适合传递给audit_log_read()以指示该函数开始读取的位置。

    有关审计日志读取过程的更多详细信息,请参见第 8.4.5.6 节,“读取审计日志文件”。

    参数:

    无。

    返回值:

    包含成功书签的JSON字符串,或包含失败的NULL和错误。

    示例:

    mysql> SELECT audit_log_read_bookmark();
    +-------------------------------------------------+
    | audit_log_read_bookmark()                       |
    +-------------------------------------------------+
    | { "timestamp": "2019-10-03 21:03:44", "id": 0 } |
    +-------------------------------------------------+
    

    注意:

    在 MySQL 8.0.19 之前,字符串返回值是二进制的JSON字符串。有关将这些值转换为非二进制字符串的信息,请参见第 8.4.5.6 节,“读取审计日志文件”。

  • audit_log_rotate()

    参数:

    无。

    返回值:

    重命名后的文件名。

    示例:

    mysql> SELECT audit_log_rotate();
    

    使用audit_log_rotate()需要AUDIT_ADMIN权��。

审计日志选项和变量参考

表 8.44 审计日志选项和变量参考

名称 命令行 选项文件 系统变量 状态变量 变量范围 动态
audit-log
审计日志缓冲区大小 全局
审计日志压缩 全局
审计日志连接策略 全局
当前审计日志会话 两者
审计日志当前大小 全局
审计日志数据库 全局
禁用审计日志 全局
审计日志加密 全局
审计日志事件最大丢弃大小 全局
审计日志事件 全局
已过滤审计日志事件 全局
已丢失审计日志事件 全局
已写入审计日志事件 全局
排除账户的审计日志 全局
审计日志文件 全局
审计日志过滤器 ID 两者
审计日志刷新 全局
审计日志刷新间隔秒数 全局
审计日志格式 全局
包含账户的审计日志 全局
审计日志最大大小 全局
审计日志密码历史保留天数 全局
审计日志策略 全局 ��
审计日志修剪秒数 全局
审计日志读取缓冲区大小 变化 变化
audit_log_rotate_on_size 全局
audit_log_statement_policy 全局
audit_log_strategy 全局
Audit_log_total_size 全局
Audit_log_write_waits 全局
名称 命令行 选项文件 系统变量 状态变量 变量范围 动态
审计日志选项和变量

本节描述了配置 MySQL Enterprise Audit 操作的命令选项和系统变量。如果在启动时指定的值不正确,audit_log 插件可能无法正确初始化,服务器也不会加载它。在这种情况下,服务器可能还会因为无法识别其他审计日志设置而产生错误消息。

要配置审计日志插件的激活,请使用此选项:

  • --audit-log[=*value*]

    命令行格式 --audit-log[=value]
    类型 枚举
    默认值 ON
    有效值 ON``OFF``FORCE``FORCE_PLUS_PERMANENT

    此选项控制服务器在启动时如何加载 audit_log 插件。只有在插件之前已经使用 INSTALL PLUGIN 注册过或者使用 --plugin-load--plugin-load-add 加载过插件时才可用。参见 Section 8.4.5.2, “Installing or Uninstalling MySQL Enterprise Audit”。

    选项值应该是插件加载选项中可用的值之一,如 Section 7.6.1, “Installing and Uninstalling Plugins” 中所述。例如,--audit-log=FORCE_PLUS_PERMANENT 告诉服务器加载插件并防止在服务器运行时被移除。

如果启用了审计日志插件,它会暴露几个系统变量,允许对日志进行控制:

mysql> SHOW VARIABLES LIKE 'audit_log%';
+--------------------------------------+--------------+
| Variable_name                        | Value        |
+--------------------------------------+--------------+
| audit_log_buffer_size                | 1048576      |
| audit_log_compression                | NONE         |
| audit_log_connection_policy          | ALL          |
| audit_log_current_session            | OFF          |
| audit_log_database                   | mysql        |
| audit_log_disable                    | OFF          |
| audit_log_encryption                 | NONE         |
| audit_log_exclude_accounts           |              |
| audit_log_file                       | audit.log    |
| audit_log_filter_id                  | 0            |
| audit_log_flush                      | OFF          |
| audit_log_flush_interval_seconds     | 0            |
| audit_log_format                     | NEW          |
| audit_log_format_unix_timestamp      | OFF          |
| audit_log_include_accounts           |              |
| audit_log_max_size                   | 0            |
| audit_log_password_history_keep_days | 0            |
| audit_log_policy                     | ALL          |
| audit_log_prune_seconds              | 0            |
| audit_log_read_buffer_size           | 32768        |
| audit_log_rotate_on_size             | 0            |
| audit_log_statement_policy           | ALL          |
| audit_log_strategy                   | ASYNCHRONOUS |
+--------------------------------------+--------------+

你可以在服务器启动时设置任何这些变量,有些变量可以在运行时设置。只能用于传统模式审计日志过滤的变量会有相应标注。

  • audit_log_buffer_size

    命令行格式 --audit-log-buffer-size=#
    系统变量 audit_log_buffer_size
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 1048576
    最小值 4096
    最大值(64 位平台) 18446744073709547520
    最大值(32 位平台) 4294967295
    单位 字节
    块大小 4096

    当审计日志插件异步写入事件到日志时,它使用一个缓冲区来存储事件内容以便写入。此变量控制该缓冲区的大小,以字节为单位。服务器将该值调整为 4096 的倍数。插件使用一个缓冲区,在初始化时分配,终止时删除。插件仅在日志记录是异步的情况下分配此缓冲区。

  • audit_log_compression

    命令行格式 --audit-log-compression=value
    系统变量 audit_log_compression
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值 NONE
    有效值 NONE``GZIP

    审计日志文件的压缩类型。允许的值为NONE(无压缩;默认值)���GZIP(GNU Zip 压缩)。有关更多信息,请参见压缩审计日志文件。

  • audit_log_connection_policy

    命令行格式 --audit-log-connection-policy=value
    已弃用 8.0.34
    系统变量 audit_log_connection_policy
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值 ALL
    有效值 ALL``ERRORS``NONE

    注意

    此已弃用的变量仅适用于传统模式审计日志过滤(参见第 8.4.5.10 节,“传统模式审计日志过滤”)。

    控制审计日志插件将连接事件写入其日志文件的策略。以下表格显示了允许的值。

    描述
    ALL 记录所有连接事件
    ERRORS 仅记录连接失败事件
    NONE 不记录连接事件

    注意

    在服务器启动时,如果还指定了audit_log_policy,则可能会覆盖对audit_log_connection_policy的任何显式值,如第 8.4.5.5 节,“配置审计日志特性”中所述。

  • audit_log_current_session

    系统变量 audit_log_current_session
    作用范围 全局,会话
    动态
    SET_VAR Hint Applies
    类型 布尔值
    默认值 取决于过滤策略

    当前会话是否启用审计日志记录。此变量的会话值只读。它在会话开始时根据audit_log_include_accountsaudit_log_exclude_accounts系统变量的值设置。审计日志插件使用会话值来确定是否为会话审计事件。(有一个全局值,但插件不使用它。)

  • audit_log_database

    命令行格式 --audit-log-database=value
    引入版本 8.0.33
    系统变量 audit_log_database
    作用范围 全局
    动态
    SET_VAR Hint Applies
    类型 字符串
    默认值 mysql

    指定audit_log插件用于查找其表的数据库。此变量只读。更多信息,请参见第 8.4.5.2 节,“安装或卸载 MySQL Enterprise Audit”。

  • audit_log_disable

    命令行格式 --audit-log-disable[={OFF|ON}]
    引入版本 8.0.28
    系统变量 audit_log_disable
    作用范围 全局
    动态
    SET_VAR Hint Applies
    类型 布尔值
    默认值 OFF

    允许禁用所有连接和已连接会话的审计日志记录。除了SYSTEM_VARIABLES_ADMIN权限外,禁用审计日志记录还需要AUDIT_ADMIN权限。请参见第 8.4.5.9 节,“禁用审计日志记录”。

  • audit_log_encryption

    命令行格式 --audit-log-encryption=value
    系统变量 audit_log_encryption
    作用范围 全局
    动态
    SET_VAR Hint Applies
    类型 枚举
    默认值 NONE
    有效值 NONE``AES

    审计日志文件的加密类型。允许的值为NONE(无加密;默认值)和AES(AES-256-CBC 密码加密)。有关更多信息,请参见加密审计日志文件。

  • audit_log_exclude_accounts

    命令行格式 --audit-log-exclude-accounts=value
    已弃用 8.0.34
    系统变量 audit_log_exclude_accounts
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 NULL

    注意

    此已弃用变量仅适用于传统模式审计日志过滤(请参见第 8.4.5.10 节,“传统模式审计日志过滤”)。

    不应记录事件的帐户。该值应为NULL或包含一个或多个逗号分隔帐户名称列表的字符串。有关更多信息,请参见第 8.4.5.7 节,“审计日志过滤”。

    audit_log_exclude_accounts的修改仅影响在修改后创建的连接,而不影响现有连接。

  • audit_log_file

    命令行格式 --audit-log-file=file_name
    系统变量 audit_log_file
    范围 全��
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 audit.log

    审计日志插件写入事件的文件的基本名称和后缀。默认值为audit.log,无论日志格式如何。要使名称后缀与格式对应,必须显式设置名称,选择不同的后缀(例如,对于 XML 格式为audit.xml,对于 JSON 格式为audit.json)。

    如果audit_log_file的值是相对路径名,则插件将其解释为相对于数据目录的路径。如果该值是完整路径名,则插件将直接使用该值。如果希望将审计文件定位到单独的文件系统或目录上,完整路径名可能会很有用。出于安全原因,将审计日志文件写入仅对 MySQL 服务器和有合理查看日志原因的用户可访问的目录。

    有关审计日志插件如何解释audit_log_file值以及插件初始化和终止时发生的文件重命名规则的详细信息,请参见审计日志文件命名约定。

    审计日志插件使用包含审计日志文件的目录(从audit_log_file的值确定)作为可读取审计日志文件的位置。从这些日志文件和当前文件中,插件构建了一个列表,其中包含适用于审计日志标记和读取功能的文件。参见第 8.4.5.6 节,“读取审计日志文件”。

  • audit_log_filter_id

    系统变量 audit_log_filter_id
    作用域 全局,会话
    动态
    SET_VAR提示适用
    类型 整数
    默认值 1
    最小值 0
    最大值 4294967295

    此变量的会话值表示当前会话的内部维护的审计过滤器的 ID。值为 0 表示会话未分配任何过滤器。

  • audit_log_flush

    系统变量 audit_log_flush
    作用域 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 OFF

    注意

    audit_log_flush变量在 MySQL 8.0.31 中已被弃用;预计在未来的 MySQL 版本中将不再支持它。它已被audit_log_rotate()函数取代。

    如果audit_log_rotate_on_size为 0,则自动审计日志文件轮换被禁用,只有在手动执行时才会发生轮换。在这种情况下,通过将audit_log_flush设置为 1 或ON来启用它会导致审计日志插件关闭并重新打开其日志文件以刷新它。(变量值保持为OFF,因此您无需在再次启用它以执行另一个刷新之前显式禁用它。)有关更多信息,请参见第 8.4.5.5 节,“配置审计日志特性”。

  • audit_log_flush_interval_seconds

    命令行格式 --audit-log-flush-interval-seconds[=value]
    引入版本 8.0.34
    系统变量 audit_log_flush_interval_seconds
    范围 全局
    动态
    SET_VAR 提示适用
    类型 无符号长整型
    默认值 0
    最大值(Windows) 4294967295
    最大值(其他) 18446744073709551615
    单位

    此系统变量取决于必须安装和启用的scheduler组件(请参阅第 7.5.5 节,“调度器组件”)。要检查组件的状态:

    SHOW VARIABLES LIKE 'component_scheduler%';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------|
    | component_scheduler.enabled | On    |
    +-----------------------------+-------+
    

    audit_log_flush_interval_seconds的值为零(默认值)时,即使启用了scheduler组件(ON),也不会自动刷新权限。

    不允许值为159;相反,这些值会自动调整为60,并且服务器会发出警告。大于60的值定义了scheduler组件从启动或上一次执行开始等待多少秒,直到尝试安排另一个执行。

    要将此全局系统变量持久化到mysqld-auto.cnf文件中而不设置全局变量运行时值,请在变量名称之前加上PERSIST_ONLY关键字或@@PERSIST_ONLY.限定符。

  • audit_log_format

    命令行格式 --audit-log-format=value
    系统变量 audit_log_format
    范围 全局
    动态
    SET_VAR 提示适用
    类型 枚举
    默认值 NEW
    有效值 OLD``NEW``JSON

    审计日志文件格式。允许的值为OLD(旧式 XML)、NEW(新式 XML;默认值)和JSON。有关每种格式的详细信息,请参阅第 8.4.5.4 节,“审计日志文件格式”。

  • audit_log_format_unix_timestamp

    命令行格式 --audit-log-format-unix-timestamp[={OFF|ON}]
    引入版本 8.0.26
    系统变量 audit_log_format_unix_timestamp
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    此变量仅适用于 JSON 格式的审计日志输出。当为真时,启用此变量会导致每个日志文件记录包含一个time字段。该字段值是一个整数,表示生成审计事件的日期和时间的 UNIX 时间戳值。

    在运行时更改此变量的值会导致日志文件轮换,以便对于给定的 JSON 格式日志文件,文件中的所有记录要么包含time字段,要么不包含。

    在运行时设置audit_log_format_unix_timestamp的值需要AUDIT_ADMIN权限,除了通常需要设置全局系统变量运行时值的SYSTEM_VARIABLES_ADMIN权限(或已弃用的SUPER权限)。

  • audit_log_include_accounts

    命令行格式 --audit-log-include-accounts=value
    已弃用 8.0.34
    系统变量 audit_log_include_accounts
    范围 全局
    动态
    SET_VAR提示适用
    类型 字符串
    默认值 NULL

    注意

    此已弃用变量仅适用于传统模式的审计日志过滤(参见第 8.4.5.10 节,“传统模式审计日志过滤”)。

    应记录事件的帐户。该值应为NULL或包含一个或多个逗号分隔帐户名称列表的字符串。有关更多信息,请参见第 8.4.5.7 节,“审计日志过滤”。

    audit_log_include_accounts的修改仅影响在修改后创建的连接,而不影响现有连接。

  • audit_log_max_size

    命令行格式 --audit-log-max-size=#
    引入 8.0.26
    系统变量 audit_log_max_size
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值(Windows) 4294967295
    最大值(其他) 18446744073709551615
    单位 字节
    块大小 4096

    audit_log_max_size涉及仅支持 JSON 格式日志文件的日志文件修剪。它控制基于组合日志文件大小的修剪:

    • 值为 0(默认)会禁用基于大小的修剪。不强制执行大小限制。

    • 值大于 0 会启用基于大小的修剪。该值是超过该值后日志文件变得需要修剪的组合大小。

    如果将audit_log_max_size设置为不是 4096 的倍数的值,则会被截断为最接近的倍数。特别是,将其设置为小于 4096 的值会将其设置为 0,不会发生基于大小的修剪。

    如果audit_log_max_sizeaudit_log_rotate_on_size都大于 0,则audit_log_max_size应该大于audit_log_rotate_on_size的值的 7 倍以上。否则,会向服务器错误日志写入警告,因为在这种情况下,基于大小的修剪的“粒度”可能不足以防止每次发生时删除所有或大部分旋转的日志文件。

    注意

    设置audit_log_max_size本身并不足以导致日志文件修剪,因为修剪算法同时使用audit_log_rotate_on_sizeaudit_log_max_sizeaudit_log_prune_seconds。详情请参见审计日志文件的空间管理。

  • audit_log_password_history_keep_days

    命令行格式 --audit-log-password-history-keep-days=#
    引入版本 8.0.17
    系统变量 audit_log_password_history_keep_days
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 4294967295
    单位

    审计日志插件使用存储在 MySQL 密钥环中的加密密码实现日志文件加密(请参阅加密审计日志文件)。该插件还实现了密码历史记录,包括密码存档和过期(删除)。

    当审计日志插件创建新的加密密码时,它会存档先前的密码(如果存在),以供以后使用。audit_log_password_history_keep_days变量控制过期存档密码的自动删除。其值表示存档的审计日志加密密码在多少天后被删除。默认值为 0,禁用密码过期:密码保留期永远。

    在以下情况下创建新的审计日志加密密码:

    • 在插件初始化期间,如果插件发现启用了日志文件加密,则会检查密钥环是否包含审计日志加密密码。如果没有,则插件会自动生成一个随机初始加密密码。

    • 当调用audit_log_encryption_password_set()函数设置特定密码时。

    在每种情况下,插件将新密码存储在密钥环中,并用它来加密新的日志文件。

    在以下情况下移除过期的审计日志加密密码:

    • 在插件初始化期间。

    • 当调用audit_log_encryption_password_set()函数时。

    • audit_log_password_history_keep_days的运行时值从当前值更改为大于 0 的值时。运行时值更改发生在使用GLOBALPERSIST关键字的SET语句,但不适用于PERSIST_ONLY关键字。PERSIST_ONLY将变量设置写入mysqld-auto.cnf,但不影响运行时值。

    当密码移除发生时,当前值audit_log_password_history_keep_days决定要移除哪些密码:

    • 如果值为 0,则插件不会删除任何密码。

    • 如果值为N > 0,则插件会删除超过N天的密码。

    注意

    注意不要过期仍然需要读取已归档的加密日志文件的旧密码。

    如果通常禁用密码过期(即audit_log_password_history_keep_days的值为 0),可以通过临时分配大于零的值来执行按需清理操作。例如,要使超过 365 天的密码过期,请执行以下操作:

    SET GLOBAL audit_log_password_history_keep_days = 365;
    SET GLOBAL audit_log_password_history_keep_days = 0;
    

    设置运行时值audit_log_password_history_keep_days需要AUDIT_ADMIN权限,除了通常需要设置全局系统变量运行时值的SYSTEM_VARIABLES_ADMIN权限(或已弃用的SUPER权限)。

  • audit_log_policy

    命令行格式 --audit-log-policy=value
    已弃用 8.0.34
    系统变量 audit_log_policy
    范围 全局
    动态
    SET_VAR提示适用
    类型 枚举
    默认值 ALL
    有效值 ALL``LOGINS``QUERIES``NONE

    注意

    此弃用变量仅适用于传统模式审计日志过滤(参见第 8.4.5.10 节,“传统模式审计日志过滤”)。

    控制审计日志插件将事件写入其日志文件的策略。以下表格显示了允许的值。

    描述
    ALL 记录所有事件
    LOGINS 仅记录登录事件
    QUERIES 仅记录查询事件
    NONE 什么都不记录(禁用审计流)

    audit_log_policy只能在服务器启动时设置。在运行时,它是一个只读变量。另外两个系统变量,audit_log_connection_policyaudit_log_statement_policy,提供对日志记录策略的更精细控制,可以在启动时或运行时设置。如果在启动时使用audit_log_policy而不是其他两个变量,则服务器会使用其值来设置这些变量。有关策略变量及其交互的更多信息,请参见第 8.4.5.5 节,“配置审计日志特性”。

  • audit_log_prune_seconds

    命令行格式 --audit-log-prune-seconds=#
    引入版本 8.0.24
    系统变量 audit_log_prune_seconds
    范围 全局
    动态
    SET_VAR提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值(Windows) 4294967295
    最大值(其他) 18446744073709551615
    单位 字节

    audit_log_prune_seconds涉及审计日志文件修剪,仅支持 JSON 格式的日志文件。它根据日志文件的年龄控制修剪:

    • 值为 0(默认值)会禁用基于年龄的修剪。不强制执行年龄限制。

    • 值大于 0 会启用基于年龄的修剪。该值是日志文件变得需要修剪的秒数。

    注意

    单独设置audit_log_prune_seconds 是不足以导致日志文件修剪发生的,因为修剪算法同时使用audit_log_rotate_on_sizeaudit_log_max_sizeaudit_log_prune_seconds。有关详细信息,请参见 审计日志文件的空间管理。

  • audit_log_read_buffer_size

    命令行格式 --audit-log-read-buffer-size=#
    系统变量 audit_log_read_buffer_size
    范围 (≥ 8.0.12) 全局, 会话
    范围 (8.0.11) 全局
    动态 (≥ 8.0.12)
    动态 (8.0.11)
    SET_VAR 提示适用
    类型 整数
    默认值 (≥ 8.0.12) 32768
    默认值 (8.0.11) 1048576
    最小值 (≥ 8.0.12) 32768
    最小值 (8.0.11) 1024
    最大值 4194304
    单位 字节

    从审计日志文件中读取的缓冲区大小,以字节为单位。audit_log_read() 函数最多读取这么多字节。仅支持 JSON 日志格式的日志文件读取。有关更多信息,请参见 第 8.4.5.6 节,“读取审计日志文件”。

    截至 MySQL 8.0.12,此变量默认为 32KB,并可在运行时设置。每个客户端应适当设置其audit_log_read_buffer_size的会话值,以供其使用audit_log_read()。在 MySQL 8.0.12 之前,audit_log_read_buffer_size 默认为 1MB,影响所有客户端,并且只能在服务器启动时更改。

  • audit_log_rotate_on_size

    命令行格式 --audit-log-rotate-on-size=#
    系统变量 audit_log_rotate_on_size
    范围 全局
    动态
    SET_VAR 提示适用
    类型 整数
    默认值 0
    最小值 0
    最大值 18446744073709551615
    单位 字节
    块大小 4096

    如果audit_log_rotate_on_size为 0,则审计日志插件不执行基于大小的自动日志文件轮换。如果要进行旋转,必须手动执行;请参见手动审计日志文件旋转(MySQL 8.0.31 之前)。

    如果audit_log_rotate_on_size大于 0,则会发生基于大小的自动日志文件轮换。每当写入日志文件导致其大小超过audit_log_rotate_on_size值时,审计日志插件会重命名当前日志文件,并使用原始名称打开一个新的当前日志文件。

    如果将audit_log_rotate_on_size设置为不是 4096 的倍数的值,则会将其截断为最接近的倍数。特别是,将其设置为小于 4096 的值会将其设置为 0,并且不会发生旋转,除非手动执行。

    注意

    audit_log_rotate_on_size控制是否发生审计日志文件轮换。它还可以与audit_log_max_sizeaudit_log_prune_seconds一起用于配置旋转 JSON 格式日志文件的修剪。有关详细信息,请参见审计日志文件的空间管理。

  • audit_log_statement_policy

    命令行格式 --audit-log-statement-policy=value
    已弃用 8.0.34
    系统变量 audit_log_statement_policy
    范围 全局
    动态
    SET_VAR提示适用
    类型 枚举
    默认值 ALL
    有效值 ALL``ERRORS``NONE

    注意

    此已弃用的变量仅适用于传统模式审计日志过滤(参见第 8.4.5.10 节,“传统模式审计日志过滤”)。

    控制审计日志插件如何将语句事件写入其日志文件的策略。以下表格显示了允许的值。

    描述
    ALL 记录所有语句事件
    ERRORS 仅记录失败的语句事件
    NONE 不记录语句事件

    注意

    在服务器启动时,如果还指定了audit_log_policy,则可以覆盖为audit_log_statement_policy给出的任何显式值,如第 8.4.5.5 节,“配置审计日志特性”中所述。

  • audit_log_strategy

    命令行格式 --audit-log-strategy=value
    系统变量 audit_log_strategy
    范围 全局
    动态
    SET_VAR提示适用
    类型 枚举
    默认值 ASYNCHRONOUS
    有效值 ASYNCHRONOUS``PERFORMANCE``SEMISYNCHRONOUS``SYNCHRONOUS

    审计日志插件使用的记录方法。允许使用以下策略值:

    • ASYNCHRONOUS:异步记录。等待输出缓冲区中的空间。

    • PERFORMANCE:异步记录。在输出缓冲区中没有足够空间的请求将被丢弃。

    • SEMISYNCHRONOUS:同步记录。允许操作系统进行缓存。

    • SYNCHRONOUS:同步记录。在每个请求后调用sync()

审计日志状态变量

如果启用了审计日志插件,则会公开几个提供操作信息的状态变量。这些变量适用于遗留模式审计过滤(在 MySQL 8.0.34 中已弃用)和 JSON 模式审计过滤。

  • Audit_log_current_size

    当前审计日志文件的大小。当事件写入日志时,该值会增加,并在日志轮换时重置为 0。

  • Audit_log_event_max_drop_size

    性能记录模式中最大丢弃事件的大小。有关记录模式的描述,请参见第 8.4.5.5 节,“配置审计日志特性”。

  • Audit_log_events

    由审计日志插件处理的事件数量,无论是否根据过滤策略写入日志(参见第 8.4.5.5 节,“配置审计日志特性”)。

  • Audit_log_events_filtered

    基于过滤策略(参见第 8.4.5.5 节,“配置审计日志特性”),由审计日志插件处理的事件数量被过滤(未写入日志)。

  • Audit_log_events_lost

    在性能记录模式下丢失的事件数量,因为事件大于可用的审计日志缓冲区空间。此值可能有助于评估如何设置audit_log_buffer_size以调整性能模式的缓冲区大小。有关记录模式的描述,请参见第 8.4.5.5 节,“配置审计日志特性”。

  • Audit_log_events_written

    写入审计日志的事件数量。

  • Audit_log_total_size

    所有审计日志文件中写入的事件总大小。与Audit_log_current_size不同,Audit_log_total_size的值在日志轮换时也会增加。

  • Audit_log_write_waits

    在异步记录模式下,事件必须等待审计日志缓冲区中的空间的次数。有关记录模式的描述,请参见第 8.4.5.5 节,“配置审计日志特性”。

原文:dev.mysql.com/doc/refman/8.0/en/audit-log-restrictions.html

8.4.5.12 审计日志限制

MySQL Enterprise Audit 受到以下一般限制:

  • 仅记录 SQL 语句。通过非 SQL API(如 memcached、Node.JS 和 NDB API)进行的更改不会被记录。

  • 仅记录顶层语句,不记录存储程序内部的语句,如触发器或存储过程中的语句。

  • 诸如 LOAD DATA 这类语句引用的文件内容不会被记录。

NDB 集群。 可以在 MySQL NDB 集群中使用 MySQL Enterprise Audit,但需符合以下条件:

  • 所有要记录的更改必须使用 SQL 接口完成。使用非 SQL 接口进行的更改(如 NDB API、memcached 或 ClusterJ 提供的接口)不会被记录。

  • 插件必须安装在用于在集群上执行 SQL 的每个 MySQL 服务器上。

  • 审计插件数据必须在用于集群的所有 MySQL 服务器之间进行聚合。这种聚合是应用程序或用户的责任。

8.4.6 审计消息组件

原文:dev.mysql.com/doc/refman/8.0/en/audit-api-message-emit.html

截至 MySQL 8.0.14,audit_api_message_emit 组件使应用程序能够使用 audit_api_message_emit_udf() 函数将自己的消息事件添加到审计日志中。

audit_api_message_emit 组件与所有类型为审计的插件合作。为了具体起见,示例使用了第 8.4.5 节,“MySQL 企业审计”中描述的 audit_log 插件。

  • 安装或卸载审计消息组件

  • 审计消息函数

安装或卸载审计消息组件

要使服务器可用,组件库文件必须位于 MySQL 插件目录中(由 plugin_dir 系统变量命名的目录)。如果需要,通过在服务器启动时设置 plugin_dir 的值来配置插件目录位置。

要安装 audit_api_message_emit 组件,请使用以下语句:

INSTALL COMPONENT "file://component_audit_api_message_emit";

组件安装是一次性操作,不需要每次服务器启动都执行。INSTALL COMPONENT 加载组件,并在 mysql.component 系统表中注册它,以便在后续服务器启动时加载它。

要卸载 audit_api_message_emit 组件,请使用以下语句:

UNINSTALL COMPONENT "file://component_audit_api_message_emit";

UNINSTALL COMPONENT 卸载组件,并从 mysql.component 系统表中注销它,以使其在后续服务器启动时不加载。

因为安装和卸载 audit_api_message_emit 组件会安装和卸载组件实现的 audit_api_message_emit_udf() 函数,所以不需要使用 CREATE FUNCTIONDROP FUNCTION 来执行此操作。

审计消息函数

本节描述了 audit_api_message_emit 组件实现的 audit_api_message_emit_udf() 函数。

在使用审计消息函数之前,请根据安装或卸载审计消息组件中提供的说明安装审计消息组件。

  • audit_api_message_emit_udf(*component*, *producer*, *message*[, *key*, *value*] ...)

    向审计日志添加消息事件。消息事件包括调用者选择的组件、生产者和消息字符串,以及可选的一组键值对。

    由此函数发布的事件发送到所有已启用的审计类型插件,每个插件根据自己的规则处理事件。如果未启用任何审计类型的插件,则发布事件不会产生任何效果。

    参数:

    • component: 一个指定组件名称的字符串。

    • producer: 一个指定生产者名称的字符串。

    • message: 一个指定事件消息的字符串。

    • key, value: 事件可能包括 0 或多个键值对,指定任意应用程序提供的数据映射。每个 key 参数是一个指定其紧随其后的 value 参数名称的字符串。每个 value 参数指定其紧随其后的 key 参数的值。每个 value 可以是字符串或数值,或 NULL

    返回值:

    字符串 OK 表示成功。如果函数失败,则会发生错误。

    示例:

    mysql> SELECT audit_api_message_emit_udf('component_text',
                                             'producer_text',
                                             'message_text',
                                             'key1', 'value1',
                                             'key2', 123,
                                             'key3', NULL) AS 'Message';
    +---------+
    | Message |
    +---------+
    | OK      |
    +---------+
    

    附加信息:

    audit_api_message_emit_udf() 接收到的事件由每个启用的审计类型插件以特定于插件的格式记录。例如,audit_log 插件(参见 Section 8.4.5, “MySQL Enterprise Audit”)根据由 audit_log_format 系统变量配置的日志格式记录消息值,具体取决于配置的日志格式:

    • JSON 格式(audit_log_format=JSON):

      {
        ...
        "class": "message",
        "event": "user",
        ...
        "message_data": {
          "component": "component_text",
          "producer": "producer_text",
          "message": "message_text",
          "map": {
            "key1": "value1",
            "key2": 123,
            "key3": null
          }
        }
      }
      
    • 新式 XML 格式(audit_log_format=NEW):

      <AUDIT_RECORD>
       ...
       <NAME>Message</NAME>
       ...
       <COMMAND_CLASS>user</COMMAND_CLASS>
       <COMPONENT>component_text</COMPONENT>
       <PRODUCER>producer_text</PRODUCER>
       <MESSAGE>message_text</MESSAGE>
       <MAP>
         <ELEMENT>
           <KEY>key1</KEY>
           <VALUE>value1</VALUE>
         </ELEMENT>
         <ELEMENT>
           <KEY>key2</KEY>
           <VALUE>123</VALUE>
         </ELEMENT>
         <ELEMENT>
           <KEY>key3</KEY>
           <VALUE/>
         </ELEMENT>
       </MAP>
      </AUDIT_RECORD>
      
    • 旧式 XML 格式(audit_log_format=OLD):

      <AUDIT_RECORD
        ...
        NAME="Message"
        ...
        COMMAND_CLASS="user"
        COMPONENT="component_text"
        PRODUCER="producer_text"
        MESSAGE="message_text"/>
      

      注意

      以旧式 XML 格式记录的消息事件不包括键值映射,因为该格式施加的表现约束。

    audit_api_message_emit_udf() 发布的消息具有 MYSQL_AUDIT_MESSAGE_CLASS 的事件类别和 MYSQL_AUDIT_MESSAGE_USER 的子类别。(内部生成的审计消息具有相同的类别和 MYSQL_AUDIT_MESSAGE_INTERNAL 的子类别;目前未使用此子类别。)要在 audit_log 过滤规则中引用此类事件,请使用具有 name 值为 messageclass 元素。例如:

    {
      "filter": {
        "class": {
          "name": "message"
        }
      }
    }
    

    如果需要区分用户生成的和内部生成的消息事件,请将 subclass 值与 userinternal 进行测试。

    不支持基于键值映射内容的过滤。

    有关编写过滤规则的信息,请���阅 Section 8.4.5.7, “Audit Log Filtering”。

8.4.7 MySQL 企业防火墙

原文:dev.mysql.com/doc/refman/8.0/en/firewall.html

8.4.7.1 MySQL 企业防火墙元素

8.4.7.2 安装或卸载 MySQL 企业防火墙

8.4.7.3 使用 MySQL 企业防火墙

8.4.7.4 MySQL 企业防火墙参考

注意

MySQL 企业防火墙是 MySQL 企业版中包含的一个扩展,是一款商业产品。要了解更多关于商业产品的信息,请参见www.mysql.com/products/

MySQL 企业版包括 MySQL 企业防火墙,这是一个应用级防火墙,允许数据库管理员根据匹配接受的语句模式列表来允许或拒绝 SQL 语句的执行。这有助于加固 MySQL 服务器,防止 SQL 注入等攻击或试图利用应用程序以外的合法查询工作负载特征。

注册到防火墙的每个 MySQL 账户都有自己的语句允许列表,可以根据账户进行定制保护。对于给定的账户,防火墙可以在记录、保护或检测模式下运行,用于训练接受的语句模式、主动保护不可接受的语句或被动检测不可接受的语句。该图示说明了防火墙在每种模式下如何处理传入的语句。

图 8.1 MySQL 企业防火墙操作

流程图显示 MySQL 企业防火墙如何在记录、保护和检测模式下处理传入的 SQL 语句。

以下各节描述了 MySQL 企业防火墙的元素,讨论了如何安装和使用它,并为其元素提供参考信息。

原文:dev.mysql.com/doc/refman/8.0/en/firewall-elements.html

8.4.7.1 MySQL 企业防火墙的元素

MySQL 企业防火墙基于一个包含以下元素的插件库:

  • 一个名为MYSQL_FIREWALL的服务器端插件在 SQL 语句执行之前检查,并根据注册的防火墙配置文件,决定是否执行或拒绝每个语句。

  • MYSQL_FIREWALL插件,以及名为MYSQL_FIREWALL_USERSMYSQL_FIREWALL_WHITELIST的服务器端插件实现了性能模式和INFORMATION_SCHEMA表,提供了对注册配置文件的视图。

  • 配置文件在内存中缓存以提高性能。mysql系统数据库中的表提供了防火墙数据的后备存储,以确保配置文件在服务器重新启动时持久化。

  • 存储过程执行诸如注册防火墙配置文件、建立其操作模式以及管理缓存与持久存储之间的防火墙数据传输等任务。

  • 管理功能提供了一个 API 用于较低级别的任务,比如将缓存与持久存储同步。

  • 系统变量使防火墙配置生效,状态变量提供运行时操作信息。

  • FIREWALL_ADMINFIREWALL_USER权限使用户能够管理任何用户的防火墙规则,以及他们自己的防火墙规则。

  • FIREWALL_EXEMPT权限(自 MySQL 8.0.27 起可用)免除用户的防火墙限制。例如,对于配置防火墙的任何数据库管理员来说,这是有用的,以避免错误配置导致管理员被锁定并无法执行语句的可能性。

原文:dev.mysql.com/doc/refman/8.0/en/firewall-installation.html

8.4.7.2 安装或卸载 MySQL 企业防火墙

MySQL 企业防火墙安装是一次性操作,安装了 第 8.4.7.1 节,“MySQL 企业防火墙的元素” 中描述的元素。安装可以使用图形界面或手动进行:

  • 在 Windows 上,MySQL 安装程序包括一个选项,可以为您启用 MySQL 企业防火墙。

  • MySQL Workbench 6.3.4 或更高版本可以安装 MySQL 企业防火墙,启用或禁用已安装的防火墙,或卸载防火墙。

  • 手动安装 MySQL 企业防火墙涉及运行位于 MySQL 安装的 share 目录中的脚本。

重要

在按照本节的说明之前,请阅读整个部分。根据您的环境,步骤的某些部分可能有所不同。

注意

如果安装了 MySQL 企业防火墙,即使禁用了,也会带来一些最小的开销。为避免这种开销,请不要安装防火墙,除非您打算使用它。

有关使用说明,请参阅 第 8.4.7.3 节,“使用 MySQL 企业防火墙”。有关参考信息,请参阅 第 8.4.7.4 节,“MySQL 企业防火墙参考”。

  • 安装 MySQL 企业防火墙

  • 卸载 MySQL 企业防火墙

安装 MySQL 企业防火墙

如果 MySQL 企业防火墙已经从较旧版本的 MySQL 安装,使用本节后面给出的说明卸载它,然后在安装当前版本之前重新启动服务器。在这种情况下,还需要重新注册您的配置。

在 Windows 上,您可以使用 MySQL 安装程序来安装 MySQL 企业防火墙,如 图 8.2,“Windows 上的 MySQL 企业防火墙安装” 所示。勾选启用 MySQL 企业防火墙复选框。(为网络访问打开防火墙端口有不同的目的。它指的是 Windows 防火墙,并控制 Windows 是否阻止 MySQL 服务器用于客户端连接的 TCP/IP 端口。)

重要

对于使用 MySQL 安装程序安装的 MySQL 8.0.19 存在一个问题,如果在服务器配置步骤中选择了 MySQL 企业防火墙,则会阻止服务器启动。如果服务器启动操作失败,请单击“取消”以结束配置过程并返回仪表板。您必须卸载服务器。

解决方法是在没有选择 MySQL 企业防火墙的情况下运行 MySQL 安装程序。(即,不要选择启用 MySQL 企业防火墙复选框。)然后按照本节后面的手动安装说明安装 MySQL 企业防火墙。这个问题在 MySQL 8.0.20 中已经得到修正。

图 8.2 Windows 上的 MySQL 企业防火墙安装

内容在周围的文本中描述。

要使用 MySQL Workbench 6.3.4 或更高版本安装 MySQL 企业防火墙,请参阅 MySQL 企业防火墙界面。

要手动安装 MySQL 企业防火墙,请查看 MySQL 安装的share目录,并选择适合您平台的脚本。可用的脚本在用于引用脚本的文件名上有所不同:

  • win_install_firewall.sql

  • linux_install_firewall.sql

安装脚本在默认数据库mysql中创建存储过程。在命令行上运行脚本如下。这里的示例使用 Linux 安装脚本。对于您的系统进行适当的替换。

$> mysql -u root -p < linux_install_firewall.sql
Enter password: *(enter root password here)*

注意

要在源/副本复制、组复制或 InnoDB 集群的上下文中使用 MySQL 企业防火墙,必须在在源节点上运行安装脚本之前准备好副本节点。这是必要的,因为脚本中的INSTALL PLUGIN语句不会被复制。

  1. 在每个副本节点上,从安装脚本中提取INSTALL PLUGIN语句,并手动执行它们。

  2. 在源节点上,按照前面描述的方式运行安装脚本。

使用图形界面或手动安装 MySQL 企业防火墙应该启用防火墙。要验证,请连接到服务器并执行此语句:

mysql> SHOW GLOBAL VARIABLES LIKE 'mysql_firewall_mode';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| mysql_firewall_mode | ON    |
+---------------------+-------+

如果插件初始化失败,请检查服务器错误日志以获取诊断消息。

卸载 MySQL 企业防火墙

MySQL 企业防火墙可以使用 MySQL Workbench 或手动卸载。

要使用 MySQL Workbench 6.3.4 或更高版本卸载 MySQL 企业防火墙,请参阅 MySQL 企业防火墙界面,在第三十三章,MySQL Workbench中。

要手动卸载 MySQL 企业防火墙,请执行以下语句。语句使用IF EXISTS,因为根据先前安装的防火墙版本,一些对象可能不存在,或者通过卸载安装它们的插件而被隐式删除。

DROP TABLE IF EXISTS mysql.firewall_group_allowlist;
DROP TABLE IF EXISTS mysql.firewall_groups;
DROP TABLE IF EXISTS mysql.firewall_membership;
DROP TABLE IF EXISTS mysql.firewall_users;
DROP TABLE IF EXISTS mysql.firewall_whitelist;

UNINSTALL PLUGIN MYSQL_FIREWALL;
UNINSTALL PLUGIN MYSQL_FIREWALL_USERS;
UNINSTALL PLUGIN MYSQL_FIREWALL_WHITELIST;

DROP FUNCTION IF EXISTS firewall_group_delist;
DROP FUNCTION IF EXISTS firewall_group_enlist;
DROP FUNCTION IF EXISTS mysql_firewall_flush_status;
DROP FUNCTION IF EXISTS normalize_statement;
DROP FUNCTION IF EXISTS read_firewall_group_allowlist;
DROP FUNCTION IF EXISTS read_firewall_groups;
DROP FUNCTION IF EXISTS read_firewall_users;
DROP FUNCTION IF EXISTS read_firewall_whitelist;
DROP FUNCTION IF EXISTS set_firewall_group_mode;
DROP FUNCTION IF EXISTS set_firewall_mode;

DROP PROCEDURE IF EXISTS mysql.sp_firewall_group_delist;
DROP PROCEDURE IF EXISTS mysql.sp_firewall_group_enlist;
DROP PROCEDURE IF EXISTS mysql.sp_reload_firewall_group_rules;
DROP PROCEDURE IF EXISTS mysql.sp_reload_firewall_rules;
DROP PROCEDURE IF EXISTS mysql.sp_set_firewall_group_mode;
DROP PROCEDURE IF EXISTS mysql.sp_set_firewall_group_mode_and_user;
DROP PROCEDURE IF EXISTS mysql.sp_set_firewall_mode;
DROP PROCEDURE IF EXISTS mysql.sp_migrate_firewall_user_to_group;

原文:dev.mysql.com/doc/refman/8.0/en/firewall-usage.html

8.4.7.3 使用 MySQL 企业防火墙

在使用 MySQL 企业防火墙之前,请根据 Section 8.4.7.2, “安装或卸载 MySQL 企业防火墙”中提供的说明进行安装。

本节描述了如何使用 SQL 语句配置 MySQL 企业防火墙。另外,MySQL Workbench 6.3.4 或更高版本提供了用于防火墙控制的图形界面。参见 MySQL 企业防火墙界面。

  • 启用或禁用防火墙

  • 分配防火墙权限

  • 防火墙概念

  • 注册防火墙组配置文件

  • 注册防火墙帐户配置文件

  • 监控防火墙

  • 将帐户配置文件迁移到组配置文件

启用或禁用防火墙

要启用或禁用防火墙,请设置mysql_firewall_mode系统变量。默认情况下,当安装防火墙时,此变量已启用。要明确控制初始防火墙状态,可以在服务器启动时设置该变量。例如,要在选项文件中启用防火墙,请使用以下行:

[mysqld]
mysql_firewall_mode=ON

修改my.cnf后,重新启动服务器以使新设置生效。

或者,要在运行时设置和持久化防火墙设置:

SET PERSIST mysql_firewall_mode = OFF;
SET PERSIST mysql_firewall_mode = ON;

SET PERSIST为正在运行的 MySQL 实例设置一个值。它还保存该值,导致其在后续服务器重新启动时保留。要更改正在运行的 MySQL 实例的值,而不使其在后续重新启动时保留,使用GLOBAL关键字而不是PERSIST。参见 Section 15.7.6.1, “变量赋值的 SET 语法”。

分配防火墙权限

安装防火墙后,向用于管理它的 MySQL 帐户或帐户授予适当的权限。权限取决于帐户应被允许执行哪些防火墙操作:

  • FIREWALL_EXEMPT权限(自 MySQL 8.0.27 起可用)授予任何应免于防火墙限制的帐户。例如,对于配置防火墙的数据库管理员来说,这很有用,以避免配置错误导致甚至管理员也被锁定并无法执行语句的可能性。

  • FIREWALL_ADMIN权限授予任何应具有完全管理防火墙访问权限的帐户。(某些管理防火墙功能可以由具有FIREWALL_ADMIN或已弃用的SUPER权限的帐户调用,如各个功能描述中所示。)

  • FIREWALL_USER权限授予任何应仅具有其自身防火墙规则的管理访问权限的帐户。

  • mysql系统数据库中的防火墙存储过程授予EXECUTE权限。这些存储过程可能调用管理功能,因此存储过程访问还需要前面所需的用于这些功能的权限。

注意

只能在安装了防火墙时授予FIREWALL_EXEMPTFIREWALL_ADMINFIREWALL_USER权限,因为MYSQL_FIREWALL插件定义了这些权限。

防火墙概念

MySQL 服务器允许客户端连接并接收他们发送的要执行的 SQL 语句。如果启用了防火墙,服务器会将每个未立即因语法错误而失败的传入语句传递给它。根据防火墙是否接受该语句,服务器会执行它或向客户端返回错误。本节描述了防火墙如何完成接受或拒绝语句的任务。

  • 防火墙配置文件

  • 防火墙语句匹配

  • 配置文件操作模式

  • 多个配置文件应用时的防火墙语句处理

防火墙配置文件

防火墙使用确定是否允许语句执行的配置文件注册表。配置文件具有以下属性:

  • 允许列表。允许列表是定义哪些语句可接受到配置文件的规则集。

  • 当前的操作模式。该模式使得可以以不同方式使用配置文件。例如:配置文件可以置于训练模式以建立白名单;白名单可用于限制语句执行或入侵检测;配置文件可以完全禁用。

  • 适用范围。范围指示配置文件适用于哪些客户端连接:

    • 防火墙支持基于账户的配置文件,使得每个配置文件都匹配特定的客户端账户(客户端用户名和主机名组合)。例如,您可以注册一个账户配置文件,其中白名单适用于源自admin@localhost的连接,以及另一个账户配置文件,其中白名单适用于源自myapp@apphost.example.com的连接。

    • 截至 MySQL 8.0.23 版本,防火墙支持可以有多个账户作为成员的组配置文件,配置文件白名单对所有成员均等适用。组配置文件使得对于需要将给定的一组白名单规则应用于多个账户的部署,管理更加简便且灵活。

最初,不存在任何配置文件,因此默认情况下,防火墙接受所有语句,并不影响 MySQL 账户可以执行哪些语句。要应用防火墙的保护功能,需要采取明确的行动:

  • 向防火墙注册一个或多个配置文件。

  • 通过为每个配置文件建立白名单来训练防火墙;也就是说,配置文件允许客户端执行的语句类型。

  • 将训练过的配置文件置于保护模式,以加固 MySQL 防止未经授权的语句执行:

    • MySQL 将每个客户端会话与特定的用户名和主机名组合关联。这个组合就是会话账户

    • 对于每个客户端连接,防火墙使用会话账户来确定哪些配置文件适用于处理客户端发出的语句。

      防火墙仅接受适用于适用配置文件白名单的语句。

大多数防火墙原则在组配置文件和账户配置文件上都适用。这两种类型的配置文件在以下方面有所不同:

  • 账户配置文件白名单仅适用于单个账户。组配置文件白名单适用于会话账户匹配任何属于该组的账户时。

  • 使用账户配置文件为多个账户应用白名单时,需要为每个账户注册一个配置文件,并在每个配置文件中复制白名单。这意味着必须单独训练每个账户配置文件,因为每个配置文件必须使用适用于其的单个账户进行训练。

    组配置文件白名单适用于多个账户,无需为每个账户重复。组配置文件可以使用任何或所有组成员账户进行训练,或者训练可以限制为任何单个成员。无论哪种方式,白名单都适用于所有成员。

  • 帐户配置文件名称基于连接到 MySQL 服务器的客户端取决于特定用户名称和主机名组合。组配置文件名称由防火墙管理员选择,除了长度必须在 1 到 288 个字符之外,没有其他约束。

注意

由于组配置文件比帐户配置文件具有优势,并且因为具有单个成员帐户的组配置文件在逻辑上等同于该帐户的帐户配置文件,建议所有新的防火墙配置文件都创建为组配置文件。从 MySQL 8.0.26 开始,帐户配置文件已被弃用,并且将在未来的 MySQL 版本中被移除。有关转换现有帐户配置文件的帮助,请参阅 Migrating Account Profiles to Group Profiles。

防火墙提供的基于配置文件的保护使得可以实施以下策略:

  • 如果应用程序具有独特的保护要求,请配置它使用不用于任何其他目的的帐户,并为该帐户设置组配置文件或帐户配置文件。

  • 如果相关应用程序共享保护要求,请将每个应用程序与其自己的帐户关联,然后将这些应用程序帐户添加为同一组配置文件的成员。或者,配置所有应用程序使用相同的帐户,并将它们与该帐户的帐户配置文件关联。

防火墙语句匹配

防火墙执行的语句匹配不使用从客户端接收的 SQL 语句。相反,服务器将传入的语句转换为规范化的摘要形式,防火墙操作使用这些摘要。语句规范化的好处在于它使相似的语句能够被分组并使用单个模式识别。例如,这些语句彼此不同:

SELECT first_name, last_name FROM customer WHERE customer_id = 1;
select first_name, last_name from customer where customer_id = 99;
SELECT first_name, last_name FROM customer WHERE customer_id = 143;

但它们都具有相同的规范化摘要形式:

SELECT `first_name` , `last_name` FROM `customer` WHERE `customer_id` = ?

通过规范化,防火墙白名单可以存储与从客户端接收的许多不同语句匹配的摘要。有关规范化和摘要的更多信息,请参阅第 29.10 节,“性能模式语句摘要和抽样”。

警告

max_digest_length系统变量设置为零会禁用摘要生成,这也会禁用需要摘要的服务器功能,例如 MySQL Enterprise Firewall。

配置文件操作模式

注册到防火墙的每个配置文件都有自己的操作模式,可以从以下值中选择:

  • OFF:此模式禁用配置文件。防火墙将其视为无效并忽略它。

  • RECORDING:这是防火墙的训练模式。从客户端接收的与配置文件匹配的传入语句被视为配置文件可接受的一部分,并成为其“指纹”的一部分。防火墙记录每个语句的规范化摘要形式,以学习配置文件的可接受语句模式。每个模式都是一个规则,规则的并集是配置文件白名单。

    组和账户配置文件之间的区别在于,组配置文件的语句记录可以限制为仅接收来自单个组成员(培训成员)的语句。

  • PROTECTING:在此模式下,配置文件允许或阻止语句执行。防火墙将传入的语句与配置文件白名单进行匹配,仅接受与之匹配的语句,并拒绝不匹配的语句。在RECORDING模式下训练配置文件后,将其切换到PROTECTING模式以加固 MySQL 防止被偏离白名单的语句访问。如果启用了mysql_firewall_trace系统变量,防火墙还会将被拒绝的语句写入错误日志。

  • DETECTING:此模式检测但不阻止入侵(与配置文件白名单中没有匹配的语句因为可疑而被拦截)。在DETECTING模式下,防火墙将可疑语句写入错误日志,但接受它们而不拒绝访问。

当配置文件被分配任何前述模式值时,防火墙会将模式存储在配置文件中。防火墙模式设置操作还允许使用RESET模式值,但不会存储此值:将配置文件设置为RESET模式会导致防火墙删除配置文件的所有规则并将其模式设置为OFF

注意

DETECTING模式下写入错误日志的消息或因为启用了mysql_firewall_trace而写入的消息被写入为 Notes,这些是信息消息。为确保这些消息出现在错误日志中并且不被丢弃,请确保错误日志的详细程度足以包括信息消息。例如,如果您正在使用基于优先级的日志过滤,如第 7.4.2.5 节,“基于优先级的错误日志过滤(log_filter_internal)”中描述的那样,请将log_error_verbosity系统变量设置为值 3。

当多个配置文件适用时的防火墙语句处理

为简单起见,后续描述如何设置配置文件的部分将从防火墙将客户端传入语句与仅一个配置文件(组配置文件或账户配置文件)匹配的角度进行。但是防火墙操作可能更加复杂:

  • 组配置文件可以包括多个账户作为成员。

  • 一个账户可以是多个组配置文件的成员。

  • 多个配置文件可以匹配给定的客户端。

以下描述涵盖了防火墙在可���有多个配置文件适用于传入语句时的一般操作情况。

正如之前提到的,MySQL 将每个客户端会话与特定的用户名和主机名组合(称为会话账户)关联起来。防火墙将会话账户与注册的配置文件进行匹配,以确定哪些配置文件适用于处理来自会话的传入语句:

  • 防火墙会忽略不活动的配置文件(模式为OFF的配置文件)。

  • 会话账户与包含具有相同用户和主机的成员的每个活动组配置文件匹配。可能会有多个这样的组配置文件。

  • 会话账户与具有相同用户和主机的活动账户配置文件匹配,如果有的话。最多只有一个这样的账户配置文件。

换句话说,会话账户可以匹配 0 或多个活动组配置文件,以及 0 或 1 个活动账户配置文件。这意味着对于给定会话,防火墙可以适用 0、1 或多个防火墙配置文件,防火墙将处理每个传入语句如下:

  • 如果没有适用的配置文件,防火墙不会施加任何限制并接受该语句。

  • 如果有适用的配置文件,它们的模式决定语句处理方式:

    • 防火墙将语句记录在每个处于RECORDING模式的适用配置文件的允许列表中。

    • 对于每个处于DETECTING模式的适用配置文件,如果语句可疑(不匹配配置文件允许列表),防火墙将将语句写入错误日志。

    • 如果至少有一个适用配置文件处于RECORDINGDETECTING模式(这些模式接受所有���句),或者如果语句与至少一个处于PROTECTING模式的适用配置文件的允许列表匹配,则防火墙将接受该语句。否则,防火墙将拒绝该语句(如果启用了mysql_firewall_trace系统变量,则将其写入错误日志)。

将这个描述记在心中,接下来的部分将回到单个组配置文件或单个账户配置文件适用的简单情况,并介绍如何设置每种类型的配置文件。

注册防火墙组配置文件

MySQL Enterprise Firewall 支持从 MySQL 8.0.23 开始注册组配置文件。组配置文件可以有多个账户作为其成员。要使用防火墙组配置文件来保护 MySQL 免受来自特定账户的传入语句的影响,请按照以下步骤操作:

  1. 注册组配置文件并将其置于RECORDING模式。

  2. 将成员账户添加到组配置文件中。

  3. 使用成员账户连接到 MySQL 服务器并执行要学习的语句。这将训练组配置文件并建立形成配置文件允许列表的规则。

  4. 将其他要作为组成员的账户添加到组配置文件中。

  5. 将组配置文件切换到PROTECTING模式。当客户端使用组配置文件的任何成员帐户连接到服务器时,配置文件允许列表会限制语句执行。

  6. 如果需要额外的培训,请将组配置文件再次切换到RECORDING模式,使用新的语句模式更新其允许列表,然后将其切换回PROTECTING模式。

防火墙相关帐户引用的准则如下:

  • 注意帐户引用出现的上下文。为防火墙操作命名帐户时,请将其指定为单引号字符串('*user_name*@*host_name*')。这与通常的 MySQL 语句约定不同,例如CREATE USERGRANT,其中您分别引用帐户名称的用户和主机部分('*user_name*'@'*host_name*')。

    为防火墙操作命名帐户的要求意味着您不能使用用户名称中嵌入@字符的帐户。

  • 防火墙根据服务器验证的实际用户和主机名称来评估语句。在配置文件中注册帐户时,请勿使用通配符字符或网络掩码:

    • 假设存在一个名为me@%.example.org的帐户,并且客户端使用它从主机abc.example.org连接到服务器。

    • 帐户名称包含%通配符字符,但服务器将客户端验证为具有用户名me和主机名abc.example.com,这就是防火墙看到的内容。

    • 因此,用于防火墙操作的帐户名称是me@abc.example.org而不是me@%.example.org

以下过程显示了如何向防火墙注册组配置文件,训练防火墙了解该配置文件的可接受语句(其允许列表),使用配置文件保护 MySQL 免受不可接受语句执行,并添加和删除组成员。示例使用fwgrp作为组配置文件名称。假定示例配置文件用于访问sakila数据库中的表的应用程序的客户端(可在dev.mysql.com/doc/index-other.html找到)。

使用管理 MySQL 帐户执行此过程中的步骤,除了由防火墙组配置文件的成员帐户执行的步骤。对于由成员帐户执行的语句,默认数据库应为sakila。(您可以通过相应调整指令来使用不同的数据库。)

  1. 如有必要,请创建要成为fwgrp组配置文件成员的帐户,并授予它们适当的访问权限。这里显示了一个成员的语句(选择适当的密码):

    CREATE USER 'member1'@'localhost' IDENTIFIED BY '*password*';
    GRANT ALL ON sakila.* TO 'member1'@'localhost';
    
  2. 使用sp_set_firewall_group_mode()存储过程向防火墙注册组配置文件,并将配置文件置于RECORDING(培训)模式:

    CALL mysql.sp_set_firewall_group_mode('fwgrp', 'RECORDING');
    
  3. 使用sp_firewall_group_enlist()存储过程添加一个初始成员帐户,用于训练组配置文件的允许列表:

    CALL mysql.sp_firewall_group_enlist('fwgrp', 'member1@localhost');
    
  4. 使用初始成员帐户训练组配置文件,从服务器主机连接到服务器,以便防火墙看到member1@localhost的会话帐户。然后执行一些语句,以便被视为配置文件的合法内容。例如:

    SELECT title, release_year FROM film WHERE film_id = 1;
    UPDATE actor SET last_update = NOW() WHERE actor_id = 1;
    SELECT store_id, COUNT(*) FROM inventory GROUP BY store_id;
    

    防火墙接收来自member1@localhost帐户的语句。因为该帐户是fwgrp配置文件的成员,该配置文件处于RECORDING模式,防火墙将语句解释为适用于fwgrp并将语句的规范化摘要形式记录为fwgrp允许列表中的规则。然后,这些规则适用于所有是fwgrp成员的帐户。

    注意

    直到fwgrp组配置文件以RECORDING模式接收语句,其允许列表为空,相当于“拒绝所有”。没有语句可以匹配空的允许列表,这带来以下影响:

    • 组配置文件无法切换到PROTECTING模式。它会拒绝每个语句,有效地禁止组成员执行任何语句。

    • 组配置文件可以切换到DETECTING模式。在这种情况下,配置文件接受每个语句,但将其记录为可疑。

  5. 此时,组配置文件信息已缓存,包括其名称、成员资格和允许列表。要查看此信息,请查询性能模式防火墙表:

    mysql> SELECT MODE FROM performance_schema.firewall_groups
           WHERE NAME = 'fwgrp';
    +-----------+
    | MODE      |
    +-----------+
    | RECORDING |
    +-----------+
    mysql> SELECT * FROM performance_schema.firewall_membership
           WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID;
    +----------+-------------------+
    | GROUP_ID | MEMBER_ID         |
    +----------+-------------------+
    | fwgrp    | member1@localhost |
    +----------+-------------------+
    mysql> SELECT RULE FROM performance_schema.firewall_group_allowlist
           WHERE NAME = 'fwgrp';
    +----------------------------------------------------------------------+
    | RULE                                                                 |
    +----------------------------------------------------------------------+
    | SELECT @@`version_comment` LIMIT ?                                   |
    | UPDATE `actor` SET `last_update` = NOW ( ) WHERE `actor_id` = ?      |
    | SELECT `title` , `release_year` FROM `film` WHERE `film_id` = ?      |
    | SELECT `store_id` , COUNT ( * ) FROM `inventory` GROUP BY `store_id` |
    +----------------------------------------------------------------------+
    

    注意

    @@version_comment规则来自连接到服务器时由mysql客户端自动发送的语句。

    重要

    根据应用程序使用情况训练防火墙。例如,为了确定服务器特性和功能,给定的 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果应用程序通常通过该连接器使用,也要使用该连接器训练防火墙。这使得这些初始语句成为与应用程序关联的组配置文件的允许列表的一部分。

  6. 再次调用sp_set_firewall_group_mode()将组配置文件切换到PROTECTING模式:

    CALL mysql.sp_set_firewall_group_mode('fwgrp', 'PROTECTING');
    

    重要

    将组配置文件从RECORDING模式切换出来,将其缓存数据同步到提供持久底层存储的mysql系统数据库表中。如果不为正在记录的配置文件切换模式,则缓存数据不会写入持久存储,并且在服务器重新启动时将丢失。

  7. 将应该成为成员的任何其他帐户添加到组配置文件中:

    CALL mysql.sp_firewall_group_enlist('fwgrp', 'member2@localhost');
    CALL mysql.sp_firewall_group_enlist('fwgrp', 'member3@localhost');
    CALL mysql.sp_firewall_group_enlist('fwgrp', 'member4@localhost');
    

    使用member1@localhost帐户训练的配置文件允许列表现在也适用于其他帐户。

  8. 要验证更新后的组成员资格,请再次查询firewall_membership表:

    mysql> SELECT * FROM performance_schema.firewall_membership
           WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID;
    +----------+-------------------+
    | GROUP_ID | MEMBER_ID         |
    +----------+-------------------+
    | fwgrp    | member1@localhost |
    | fwgrp    | member2@localhost |
    | fwgrp    | member3@localhost |
    | fwgrp    | member4@localhost |
    +----------+-------------------+
    
  9. 使用组中的任何帐户执行一些可接受和不可接受的语句来测试防火墙的组配置文件。防火墙将每个帐户的语句与配置文件的允许列表进行匹配并接受或拒绝:

    • 此语句与训练语句不完全相同,但产生的规范化语句与其中一个相同,因此防火墙接受它:

      mysql> SELECT title, release_year FROM film WHERE film_id = 98;
      +-------------------+--------------+
      | title             | release_year |
      +-------------------+--------------+
      | BRIGHT ENCOUNTERS |         2006 |
      +-------------------+--------------+
      
    • 这些语句在允许列表中找不到匹配项,因此防火墙会拒绝每个语句并显示错误:

      mysql> SELECT title, release_year FROM film WHERE film_id = 98 OR TRUE;
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> SHOW TABLES LIKE 'customer%';
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> TRUNCATE TABLE mysql.slow_log;
      ERROR 1045 (28000): Statement was blocked by Firewall
      
    • 如果启用了mysql_firewall_trace系统变量,则防火墙还会将被拒绝的语句写入错误日志。例如:

      [Note] Plugin MYSQL_FIREWALL reported:
      'ACCESS DENIED for 'member1@localhost'. Reason: No match in allowlist.
      Statement: TRUNCATE TABLE `mysql` . `slow_log`'
      

      这些日志消息可能有助于识别攻击源,如果有必要的话。

  10. 如果需要从组配置文件中移除成员,请使用sp_firewall_group_delist()存储过程,而不是sp_firewall_group_enlist()

    CALL mysql.sp_firewall_group_delist('fwgrp', 'member3@localhost');
    

防火墙组配置文件现在已经为成员帐户进行了训练。当客户端使用组中的任何帐户连接并尝试执行语句时,配置文件将保护 MySQL 免受未在允许列表中匹配的语句的影响。

刚刚展示的过程在训练允许列表之前仅向组配置文件添加了一个成员。这样做可以通过限制哪些帐户可以向允许列表添加新的可接受语句,从而更好地控制训练期间。如果需要进行额外培训,可以将配置文件切换回RECORDING模式:

CALL mysql.sp_set_firewall_group_mode('fwgrp', 'RECORDING');

然而,这使得组中的任何成员都可以执行语句并将其添加到允许列表中。为了将额外培训限制在单个组成员身上,请调用sp_set_firewall_group_mode_and_user(),它类似于sp_set_firewall_group_mode(),但多接受一个参数,指定哪个帐户被允许以RECORDING模式训练配置文件。例如,要仅允许member4@localhost进行训练,请执行以下操作:

CALL mysql.sp_set_firewall_group_mode_and_user('fwgrp', 'RECORDING', 'member4@localhost');

这使得指定帐户可以进行额外培训,而无需移除其他组成员。他们可以执行语句,但这些语句不会添加到允许列表中。(但请记住,在RECORDING模式下,其他成员可以执行任何语句。)

注意

为了避免指定特定帐户作为组配置文件的训练帐户时出现意外行为,始终确保该帐户是组的成员。

完成额外培训后,将组配置文件设置回PROTECTING模式:

CALL mysql.sp_set_firewall_group_mode('fwgrp', 'PROTECTING');

sp_set_firewall_group_mode_and_user()建立的训练帐户保存在组配置文件中,因此防火墙会在以后需要更多培训时记住它。因此,如果调用sp_set_firewall_group_mode()(不接受训练帐户参数),则当前配置文件训练帐户member4@localhost保持不变。

如果确实希望启用所有组成员在RECORDING模式下执行训练,则清除训练账户,调用sp_set_firewall_group_mode_and_user()并为账户参数传递NULL值:

CALL mysql.sp_set_firewall_group_mode_and_user('fwgrp', 'RECORDING', NULL);

可以通过将不匹配的语句记录为可疑来检测入侵,而不拒绝访问。首先,将组配置文件设置为DETECTING模式:

CALL mysql.sp_set_firewall_group_mode('fwgrp', 'DETECTING');

然后,使用成员账户执行一个不匹配组配置文件允许列表的语句。在DETECTING模式下,防火墙允许执行不匹配的语句:

mysql> SHOW TABLES LIKE 'customer%';
+------------------------------+
| Tables_in_sakila (customer%) |
+------------------------------+
| customer                     |
| customer_list                |
+------------------------------+

此外,防火墙会将消息写入错误日志:

[Note] Plugin MYSQL_FIREWALL reported:
'SUSPICIOUS STATEMENT from 'member1@localhost'. Reason: No match in allowlist.
Statement: SHOW TABLES LIKE ?'

要禁用组配置文件,请将其模式更改为OFF

CALL mysql.sp_set_firewall_group_mode(*group*, 'OFF');

要忘记配置文件的所有训练并禁用它,请重置它:

CALL mysql.sp_set_firewall_group_mode(*group*, 'RESET');

重置操作会导致防火墙删除配置文件的所有规则并将其模式设置为OFF

注册防火墙账户配置文件

MySQL 企业防火墙允许注册与个人账户对应的配置文件。要使用防火墙账户配置文件保护 MySQL 免受来自特定账户的传入语句的影响,请按照以下步骤操作:

  1. 注册账户配置文件并将其设置为RECORDING模式。

  2. 使用账户连接到 MySQL 服务器并执行要学习的语句。这将训练账户配置文件并建立形成配置文件允许列表的规则。

  3. 将账户配置文件切换到PROTECTING模式。当客户端使用该账户连接到服务器时,账户配置文件允许列表将限制语句执行。

  4. 如果需要额外的训练,请再次将账户配置文件切换到RECORDING模式,使用新的语句模式更新其允许列表,然后将其切换回PROTECTING模式。

遵循以下与防火墙相关的账户引用指南:

  • 注意账户引用出现的上下文。要为防火墙操作命名一个账户,请将其指定为单引号字符串('*user_name*@*host_name*')。这与通常的 MySQL 语句约定不同,例如CREATE USERGRANT,其中您分别引用账户名称的用户和主机部分('*user_name*'@'*host_name*')。

    为防火墙操作命名账户时,要求将账户命名为单引号字符串意味着您不能使用用户名称中嵌入@字符的账户。

  • 防火墙根据服务器验证的实际用户和主机名称对语句进行评估。在配置文件中注册账户时,不要使���通配符字符或网络掩码:

    • 假设存在一个名为me@%.example.org的账户,并且客户端使用它从主机abc.example.org连接到服务器。

    • 账户名称包含%通配符字符,但服务器将客户端验证为具有用户名me和主机名abc.example.com,这就是防火墙看到的内容。

    • 因此,用于防火墙操作的账户名称是me@abc.example.org而不是me@%.example.org

以下过程展示了如何向防火墙注册账户配置文件,训练防火墙了解该配置文件的可接受语句(其允许列表),并使用配置文件保护 MySQL 免受账户执行不可接受语句的影响。假定示例账户fwuser@localhost用于由访问sakila数据库中的表的应用程序(可在dev.mysql.com/doc/index-other.html找到)。

使用管理 MySQL 账户执行此过程中的步骤,除了那些指定由与防火墙注册的账户配置文件对应的fwuser@localhost账户执行的步骤。对于使用此账户执行的语句,默认数据库应为sakila。(您可以通过相应调整指令来使用不同的数据库。)

  1. 如有必要,创建用于执行语句的账户(选择适当的密码)并为sakila数据库授予权限:

    CREATE USER 'fwuser'@'localhost' IDENTIFIED BY '*password*';
    GRANT ALL ON sakila.* TO 'fwuser'@'localhost';
    
  2. 使用sp_set_firewall_mode()存储过程向防火墙注册账户配置文件并将配置文件置于RECORDING(训练)模式:

    CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'RECORDING');
    
  3. 要训练已注册的账户配置文件,请从服务器主机作为fwuser连接到服务器,以便防火墙看到fwuser@localhost的会话账户。然后使用该账户执行一些被视为配置文件合法的语句。例如:

    SELECT first_name, last_name FROM customer WHERE customer_id = 1;
    UPDATE rental SET return_date = NOW() WHERE rental_id = 1;
    SELECT get_customer_balance(1, NOW());
    

    因为配置文件处于RECORDING模式,防火墙将语句的规范化摘要形式记录为配置文件允许列表中的规则。

    注意

    直到fwuser@localhost账户配置文件在RECORDING模式下接收语句,其允许列表为空,相当于“拒绝所有”。空的允许列表无法匹配任何语句,这带来以下影响:

    • 账户配置文件无法切换到PROTECTING模式。它会拒绝每个语句,有效地禁止账户执行任何语句。

    • 账户配置文件可以切换到DETECTING模式。在这种情况下,配置文件接受每个语句但将其记录为可疑。

  4. 此时,账户配置文件信息已被缓存。要查看此信息,请查询INFORMATION_SCHEMA防火墙表:

    mysql> SELECT MODE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS
           WHERE USERHOST = 'fwuser@localhost';
    +-----------+
    | MODE      |
    +-----------+
    | RECORDING |
    +-----------+
    mysql> SELECT RULE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST
           WHERE USERHOST = 'fwuser@localhost';
    +----------------------------------------------------------------------------+
    | RULE                                                                       |
    +----------------------------------------------------------------------------+
    | SELECT `first_name` , `last_name` FROM `customer` WHERE `customer_id` = ?  |
    | SELECT `get_customer_balance` ( ? , NOW ( ) )                              |
    | UPDATE `rental` SET `return_date` = NOW ( ) WHERE `rental_id` = ?          |
    | SELECT @@`version_comment` LIMIT ?                                         |
    +----------------------------------------------------------------------------+
    

    注意

    @@version_comment规则来自连接到服务器时由mysql客户端自动发送的语句。

    重要

    根据应用程序使用情况训练防火墙。例如,为了确定服务器特性和功能,给定的 MySQL 连接器可能会在每个会话开始时向服务器发送语句。如果一个应用程序通常通过该连接器使用,也要使用该连接器来训练防火墙。这样可以使这些初始语句成为与应用程序关联的账户配置的白名单的一部分。

  5. 再次调用sp_set_firewall_mode(),这次将账户配置切换到PROTECTING模式:

    CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'PROTECTING');
    

    重要提示

    将账户配置从RECORDING模式切换出来会将其缓存数据同步到提供持久底层存储的mysql系统数据库表中。如果不切换正在记录的配置的模式,则缓存数据不会写入持久存储,并且在服务器重新启动时会丢失。

  6. 通过使用账户执行一些可接受和不可接受的语句来测试账户配置。防火墙会将来自账户的每个语句与配置白名单进行匹配并接受或拒绝它:

    • 该语句与训练语句不完全相同,但产生的规范化语句与其中一个相同,因此防火墙接受它:

      mysql> SELECT first_name, last_name FROM customer WHERE customer_id = '48';
      +------------+-----------+
      | first_name | last_name |
      +------------+-----------+
      | ANN        | EVANS     |
      +------------+-----------+
      
    • 这些语句在白名单中找不到匹配项,因此防火墙会拒绝每个语句并显示错误:

      mysql> SELECT first_name, last_name FROM customer WHERE customer_id = 1 OR TRUE;
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> SHOW TABLES LIKE 'customer%';
      ERROR 1045 (28000): Statement was blocked by Firewall
      mysql> TRUNCATE TABLE mysql.slow_log;
      ERROR 1045 (28000): Statement was blocked by Firewall
      
    • 如果启用了mysql_firewall_trace系统变量,防火墙还会将被拒绝的语句写入错误日志。例如:

      [Note] Plugin MYSQL_FIREWALL reported:
      'ACCESS DENIED for fwuser@localhost. Reason: No match in allowlist.
      Statement: TRUNCATE TABLE `mysql` . `slow_log`'
      

      这些日志消息可能有助于识别攻击源,如果有必要的话。

防火墙账户配置现在已经针对fwuser@localhost账户进行了训练。当客户端使用该账户连接并尝试执行语句时,该配置会保护 MySQL 免受未被配置白名单匹配的语句的影响。

可以通过将不匹配的语句记录为可疑来检测入侵,而不拒绝访问。首先,将账户配置置于DETECTING模式:

CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'DETECTING');

然后,使用该账户执行一个不匹配账户配置白名单的语句。在DETECTING模式下,防火墙允许执行不匹配的语句:

mysql> SHOW TABLES LIKE 'customer%';
+------------------------------+
| Tables_in_sakila (customer%) |
+------------------------------+
| customer                     |
| customer_list                |
+------------------------------+

此外,防火墙会将一条消息写入错误日志:

[Note] Plugin MYSQL_FIREWALL reported:
'SUSPICIOUS STATEMENT from 'fwuser@localhost'. Reason: No match in allowlist.
Statement: SHOW TABLES LIKE ?'

要禁用账户配置,请将其模式更改为OFF

CALL mysql.sp_set_firewall_mode(*user*, 'OFF');

要忘记配置的所有训练并禁用它,请重置它:

CALL mysql.sp_set_firewall_mode(*user*, 'RESET');

重置操作会导致防火墙删除配置的所有规则并将其模式设置为OFF

监控防火墙

要评估防火墙的活动,请检查其状态变量。例如,在执行早期显示的过程来训练和保护fwgrp组配置后,变量如下所示:

mysql> SHOW GLOBAL STATUS LIKE 'Firewall%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Firewall_access_denied     | 3     |
| Firewall_access_granted    | 4     |
| Firewall_access_suspicious | 1     |
| Firewall_cached_entries    | 4     |
+----------------------------+-------+

变量分别表示被拒绝的语句数、被接受的语句数、被记录为可疑的语句数以及被添加到缓存中的语句数。Firewall_access_granted计数为 4,因为通过注册账户连接时,mysql客户端发送了@@version_comment语句,每次连接都发送了三次,再加上未在DETECTING模式下被阻止的SHOW TABLES语句。

将账户配置文件迁移到组配置文件

在 MySQL 8.0.23 之前,MySQL 企业防火墙仅支持每个应用于单个账户的账户配置文件。从 MySQL 8.0.23 开始,防火墙还支持每个可以应用于多个账户的组配置文件。当需要将相同的允许列表应用于多个账户时,组配置文件能够更轻松地进行管理:不需要为每个账户创建一个账户配置文件并在所有这些配置文件中复制允许列表,只需创建一个组配置文件并将账户作为其成员。然后该组允许列表将应用于所有账户。

一个只有一个成员账户的组配置文件在逻辑上等同于该账户的账户配置文件,因此可以完全使用组配置文件来管理防火墙,而不是混合使用账户和组配置文件。对于新的防火墙安装,通过统一创建新的组配置文件而避免账户配置文件,可以实现这一点。

由于组配置文件提供了更大的灵活性,建议所有新的防火墙配置文件都以组配置文件的形式创建。从 MySQL 8.0.26 开始,账户配置文件已被弃用,并可能在未来的 MySQL 版本中被移除。对于已包含账户配置文件的防火墙安装升级,MySQL 8.0.26 及更高版本的 MySQL 企业防火墙包含一个名为sp_migrate_firewall_user_to_group()的存储过程,帮助您将账户配置文件转换为组配置文件。要使用它,请按照具有FIREWALL_ADMIN权限的用户执行以下过程:

  1. 运行firewall_profile_migration.sql脚本来安装sp_migrate_firewall_user_to_group()存储过程。该脚本位于您的 MySQL 安装的share目录中。

    $> mysql -u root -p < firewall_profile_migration.sql
    Enter password: *(enter root password here)*
    
  2. 通过查询信息模式MYSQL_FIREWALL_USERS表来识别存在哪些账户配置文件。例如:

    mysql> SELECT USERHOST FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS;
    +-------------------------------+
    | USERHOST                      |
    +-------------------------------+
    | admin@localhost               |
    | local_client@localhost        |
    | remote_client@abc.example.com |
    +-------------------------------+
    
  3. 对于上一步骤识别出的每个账户配置文件,将其转换为一个组配置文件:

    CALL mysql.sp_migrate_firewall_user_to_group('admin@localhost', 'admins');
    CALL mysql.sp_migrate_firewall_user_to_group('local_client@localhost', 'local_clients');
    CALL mysql.sp_migrate_firewall_user_to_group('remote_client@localhost', 'remote_clients');
    

    在每种情况下,账户配置文件必须存在且不能处于RECORDING模式,并且群组配置文件不能已经存在。生成的群组配置文件以命名的账户作为其唯一的成员,并且也被设置为群组培训账户。群组配置文件的操作模式取自账户配置文件的操作模式。

  4. (可选)移除sp_migrate_firewall_user_to_group()

    DROP PROCEDURE IF EXISTS mysql.sp_migrate_firewall_user_to_group;
    

有关sp_migrate_firewall_user_to_group()的更多详细信息,请参见防火墙杂项存储过程。

原文:dev.mysql.com/doc/refman/8.0/en/firewall-reference.html

8.4.7.4 MySQL 企业防火墙参考

以下各节提供了 MySQL 企业防火墙元素的参考:

  • MySQL 企业防火墙表

  • MySQL 企业防火墙存储过程

  • MySQL 企业防火墙管理功能

  • MySQL 企业防火墙系统变量

  • MySQL 企业防火墙状态变量

MySQL 企业防火墙表

MySQL 企业防火墙根据组和帐户的基础信息维护配置文件信息。它使用mysql系统数据库中的表进行持久存储,并使用INFORMATION_SCHEMA或 Performance Schema 表提供对内存中缓存数据的视图。启用后,防火墙基于缓存数据做出操作决策。

  • 防火墙组配置文件表

  • 防火墙帐户配置文件表

防火墙组配置文件表

截至 MySQL 8.0.23,MySQL 企业防火墙使用mysql系统数据库中的表来维护组配置文件信息以进行持久存储,并使用 Performance Schema 表提供对内存中缓存数据的视图。

每个系统和 Performance Schema 表只能由具有相应SELECT权限的帐户访问。

mysql.firewall_groups表列出了注册的防火墙组配置文件的名称和操作模式。该表具有以下列(相应的 Performance Schema firewall_groups表具有类似但不一定相同的列):

  • NAME

    组配置文件名称。

  • MODE

    配置文件的当前操作模式。允许的模式值为OFFDETECTINGPROTECTINGRECORDING。有关它们含义的详细信息,请参见防火墙概念。

  • USERHOST

    组配置文件的训练帐户,在配置文件处于RECORDING模式时使用。该值为NULL,或具有格式*user_name*@*host_name*的非NULL帐户:

    • 如果值为NULL,防火墙将记录来自组成员的任何帐户接收到的 allowlist 规则。

    • 如果值为非NULL,防火墙仅记录来自指定帐户(应为组的成员)接收的语句的允许列表规则。

mysql.firewall_group_allowlist表列出了注册的防火墙组配置文件的允许列表规则。该表具有以下列(相应的性能模式firewall_group_allowlist表具有类似但不一定相同的列):

  • NAME

    组配置文件名称。

  • RULE

    表示配置文件可接受语句模式的规范化语句。配置文件允许列表是其规则的并集。

  • ID

    用于表的主键的整数列。

mysql.firewall_membership表列出了注册的防火墙组配置文件的成员(帐户)。该表具有以下列(相应的性能模式firewall_membership表具有类似但不一定相同的列):

  • GROUP_ID

    组配置文件名称。

  • MEMBER_ID

    是配置文件成员的帐户名称。

防火墙帐户配置表

MySQL 企业防火墙使用mysql系统数据库中的表进行持久存储的帐户配置文件信息,并使用INFORMATION_SCHEMA表提供对内存中缓存数据的视图。

每个mysql系统数据库表只能被具有相应SELECT权限的帐户访问。INFORMATION_SCHEMA表可被任何人访问。

截至 MySQL 8.0.26,这些表已被弃用,并可能在未来的 MySQL 版本中被移除。请参阅 Migrating Account Profiles to Group Profiles。

mysql.firewall_users表列出了注册的防火墙帐户配置文件的名称和操作模式。该表具有以下列(相应的MYSQL_FIREWALL_USERS表具有类似但不一定相同的列):

  • USERHOST

    帐户配置文件名称。每个帐户名称的格式为*user_name*@*host_name*

  • MODE

    配置文件的当前操作模式。允许的模式值为OFFDETECTINGPROTECTINGRECORDINGRESET。有关其含义的详细信息,请参阅 Firewall Concepts。

mysql.firewall_whitelist表列出了已注册的防火墙帐户配置文件的允许列表规则。该表具有以下列(相应的MYSQL_FIREWALL_WHITELIST表具有类似但不一定相同的列):

  • USERHOST

    帐户配置文件名称。每个帐户名称的格式为*user_name*@*host_name*

  • RULE

    表示配置文件的可接受语句模式的规范化语句。配置文件的允许列表是其规则的并集。

  • ID

    表的主键是整数列。此列在 MySQL 8.0.12 中添加。

MySQL 企业防火墙存储过程

MySQL 企业防火墙存储过程执行诸如向防火墙注册配置文件、建立其操作模式以及管理防火墙数据在缓存和持久存储之间传输等任务。这些存储过程调用提供用于低级任务的 API 的管理函数。

防火墙存储过程在mysql系统数据库中创建。要调用防火墙存储过程,可以在mysql是默认数据库时执行,或者使用数据库名称限定过程名称。例如:

CALL mysql.sp_set_firewall_group_mode(*group*, *mode*);
  • 防火墙组配置文件存储过程

  • 防火墙帐户配置文件存储过程

  • 防火墙杂项存储过程

防火墙组配置文件存储过程

这些存储过程在防火墙组配置文件上执行管理操作:

  • sp_firewall_group_delist(*group*, *user*)

    此存储过程从防火墙组配置文件中删除一个帐户。

    如果调用成功,则组成员身份的更改将同时应用于内存缓存和持久存储。

    参数:

    • group: 受影响的组配置文件的名称。

    • user: 要移除的帐户,格式为*user_name*@*host_name*

    例子:

    CALL sp_firewall_group_delist('g', 'fwuser@localhost');
    

    此存储过程在 MySQL 8.0.23 中添加。

  • sp_firewall_group_enlist(*group*, *user*)

    此存储过程将一个帐户添加到防火墙组配置文件中。在将帐户添加到组之前,不需要将帐户本身注册到防火墙。

    如果调用成功,则组成员身份的更改将同时应用于内存缓存和持久存储。

    参数:

    • group: 受影响的组配置文件的名称。

    • user: 要添加的帐户,格式为*user_name*@*host_name*

    例子:

    CALL sp_firewall_group_enlist('g', 'fwuser@localhost');
    

    此存储过程在 MySQL 8.0.23 中添加。

  • sp_reload_firewall_group_rules(*group*)

    此存储过程为各个组配置文件提供防火墙操作控制。该过程使用防火墙管理函数从mysql.firewall_group_allowlist表中重新加载组配置文件的内存规则。

    参数:

    • group:受影响的组配置文件的名称。

    示例:

    CALL sp_reload_firewall_group_rules('myapp');
    

    警告

    此存储过程在重新加载持久存储中的组配置文件的允许规则之前清除组配置文件的内存中的允许规则,并将配置文件模式设置为OFF。如果在调用sp_reload_firewall_group_rules()之前配置文件模式不是OFF,则在重新加载规则后使用sp_set_firewall_group_mode()将其恢复为先前的模式。例如,如果配置文件处于PROTECTING模式,则在调用sp_reload_firewall_group_rules()后不再有效,必须显式将其设置为PROTECTING

    此存储过程在 MySQL 8.0.23 中添加。

  • sp_set_firewall_group_mode(*group*, *mode*)

    此存储过程在将配置文件注册到防火墙后,为防火墙组配置文件建立操作模式,如果尚未注册,则调用防火墙管理函数以在缓存和持久存储之间传输防火墙数据。即使mysql_firewall_mode系统变量为OFF,也可以调用此存储过程,尽管在启用防火墙之前,为配置文件设置模式不会产生操作效果。

    如果配置文件之前存在,则其任何记录限制保持不变。要设置或清除限制,请改为调用sp_set_firewall_group_mode_and_user()

    参数:

    • group:受影响的组配置文件的名称。

    • mode:配置文件的操作模式,以字符串形式表示。允许的模式值为OFFDETECTINGPROTECTINGRECORDING。有关它们的含义的详细信息,请参见防火墙概念。

    示例:

    CALL sp_set_firewall_group_mode('myapp', 'PROTECTING');
    

    此存储过程在 MySQL 8.0.23 中添加。

  • sp_set_firewall_group_mode_and_user(*group*, *mode*, *user*)

    此存储过程向防火墙注册一个组并建立其操作模式,类似于sp_set_firewall_group_mode(),但还指定了在组处于RECORDING模式时要使用的训练帐户。

    参数:

    • group:受影响的组配置文件的名称。

    • mode:配置文件的操作模式,以字符串形式表示。允许的模式值为OFFDETECTINGPROTECTINGRECORDING。有关它们的含义的详细信息,请参见防火墙概念。

    • user:组配置文件的训练帐户,在配置文件处于RECORDING模式时使用。该值为NULL,或具有格式*user_name*@*host_name*的非NULL帐户:

      • 如果数值为NULL,防火墙将记录来自任何属于该组的帐户接收到的语句的允许规则。

      • 如果值为非NULL,则防火墙记录仅允许来自指定账户(应为组的成员)的语句。

    示例:

    CALL sp_set_firewall_group_mode_and_user('myapp', 'RECORDING', 'myapp_user1@localhost');
    

    此过程是在 MySQL 8.0.23 中添加的。

防火墙账户配置文件存储过程

这些存储过程执行防火墙账户配置文件的管理操作:

  • sp_reload_firewall_rules(*user*)

    此存储过程为个别账户配置文件提供防火墙操作控制。该过程使用防火墙管理函数从mysql.firewall_whitelist表中存储的规则重新加载账户配置文件的内存中规则。

    参数:

    • user: 受影响的账户配置文件的名称,以*user_name*@*host_name*格式的字符串表示。

    示例:

    CALL mysql.sp_reload_firewall_rules('fwuser@localhost');
    

    警告

    此过程在重新加载持久存储中的账户配置文件内存中的允许列表规则之前清除它们,并将配置文件模式设置为OFF。如果在调用sp_reload_firewall_rules()之前配置文件模式不是OFF,则在重新加载规则后使用sp_set_firewall_mode()将其恢复为先前的模式。例如,如果配置文件处于PROTECTING模式,则在调用sp_reload_firewall_rules()后不再有效,必须显式将其设置为PROTECTING

    从 MySQL 8.0.26 开始,此存储过程已弃用,并可能在将来的 MySQL 版本中删除。请参见将账户配置文件迁移到组配置文件。

  • sp_set_firewall_mode(*user*, *mode*)

    此存储过程在注册配置文件到防火墙后,为防火墙账户配置文件建立操作模式。必要时,该过程还调用防火墙管理函数以在缓存和持久存储之间传输防火墙数据。即使mysql_firewall_mode系统变量为OFF,也可以调用此过程,尽管在启用防火墙之前,为配置文件设置模式不会产生操作效果。

    参数:

    • user: 受影响的账户配置文件的名称,以*user_name*@*host_name*格式的字符串表示。

    • mode: 该配置文件的操作模式,以字符串形式表示。允许的模式值为OFFDETECTINGPROTECTINGRECORDINGRESET。有关它们含义的详细信息,请参见防火墙概念。

    将账户配置文件切换到任何模式,但RECORDING会将其防火墙缓存数据同步到提供持久底层存储的mysql系统数据库表中。将模式从OFF切换到RECORDING会将允许列表从mysql.firewall_whitelist表重新加载到缓存中。

    如果一个账户配置具有空的允许列表,其模式不能设置为PROTECTING,因为该配置将拒绝每个语句,实际上会禁止该账户执行语句。针对这种模式设置尝试,防火墙会生成一条诊断消息,该消息作为结果集返回,而不是作为 SQL 错误:

    mysql> CALL mysql.sp_set_firewall_mode('a@b','PROTECTING');
    +----------------------------------------------------------------------+
    | set_firewall_mode(arg_userhost, arg_mode)                            |
    +----------------------------------------------------------------------+
    | ERROR: PROTECTING mode requested for a@b but the allowlist is empty. |
    +----------------------------------------------------------------------+
    

    从 MySQL 8.0.26 开始,此过程已被弃用,并可能在未来的 MySQL 版本中移除。请参阅 Migrating Account Profiles to Group Profiles。

防火墙杂项存储过程

这些存储过程执行杂项防火墙管理操作。

  • sp_migrate_firewall_user_to_group(*user*, *group*)

    从 MySQL 8.0.26 开始,账户配置已被弃用,因为组配置可以执行账户配置可以执行的任何操作。sp_migrate_firewall_user_to_group()存储过程将防火墙账户配置转换为以该账户为唯一成员的组配置。运行firewall_profile_migration.sql脚本进行安装。转换过程在 Migrating Account Profiles to Group Profiles 中讨论。

    此例程需要FIREWALL_ADMIN权限。

    参数:

    • user: 要转换为组配置的账户配置的名称,以*user_name*@*host_name*格式的字符串。账户配置必须存在,并且不能当前处于RECORDING模式。

    • group: 新组配置的名称,该名称不能已存在。新组配置以命名账户作为其唯一成员,并且该成员被设置为组培训账户。组配置操作模式取自账户配置操作模式。

    示例:

    CALL sp_migrate_firewall_user_to_group('fwuser@localhost', 'mygroup);
    

    此过程已添加到 MySQL 8.0.26 中。

MySQL 企业防火墙管理功能

MySQL 企业防火墙管理功能提供了一个 API,用于执行诸如将防火墙缓存与底层系统表同步等较低级别任务。

在正常操作中,这些功能由防火墙存储过程调用,而不是直接由用户调用。因此,这些功能描述不包括有关其参数和返回类型的详细信息。

  • 防火墙组配置功能

  • 防火墙账户配置功能

  • 防火墙杂项功能

防火墙组配置功能

这些功能执行防火墙组配置的管理操作:

  • firewall_group_delist(*group*, *user*)

    此函数从组配置文件中删除帐户。它需要FIREWALL_ADMIN权限。

    示例:

    SELECT firewall_group_delist('g', 'fwuser@localhost');
    

    此函数在 MySQL 8.0.23 中添加。

  • firewall_group_enlist(*group*, *user*)

    此函数将帐户添加到组配置文件中。它需要FIREWALL_ADMIN权限。

    在将帐户添加到组之前,不需要将帐户本身注册到防火墙。

    示例:

    SELECT firewall_group_enlist('g', 'fwuser@localhost');
    

    此函数在 MySQL 8.0.23 中添加。

  • read_firewall_group_allowlist(*group*, *rule*)

    此聚合函数通过对mysql.firewall_group_allowlist表上的SELECT语句更新了命名组配置文件的记录语句缓存。它需要FIREWALL_ADMIN权限。

    示例:

    SELECT read_firewall_group_allowlist('my_fw_group', fgw.rule)
    FROM mysql.firewall_group_allowlist AS fgw
    WHERE NAME = 'my_fw_group';
    

    此函数在 MySQL 8.0.23 中添加。

  • read_firewall_groups(*group*, *mode*, *user*)

    此聚合函数通过对mysql.firewall_groups表上的SELECT语句更新了防火墙组配置文件缓存。它需要FIREWALL_ADMIN权限。

    示例:

    SELECT read_firewall_groups('g', 'RECORDING', 'fwuser@localhost')
    FROM mysql.firewall_groups;
    

    此函数在 MySQL 8.0.23 中添加。

  • set_firewall_group_mode(*group*, *mode*[, *user*])

    此函数管理组配置文件缓存,建立配置文件操作模式,并可选择指定配置文件训练帐户。它需要FIREWALL_ADMIN权限。

    如果未提供可选的user参数,则配置文件的先前user设置保持不变。要更改设置,请使用第三个参数调用该函数。

    如果提供了可选的user参数,则指定组配置文件的训练帐户,用于配置文件处于RECORDING模式时使用。该值为NULL,或具有格式*user_name*@*host_name*的非NULL帐户:

    • 如果值为NULL,防火墙记录允许列表规则用于接收来自任何属于该组的帐户的语句。

    • 如果值为非NULL,则防火墙仅记录来自命名帐户(应为组成员)的语句的允许列表规则。

    示例:

    SELECT set_firewall_group_mode('g', 'DETECTING');
    

    此函数在 MySQL 8.0.23 中添加。

防火墙帐户配置文件函数

这些函数执行防火墙帐户配置文件的管理操作:

  • read_firewall_users(*user*, *mode*)

    此聚合函数通过对mysql.firewall_users表上的SELECT语句更新防火墙帐户配置文件缓存。它需要FIREWALL_ADMIN权限或已弃用的SUPER权限。

    示例:

    SELECT read_firewall_users('fwuser@localhost', 'RECORDING')
    FROM mysql.firewall_users;
    

    截至 MySQL 8.0.26 版本,此函数已被弃用,并可能在未来的 MySQL 版本中被移除。请参阅将帐户配置文件迁移到组配置文件。

  • read_firewall_whitelist(*user*, *rule*)

    此聚合函数通过对mysql.firewall_whitelist表上的SELECT语句更新命名帐户配置文件的记录语句缓存。它需要FIREWALL_ADMIN权限或已弃用的SUPER权限。

    示例:

    SELECT read_firewall_whitelist('fwuser@localhost', fw.rule)
    FROM mysql.firewall_whitelist AS fw
    WHERE USERHOST = 'fwuser@localhost';
    

    截至 MySQL 8.0.26 版本,此函数已被弃用,并可能在未来的 MySQL 版本中被移除。请参阅将帐户配置文件迁移到组配置文件。

  • set_firewall_mode(*user*, *mode*)

    此函数管理帐户配置文件缓存并建立配置文件操作模式。它需要FIREWALL_ADMIN权限或已弃用的SUPER权限。

    示例:

    SELECT set_firewall_mode('fwuser@localhost', 'RECORDING');
    

    截至 MySQL 8.0.26 版本,此函数已被弃用,并可能在未来的 MySQL 版本中被移除。请参阅将帐户配置文件迁移到组配置文件。

防火墙杂项函数

这些函数执行各种防火墙操作:

  • mysql_firewall_flush_status()

    此函数将多个防火墙状态变量重置为 0:

    • Firewall_access_denied

    • Firewall_access_granted

    • Firewall_access_suspicious

    此函数需要FIREWALL_ADMIN权限或已弃用的SUPER权限。

    示例:

    SELECT mysql_firewall_flush_status();
    
  • normalize_statement(*stmt*)

    此函数将 SQL 语句规范化为用于允许列表规则的摘要形式。它需要FIREWALL_ADMIN权限或已弃用的SUPER权限。

    示例:

    SELECT normalize_statement('SELECT * FROM t1 WHERE c1 > 2');
    

    注意

    相同的摘要功能在防火墙上下文之外使用STATEMENT_DIGEST_TEXT() SQL 函数可用。

MySQL 企业防火墙系统变量

MySQL 企业防火墙支持以下系统变量。使用它们来配置防火墙操作。除非安装了防火墙(参见第 8.4.7.2 节,“安装或卸载 MySQL 企业防火墙”),否则这些变量不可用。

  • mysql_firewall_mode

    命令行格式 --mysql-firewall-mode[={OFF&#124;ON}]
    系统变量 mysql_firewall_mode
    范围 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 ON

    MySQL 企业防火墙是否启用(默认情况下)或禁用。

  • mysql_firewall_trace

    命令行格式 --mysql-firewall-trace[={OFF&#124;ON}]
    系统变量 mysql_firewall_trace
    范围 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 OFF

    MySQL 企业防火墙跟踪是否启用或禁用(默认情况下)。当mysql_firewall_trace启用时,在PROTECTING模式下,防火墙会将被拒绝的语句写入错误日志。

MySQL 企业防火墙状态变量

MySQL 企业防火墙支持以下状态变量。使用它们来获取有关防火墙运行状态的信息。除非安装了防火墙(参见第 8.4.7.2 节,“安装或卸载 MySQL 企业防火墙”),否则这些变量不可用。防火墙状态变量在安装MYSQL_FIREWALL插件或启动服务器时被设置为 0。许多变量通过mysql_firewall_flush_status()函数重置为零(参见 MySQL 企业防火墙管理函数)。

  • Firewall_access_denied

    被 MySQL 企业防火墙拒绝的语句数量。

  • Firewall_access_granted

    被 MySQL 企业防火墙接受的语句数量。

  • Firewall_access_suspicious

    MySQL 企业防火墙记录为可疑的语句数量,适用于处于DETECTING模式的用户。

  • Firewall_cached_entries

    MySQL 企业防火墙记录的语句数量,包括重复的语句。

8.5 MySQL 企业数据脱敏和去识别

原文:dev.mysql.com/doc/refman/8.0/en/data-masking.html

8.5.1 数据脱敏组件与数据脱敏插件

8.5.2 MySQL 企业数据脱敏和去识别组件

8.5.3 MySQL 企业数据脱敏和去识别插件

注意

MySQL 企业数据脱敏和去识别是包含在 MySQL 企业版中的扩展,这是一款商业产品。要了解更多关于商业产品的信息,请访问www.mysql.com/products/

MySQL 企业版提供数据脱敏和去识别功能:

  • 转换现有数据以脱敏并删除识别特征,例如将信用卡号的所有数字更改为最后四位为'X'字符。

  • 生成随机数据,例如电子邮件地址和支付卡号。

  • 通过数据库中存储的字典数据替换数据。这些字典可以以标准方式轻松复制。管理权限仅限于被授予特殊权限的授权用户,以便只有他们可以创建和修改字典。

注意

MySQL 企业数据脱敏和去识别最初在 MySQL 8.0.13 中作为插件库实现。截至 MySQL 8.0.33,MySQL 企业版还提供了访问数据脱敏和去识别功能的组件。有关相似之处和差异的信息,请参见表 8.45,“数据脱敏组件与插件元素之间的比较”。

如果您是第一次使用 MySQL 企业数据脱敏和去识别,请考虑安装组件以访问仅在组件基础设施中可用的持续增强功能。

应用程序使用这些功能的方式取决于数据的使用目的和访问者:

  • 应用程序使用敏感数据时,可以通过执行数据脱敏并允许使用部分脱敏数据进行客户识别来保护数据。例如:呼叫中心可能会要求客户提供他们社会安全号码的最后四位数字。

  • 需要格式正确的数据,但不一定是原始数据的应用程序可以合成样本数据。例如:一个应用程序开发人员正在测试数据验证器,但无法访问原始数据,可以合成具有相同格式的随机数据。

  • 必须用字典术语替换真实姓名以保护敏感信息但仍向应用程序用户提供真实内容的应用程序。例如:受限于查看地址的培训用户将从字典城市名称中获取随机术语,而不是真实城市名称。这种情况的变体可能是,只有当真实城市名称存在于usa_city_names中时才替换真实城市名称。

示例 1:

医学研究机构可能保存包含个人和医疗数据混合的患者数据。这可能包括基因序列(长字符串)、以 JSON 格式存储的测试结果和其他数据类型。尽管数据主要由自动分析软件使用,但仍有可能访问特定患者的基因组数据或测试结果。在这种情况下,应使用数据掩码使这些信息不具有个人识别性。

示例 2:

信用卡处理公司提供一组使用敏感数据的服务,例如:

  • 每秒处理大量金融交易。

  • 存储大量与交易相关的数据。

  • 通过对个人数据设置严格要求来保护与交易相关的数据。

  • 处理关于使用可逆或部分掩码数据的交易的客户投诉。

典型交易可能包括许多类型的敏感信息,包括:

  • 信用卡号码。

  • 交易类型和金额。

  • 商家类型。

  • 交易密文(用于确认交易的合法性)。

  • GPS 设备终端的地理位置(用于欺诈检测)。

这些类型的信息可能会与客户个人数据(例如银行或其他发卡金融机构)合并,例如:

  • 客户全名(个人或公司)。

  • 地址。

  • 出生日期。

  • 社会安全号码。

  • 电子邮件地址。

  • 电话号码。

卡处理公司和金融机构内的各种员工角色需要访问这些数据。其中一些角色可能只需要访问掩码数据。其他角色可能需要根据情况访问原始数据,这些情况记录在审计日志中。

掩码和去标识化是符合监管要求的核心,因此 MySQL 企业数据掩码和去标识化可以帮助应用程序开发人员满足隐私要求:

  • PCI – DSS:支付卡数据。

  • HIPAA:健康数据隐私,经济和临床健康信息技术法案(HITECH 法案)。

  • 欧盟《通用数据保护指令》(GDPR):个人数据保护。

  • 英国《数据保护法》:个人数据保护。

  • 萨班斯·奥克斯利法案、GLBA、美国爱国者法案、1998 年身份盗窃和假冒法案。

  • FERPA – 学生数据,NASD,加州 SB1386 和 AB 1950,州数据保护法律,巴塞尔 II。

以下各节描述了 MySQL 企业数据掩码和去标识化的元素,讨论了如何安装和使用它,并为其元素提供参考信息。

8.5.1 数据遮蔽组件与数据遮蔽插件

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-components-vs-plugin.html

在 8.0.33 之前,MySQL 使用服务器端插件启用了遮蔽和去识别功能,但在 MySQL 8.0.33 中转而使用了组件基础架构。以下表格简要比较了 MySQL 企业数据遮蔽和去识别组件与插件库,以提供它们之间的区别概述。它可能帮助您从插件过渡到组件。

注意

只能同时启用数据遮蔽组件或插件。同时启用组件和插件不受支持,结果可能不如预期。

表 8.45 数据遮蔽组件与插件元素的比较

类别 组件 插件
接口 服务函数、可加载函数 可加载函数
支持多字节字符集 是,用于通用遮蔽功能
通用遮蔽功能 mask_inner(), mask_outer() mask_inner(), mask_outer()
特定类型的遮蔽 PAN、SSN、IBAN、UUID、Canada SIN、UK NIN PAN、SSN
随机生成,特定类型 电子邮件、美国电话、PAN、SSN、IBAN、UUID、Canada SIN、UK NIN 电子邮件、美国电话、PAN、SSN
从给定范围生成整数的随机数
持久化替换字典 数据库 文件
管理字典的权限 专用权限 文件
安装/卸载期间自动加载功能注册/注销
现有功能的增强 gen_rnd_email() 函数添加更多参数 N/A
类别 组件 插件

8.5.2 MySQL 企业数据脱敏和去标识化组件

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-components.html

8.5.2.1 MySQL 企业数据脱敏和去标识化组件安装

8.5.2.2 使用 MySQL 企业数据脱敏和去标识化组件

8.5.2.3 MySQL 企业数据脱敏和去标识化组件功能参考

8.5.2.4 MySQL 企业数据脱敏和去标识化组件功能描述

MySQL 企业数据脱敏和去标识化实现了以下元素:

  • mysql系统数据库中的一张表,用于持久存储字典和术语。

  • 一个名为component_masking的组件,实现脱敏功能并将其作为服务接口提供给开发人员。

    希望使用component_masking相同服务功能的开发人员应查阅 MySQL 源代码分发中的internal\components\masking\component_masking.h文件或 https://dev.mysql.com/doc/dev/mysql-server/latest。

  • 一个名为component_masking_functions的组件,提供可加载函数。

    一组可加载函数为执行脱敏和去标识化操作提供了 SQL 级 API。其中一些函数需要MASKING_DICTIONARIES_ADMIN动态权限。

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-components-installation.html

8.5.2.1 MySQL 企业数据脱敏和去标识化组件安装

从 MySQL 8.0.33 开始,组件提供了访问 MySQL 企业数据脱敏和去标识化功能的功能。以前,MySQL 将脱敏和去标识化功能实现为包含插件和几个可加载函数的插件库文件。在开始组件安装之前,请删除data_masking插件及其所有可加载函数,以避免冲突。有关说明,请参见第 8.5.3.1 节,“MySQL 企业数据脱敏和去标识化插件安装”。

MySQL 企业数据脱敏和去标识化数据库表和组件包括:

  • masking_dictionaries

    目的:mysql系统模式中的表,提供字典和术语的持久存储。

  • component_masking 组件

    目的:该组件实现了脱敏功能的核心,并将其作为服务公开。

    URN:file://component_masking

  • component_masking_functions 组件

    目的:该组件将component_masking组件的所有功能作为可加载函数公开。其中一些函数需要MASKING_DICTIONARIES_ADMIN动态权限。

    URN:file://component_masking_functions

要设置 MySQL 企业数据脱敏和去标识化,请执行以下操作:

  1. 创建masking_dictionaries表。

    CREATE TABLE IF NOT EXISTS
    mysql.masking_dictionaries(
        Dictionary VARCHAR(256) NOT NULL,
        Term VARCHAR(256) NOT NULL,
        UNIQUE INDEX dictionary_term_idx (Dictionary, Term),
        INDEX dictionary_idx (Dictionary)
    ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
    
  2. 使用INSTALL COMPONENT SQL 语句来安装数据脱敏组件。

    INSTALL COMPONENT 'file://component_masking';
    INSTALL COMPONENT 'file://component_masking_functions';
    

    如果在复制源服务器上使用组件和函数,请在所有副本服务器上安装它们,以避免复制问题。在加载组件时,有关它们的信息可如第 7.5.2 节,“获取组件信息”所述获得。

要移除 MySQL 企业数据脱敏和去标识化,请执行以下操作:

  1. 使用UNINSTALL COMPONENT SQL 语句来卸载数据脱敏组件。

    UNINSTALL COMPONENT 'file://component_masking';
    UNINSTALL COMPONENT 'file://component_masking_functions';
    
  2. 删除masking_dictionaries表。

    DROP TABLE mysql.masking_dictionaries;
    

component_masking_functions 会自动安装所有相关的可加载函数。同样,当卸载该组件时,也会自动卸载这些函数。有关安装或卸载组件的一般信息,请参见第 7.5.1 节,“安装和卸载组件”。

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-component-usage.html

8.5.2.2 使用 MySQL 企业数据蒙版和去识别组件

在使用 MySQL 企业数据蒙版和去识别之前,请根据提供的说明进行安装,详情请参阅第 8.5.2.1 节,“MySQL 企业数据蒙版和去识别组件安装”。

要在应用程序中使用 MySQL 企业数据蒙版和去识别,请调用适用于您希望执行的操作的函数。有关详细的函数描述,请参阅第 8.5.2.4 节,“MySQL 企业数据蒙版和去识别组件函数描述”。本节演示如何使用这些函数执行一些代表性任务。首先概述可用函数,然后展示一些函数在实际环境中的使用示例:

  • 蒙版数据以消除识别特征

  • 生成具有特定特征的随机数据

  • 使用字典生成随机数据

  • 使用蒙版数据进行客户识别

  • 创建显示蒙版数据的视图

蒙版数据以消除识别特征

MySQL 提供了通用蒙版组件函数,用于蒙版任意字符串,以及专用蒙版函数,用于蒙版特定类型的值。

通用蒙版组件函数

mask_inner()mask_outer() 是通用函数,根据字符串内的位置蒙版任意字符串的部分。这两个函数支持以任何字符集编码的输入字符串:

  • mask_inner() 对其字符串参数的内部进行蒙版处理,保留末尾未蒙版。其他参数指定未蒙版末尾的大小。

    mysql> SELECT mask_inner('This is a string', 5, 1);
    +--------------------------------------+
    | mask_inner('This is a string', 5, 1) |
    +--------------------------------------+
    | This XXXXXXXXXXg                     |
    +--------------------------------------+
    mysql> SELECT mask_inner('This is a string', 1, 5);
    +--------------------------------------+
    | mask_inner('This is a string', 1, 5) |
    +--------------------------------------+
    | TXXXXXXXXXXtring                     |
    +--------------------------------------+
    mysql> SELECT mask_inner("かすみがうら市", 3, 1);
    +----------------------------------+
    | mask_inner("かすみがうら市", 3, 1) |
    +----------------------------------+
    | かすみXXX 市                       |
    +----------------------------------+
    mysql> SELECT mask_inner("かすみがうら市", 1, 3);
    +----------------------------------+
    | mask_inner("かすみがうら市", 1, 3) |
    +----------------------------------+
    | かXXXうら市                       |
    +----------------------------------+
    
  • mask_outer() 则相反,掩码其字符串参数的两端,保留内部不掩码。其他参数指定掩码端的大小。

    mysql> SELECT mask_outer('This is a string', 5, 1);
    +--------------------------------------+
    | mask_outer('This is a string', 5, 1) |
    +--------------------------------------+
    | XXXXXis a strinX                     |
    +--------------------------------------+
    mysql> SELECT mask_outer('This is a string', 1, 5);
    +--------------------------------------+
    | mask_outer('This is a string', 1, 5) |
    +--------------------------------------+
    | Xhis is a sXXXXX                     |
    +--------------------------------------+
    

默认情况下,mask_inner()mask_outer() 使用 'X' 作为掩码字符,但允许使用可选的掩码字符参数:

mysql> SELECT mask_inner('This is a string', 5, 1, '*');
+-------------------------------------------+
| mask_inner('This is a string', 5, 1, '*') |
+-------------------------------------------+
| This **********g                          |
+-------------------------------------------+
mysql> SELECT mask_inner("かすみがうら市", 2, 2, "#");
+---------------------------------------+
| mask_inner("かすみがうら市", 2, 2, "#") |
+---------------------------------------+
| かす###ら市                            |
+---------------------------------------+
特殊用途掩码组件函数

其他掩码函数期望一个表示特定类型值的字符串参数,并对其进行掩码以消除识别特征。

注意

这里的示例使用返回适当类型值的随机值生成函数来提供函数参数。有关生成函数的更多信息,请参阅生成具有特定特征的随机数据。

支付卡主帐号号码掩码。 掩码函数提供主帐号号码的严格和宽松掩码。

  • mask_pan() 掩码号码的除最后四位之外的所有数字:

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX2461        |
    +-------------------------+
    
  • mask_pan_relaxed() 类似,但不掩码指示支付卡发卡方的前六位数字:

    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 770630XXXXXX0807                |
    +---------------------------------+
    

国际银行账号号码掩码。 mask_iban() 掩码号码的除前两个字母(表示国家)之外的所有数字:

mysql> SELECT mask_iban(gen_rnd_iban());
+---------------------------+
| mask_iban(gen_rnd_iban()) |
+---------------------------+
| ZZ** **** **** ****       |
+---------------------------+

通用唯一标识符掩码。 mask_uuid() 掩码所有有意义的字符:

mysql> SELECT mask_uuid(gen_rnd_uuid());
+--------------------------------------+
| mask_uuid(gen_rnd_uuid())            |
+--------------------------------------+
| ********-****-****-****-************ |
+--------------------------------------+

美国社会安全号码掩码。 mask_ssn() 掩码号码的除最后四位之外的所有数字:

mysql> SELECT mask_ssn(gen_rnd_ssn());
+-------------------------+
| mask_ssn(gen_rnd_ssn()) |
+-------------------------+
| ***-**-1723             |
+-------------------------+

加拿大社会保险号码掩码。 mask_canada_sin() 掩码号码的有意义数字:

mysql> SELECT mask_canada_sin(gen_rnd_canada_sin());
+---------------------------------------+
| mask_canada_sin(gen_rnd_canada_sin()) |
+---------------------------------------+
| XXX-XXX-XXX                           |
+---------------------------------------+

英国国民保险号码掩码。 mask_uk_nin() 掩码号码的除前两位之外的所有数字:

mysql> SELECT mask_uk_nin(gen_rnd_uk_nin());
+-------------------------------+
| mask_uk_nin(gen_rnd_uk_nin()) |
+-------------------------------+
| ZH*******                     |
+-------------------------------+
生成具有特定特征的随机数据

几个组件函数生成随机值。这些值可用于测试、模拟等用途。

gen_range() 从给定范围返回一个随机整数:

mysql> SELECT gen_range(1, 10);
+------------------+
| gen_range(1, 10) |
+------------------+
|                6 |
+------------------+

gen_rnd_canada_sin() 返回从未用于合法号码的范围中选择的随机数:

mysql> SELECT gen_rnd_canada_sin();
+----------------------+
| gen_rnd_canada_sin() |
+----------------------+

(由于其返回值仅用于测试目的,而非出版,因此不显示gen_rnd_canada_sin()函数的结果。不能保证该数字未分配给合法的加拿大 SIN。)

gen_rnd_email()返回一个随机的电子邮件地址,名称和姓氏部分在指定域mynet.com中具有指定数量的数字,如下例所示:

mysql> SELECT gen_rnd_email(6, 8, 'mynet.com');
+------------------------------+
| gen_rnd_email(6, 8, 'mynet') |
+------------------------------+
| ayxnqu.xmkpvvyr@mynet.com    |
+------------------------------+

gen_rnd_iban()返回一个从未用于合法数字的范围中选择的数字:

mysql> SELECT gen_rnd_iban('XO', 24);
+-------------------------------+
| gen_rnd_iban('XO', 24)        |
+-------------------------------+
| XO25 SL7A PGQR B9NN 6IVB RFE8 |
+-------------------------------+

gen_rnd_pan()返回一个随机的支付卡主帐号:

mysql> SELECT gen_rnd_pan();

(由于其返回值仅用于测试目的,而非出版,因此不显示gen_rnd_pan()函数的结果。不能保证该数字未分配给合法的支付账户。)

gen_rnd_ssn()返回一个随机的美国社会安全号码,第一部分和第二部分分别从未用于合法数字的范围中选择:

mysql> SELECT gen_rnd_ssn();
+---------------+
| gen_rnd_ssn() |
+---------------+
| 912-45-1615   |
+---------------+

gen_rnd_uk_nin()返回一个从未用于合法数字的范围中选择的数字:

mysql> SELECT gen_rnd_uk_nin();
+------------------+
| gen_rnd_uk_nin() |
+------------------+

(由于其返回值仅用于测试目的,而非出版,因此不显示gen_rnd_uk_nin()函数的结果。不能保证该数字未分配给合法的 NIN。)

gen_rnd_us_phone()返回一个在未用于合法数字的 555 区号中的随机美国电话号码:

mysql> SELECT gen_rnd_us_phone();
+--------------------+
| gen_rnd_us_phone() |
+--------------------+
| 1-555-747-5627     |
+--------------------+

gen_rnd_uuid()返回一个从未用于合法标识符的范围中选择的数字:

mysql> SELECT gen_rnd_uuid();
+--------------------------------------+
| gen_rnd_uuid()                       |
+--------------------------------------+
| 68946384-6880-3150-6889-928076732539 |
+--------------------------------------+
使用字典生成随机数据

MySQL 企业数据脱敏和去标识化使得可以将字典用作称为术语的随机值的来源。要使用字典,必须首先将其添加到masking_dictionaries系统表中并赋予一个名称。这些字典在组件初始化期间(服务器启动时)从表中读取并加载到缓存中。然后可以向字典中添加、移除和选择术语,并将其用作随机值或替换其他值。

注意

始终使用字典管理函数编辑字典,而不是直接修改表格。如果手动操作表格,则字典缓存将与表格不一致。

一个有效的masking_dictionaries表具有以下特征:

  • 管理员在mysql模式中创建了masking_dictionaries系统表如下:

    CREATE TABLE IF NOT EXISTS
    masking_dictionaries(
        Dictionary VARCHAR(256) NOT NULL,
        Term VARCHAR(256) NOT NULL,
        UNIQUE INDEX dictionary_term_idx (Dictionary, Term),
        INDEX dictionary_idx (Dictionary)
    ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
    
  • 需要 MASKING_DICTIONARY_ADMIN 权限来添加和删除术语,或者删除整个字典。

  • 表中可能包含多个字典及其术语。

  • 任何用户账户都可以查看字典。通过足够的查询,所有字典中的术语都是可检索的。避免向字典表中添加敏感数据。

假设一个名为DE_cities的字典包含德国这些城市的名称:

Berlin
Munich
Bremen

使用masking_dictionary_term_add()来分配一个字典名称和一个术语:

mysql> SELECT masking_dictionary_term_add('DE_Cities', 'Berlin');
+----------------------------------------------------+
| masking_dictionary_term_add('DE_Cities', 'Berlin') |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('DE_Cities', 'Munich');
+----------------------------------------------------+
| masking_dictionary_term_add('DE_Cities', 'Munich') |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('DE_Cities', 'Bremen');
+----------------------------------------------------+
| masking_dictionary_term_add('DE_Cities', 'Bremen') |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+

还假设一个名为US_Cities的字典包含美国这些城市的名称:

Houston
Phoenix
Detroit
mysql> SELECT masking_dictionary_term_add('US_Cities', 'Houston');
+-----------------------------------------------------+
| masking_dictionary_term_add('US_Cities', 'Houston') |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('US_Cities', 'Phoenix');
+-----------------------------------------------------+
| masking_dictionary_term_add('US_Cities', 'Phoenix') |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('US_Cities', 'Detroit');
+-----------------------------------------------------+ 
| masking_dictionary_term_add('US_Cities', 'Detroit') |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+

要从字典中选择一个随机术语,请使用gen_dictionary()

mysql> SELECT gen_dictionary('DE_Cities');
+-----------------------------+
| gen_dictionary('DE_Cities') |
+-----------------------------+
| Berlin                      |
+-----------------------------+
mysql> SELECT gen_dictionary('US_Cities');
+-----------------------------+
| gen_dictionary('US_Cities') |
+-----------------------------+
| Phoenix                     |
+-----------------------------+

要从多个字典中选择一个随机术语,随机选择一个字典,然后从中选择一个术语:

mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Detroit                                                       |
+---------------------------------------------------------------+
mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Bremen                                                        |
+---------------------------------------------------------------+

gen_blocklist()函数使得一个字典中的术语可以被另一个字典中的术语替换,从而实现了掩码替换。它的参数是要替换的术语,术语出现的字典,以及要选择替换的字典。例如,要用美国城市替换德国城市,或者反之,可以像这样使用gen_blocklist()

mysql> SELECT gen_blocklist('Munich', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Munich', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Houston                                           |
+---------------------------------------------------+
mysql> SELECT gen_blocklist('El Paso', 'US_Cities', 'DE_Cities');
+----------------------------------------------------+
| gen_blocklist('El Paso', 'US_Cities', 'DE_Cities') |
+----------------------------------------------------+
| Bremen                                             |
+----------------------------------------------------+

如果要替换的术语不在第一个字典中,gen_blocklist()会原样返回它:

mysql> SELECT gen_blocklist('Moscow', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Moscow', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Moscow                                            |
+---------------------------------------------------+
使用掩码数据进行客户识别

在客服呼叫中心,一个常见的身份验证技术是要求客户提供他们社会安全号码(SSN)的最后四位数字。例如,一个客户可能说她的名字是乔安娜·邦德,她的最后四位 SSN 数字是0007

假设包含客户记录的customer表具有这些列:

  • id: 客户 ID 号码。

  • first_name: 客户名字。

  • last_name: 客户姓氏。

  • ssn: 客户社会安全号码。

例如,表可能定义如下:

CREATE TABLE customer
(
  id         BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(40),
  last_name  VARCHAR(40),
  ssn        VARCHAR(11)
);

客服代表用于检查客户社会安全号码的应用程序可能执行类似这样的查询:

mysql> SELECT id, ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | ssn         |
+-----+-------------+
| 786 | 906-39-0007 |
+-----+-------------+

然而,这会将 SSN 暴露给客服代表,他们除了最后四位数字外不需要看到任何内容。相反,应用程序可以使用这个查询仅显示掩码的 SSN:

mysql> SELECT id, mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | ***-**-0007 |
+-----+-------------+

现在代表只看到必要的内容,客户隐私得到保护。

为什么在CONVERT()函数中使用参数mask_ssn()?因为mask_ssn()需要一个长度为 11 的参数。因此,即使ssn被定义为VARCHAR(11),如果ssn列具有多字节字符集,当传递给可加载函数时可能会看起来比 11 个字节长,并在记录错误时返回NULL。将值转换为二进制字符串可以确保函数看到长度为 11 的参数。

当字符串参数没有单字节字符集时,可能需要类似的技术来处理其他数据脱敏函数。

创建显示脱敏数据的视图

如果来自表的脱敏数据用于多个查询,定义一个生成脱敏数据的视图可能会很方便。这样,应用程序可以从视图中选择而无需在单独的查询中执行脱敏。

例如,可以像这样定义前一节中customer表的脱敏视图:

CREATE VIEW masked_customer AS
SELECT id, first_name, last_name,
mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
FROM customer;

然后查找客户的查询变得更简单,但仍返回脱敏数据:

mysql> SELECT id, masked_ssn
mysql> FROM masked_customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | ***-**-0007 |
+-----+-------------+

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-component-function-reference.html

8.5.2.3 MySQL 企业数据遮盖和去识别组件函数参考

表 8.46 MySQL 企业数据遮盖和去识别组件函数

名称 描述 引入版本
gen_blocklist() 执行字典术语替换 8.0.33
gen_dictionary() 从字典返回随机术语 8.0.33
gen_range() 在范围内生成随机数 8.0.33
gen_rnd_canada_sin() 生成随机加拿大社会保险号码 8.0.33
gen_rnd_email() 生成随机电子邮件地址 8.0.33
gen_rnd_iban() 生成随机国际银行帐号 8.0.33
gen_rnd_pan() 生成随机支付卡主帐号 8.0.33
gen_rnd_ssn() 生成随机美国社会安全号码 8.0.33
gen_rnd_uk_nin() 生成随机英国国民保险号码 8.0.33
gen_rnd_us_phone() 生成随机美国电话号码 8.0.33
gen_rnd_uuid() 生成随机通用唯一标识符 8.0.33
mask_canada_sin() 遮盖加拿大社会保险号码 8.0.33
mask_iban() 遮盖国际银行帐号 8.0.33
mask_inner() 遮盖字符串的内部部分 8.0.33
mask_outer() 遮盖字符串的左右部分 8.0.33
mask_pan() 遮盖支付卡主帐号部分的字符串 8.0.33
mask_pan_relaxed() 遮盖支付卡主帐号部分的字符串 8.0.33
mask_ssn() 遮盖美国社会安全号码 8.0.33
mask_uk_nin() 遮盖英国国民保险号码 8.0.33
mask_uuid() 遮蔽字符串中的通用唯一标识符部分 8.0.33
masking_dictionary_remove() 从数据库表中移除字典 8.0.33
masking_dictionary_term_add() 向字典中添加新术语 8.0.33
masking_dictionary_term_remove() 从字典中移除现有术语 8.0.33
名称 描述 引入版本

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-component-functions.html

8.5.2.4 MySQL 企业数据掩码和去标识化组件功能描述

MySQL 企业数据掩码和去标识化组件包括几个函数,可以分为以下类别:

  • 数据掩码组件函数

  • 生成随机数据组件函数

  • 字典掩码管理组件函数

  • 生成字典组件函数

数据掩码组件函数

本节中的每个组件函数对其字符串参数执行掩码操作并返回掩码结果。

  • mask_canada_sin(*str* [, *mask_char*])

    掩盖加拿大社会保险号(SIN)并返回所有有意义的数字被'X'字符替换的数字。可以指定一个可选的掩盖字符。

    参数:

    • str: 需要掩盖的字符串。接受的格式有:

      • 九个不间隔的数字。

      • 九个数字按照模式分组:xxx-xxx-xxx('-'是任何分隔字符)。

      此参数将转换为utf8mb4字符集。

    • mask_char: (可选)用于掩盖的单个字符。如果未提供mask_char,默认为'X'

    返回值:

    掩盖后的加拿大社会保险号作为一个字符串,编码为utf8mb4字符集,如果参数长度不正确则报错,或者如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_canada_sin('046-454-286'), mask_canada_sin('abcdefijk');
    +--------------------------------+------------------------------+
    | mask_canada_sin('046-454-286') | mask_canada_sin('abcdefijk') |
    +--------------------------------+------------------------------+
    | XXX-XXX-XXX                    | XXXXXXXXX                    |
    +--------------------------------+------------------------------+
    mysql> SELECT mask_canada_sin('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_canada_sin'; Argument 0 is too short.
    mysql> SELECT mask_canada_sin('046-454-286-909');
    ERROR 1123 (HY000): Can't initialize function 'mask_canada_sin'; Argument 0 is too long.
    
  • mask_iban(*str* [, *mask_char*])

    掩盖国际银行账号(IBAN)并返回除了前两个字母(表示国家)以外的所有字符被'*'字符替换的数字。可以指定一个可选的掩盖字符。

    参数:

    • str: 需要掩盖的字符串。每个国家可能有不同的国家路由或账号编号系统,最少 13 个字符,最多 34 个字母数字 ASCII 字符。接受的格式有:

      • 非分隔字符。

      • 每四个字符分组,除了最后一组,用空格或其他分隔字符分隔(例如:xxxx-xxxx-xxxx-xx)。

      此参数将转换为utf8mb4字符集。

    • mask_char: (可选)用于掩盖的单个字符。如果未提供mask_char,默认为'*'

    返回值:

    作为字符串编码在utf8mb4字符集中的掩码国际银行账号,如果参数长度不正确则返回错误,如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_iban('IE12 BOFI 9000 0112 3456 78'), mask_iban('abcdefghijk');
    +------------------------------------------+--------------------------+
    | mask_iban('IE12 BOFI 9000 0112 3456 78') | mask_iban('abcdefghijk') |
    +------------------------------------------+--------------------------+
    | IE** **** **** **** **** **              | ab*********              |
    +------------------------------------------+--------------------------+
    mysql> SELECT mask_iban('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_iban'; Argument 0 is too short.
    mysql> SELECT mask_iban('IE12 BOFI 9000 0112 3456 78 IE12 BOFI 9000 0112 3456 78');
    ERROR 1123 (HY000): Can't initialize function 'mask_iban'; Argument 0 is too long.
    
  • mask_inner(*str*, *margin1*, *margin2* [, *mask_char*])

    掩码字符串的内部部分,保留两端不变,并返回结果。可以指定一个可选的掩码字符。

    mask_inner支持所有字符集。

    参数:

    • str:要掩码的字符串。此参数将转换为utf8mb4字符集。

    • margin1:一个非负整数,指定要保留不掩码的字符串左端字符的数量。如果值为 0,则不保留任何左端字符。

    • margin2:一个非负整数,指定要保留不掩码的字符串右端字符的数量。如果值为 0,则不保留任何右端字符。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'X'

    返回值:

    使用与str相同的字符集编码的掩码字符串,如果任一边界为负则返��错误。

    如果边界值的总和大于参数长度,则不进行掩码操作,直接返回参数。

    注意

    该函数经过优化,可更快地处理单字节字符串(具有相等的字节长度和字符长度)。例如,utf8mb4字符集仅使用一个字节表示 ASCII 字符,因此该函数将只处理包含 ASCII 字符的字符串作为单字节字符字符串。

    示例:

    mysql> SELECT mask_inner('abcdef', 1, 2), mask_inner('abcdef',0, 5);
    +----------------------------+---------------------------+
    | mask_inner('abcdef', 1, 2) | mask_inner('abcdef',0, 5) |
    +----------------------------+---------------------------+
    | aXXXef                     | Xbcdef                    |
    +----------------------------+---------------------------+
    mysql> SELECT mask_inner('abcdef', 1, 2, '*'), mask_inner('abcdef',0, 5, '#');
    +---------------------------------+--------------------------------+
    | mask_inner('abcdef', 1, 2, '*') | mask_inner('abcdef',0, 5, '#') |
    +---------------------------------+--------------------------------+
    | a***ef                          | #bcdef                         |
    +---------------------------------+--------------------------------+
    
  • mask_outer(*str*, *margin1*, *margin2* [, *mask_char*])

    掩码字符串的左端和右端,保留内部不变,并返回结果。可以指定一个可选的掩码字符。

    mask_outer支持所有字符集。

    参数:

    • str:要掩码的字符串。此参数将转换为utf8mb4字符集。

    • margin1:一个非负整数,指定要掩码的字符串左端字符的数量。如果值为 0,则不对左端字符进行掩码。

    • margin2:一个非负整数,指定要掩码的字符串右端字符的数量。如果值为 0,则不对右端字符进行掩码。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'X'

    返回值:

    使用与str相同的字符集编码的掩码字符串,如果任一边界为负则返回错误。

    如果边界值的总和大于参数长度,则整个参数都会被掩码。

    注意

    该函数经过优化,以便更快地处理单字节字符串(具有相等的字节长度和字符长度)。例如,utf8mb4字符集仅使用一个字节来表示 ASCII 字符,因此该函数将仅处理包含 ASCII 字符的字符串作为单字节字符字符串。

    示例:

    mysql> SELECT mask_outer('abcdef', 1, 2), mask_outer('abcdef',0, 5);
    +----------------------------+---------------------------+
    | mask_outer('abcdef', 1, 2) | mask_outer('abcdef',0, 5) |
    +----------------------------+---------------------------+
    | XbcdXX                     | aXXXXX                    |
    +----------------------------+---------------------------+
    mysql> SELECT mask_outer('abcdef', 1, 2, '*'), mask_outer('abcdef',0, 5, '#');
    +---------------------------------+--------------------------------+
    | mask_outer('abcdef', 1, 2, '*') | mask_outer('abcdef',0, 5, '#') |
    +---------------------------------+--------------------------------+
    | *bcd**                          | a#####                         |
    +---------------------------------+--------------------------------+
    
  • mask_pan(*str* [, *mask_char*])

    掩码一个支付卡的主帐号(PAN),并返回除了最后四位数字以外的所有数字都替换为'X'字符的号码。可以指定一个可选的掩码字符。

    参数:

    • str:要掩码的字符串。该字符串必须包含最少 14 个最多 19 个字母数字字符。此参数被转换为utf8mb4字符集。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'X'

    返回值:

    掩码后的支付号码作为以utf8mb4字符集编码的字符串,如果参数长度不正确则报错,或者如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX9102        |
    +-------------------------+
    mysql> SELECT mask_pan(gen_rnd_pan(19));
    +---------------------------+
    | mask_pan(gen_rnd_pan(19)) |
    +---------------------------+
    | XXXXXXXXXXXXXXX8268       |
    +---------------------------+
    mysql> SELECT mask_pan('a*Z');
    ERROR 1123 (HY000): Can't initialize function 'mask_pan'; Argument 0 is too short.
    
  • mask_pan_relaxed(*str*)

    掩码一个支付卡的主帐号,并返回除了前六位和最后四位数字以外的所有数字都替换为'X'字符的号码。前六位数字表示支付卡发行者。可以指定一个可选的掩码字符。

    参数:

    • str:要掩��的字符串。该字符串必须适合主帐号号码的长度,但不进行其他检查。此参数被转换为utf8mb4字符集。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'X'

    返回值:

    掩码后的支付号码作为以utf8mb4字符集编码的字符串,如果参数长度不正确则报错,或者如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 551279XXXXXX3108                |
    +---------------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan(19));
    +-----------------------------------+
    | mask_pan_relaxed(gen_rnd_pan(19)) |
    +-----------------------------------+
    | 462634XXXXXXXXX6739               |
    +-----------------------------------+
    mysql> SELECT mask_pan_relaxed('a*Z');
    ERROR 1123 (HY000): Can't initialize function 'mask_pan_relaxed'; Argument 0 is too short.
    
  • mask_ssn(*str* [, *mask_char*])

    掩码一个美国社会安全号码(SSN),并返回除了最后四位数字以外的所有数字都替换为'*'字符。可以指定一个可选的掩码字符。

    参数:

    • str:要掩码的字符串。接受的格式为:

      • 九个不间断的数字。

      • 九位数字按照模式分组:xxx-xx-xxxx('-'是任何分隔符字符)。

      这个参数被转换为utf8mb4字符集。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'*'

    返回值:

    掩码后的社会安全号码作为以utf8mb4字符集编码的字符串,如果参数长度不正确则报错,或者如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_ssn('909-63-6922'), mask_ssn('cdefghijk');
    +-------------------------+-------------------------+
    | mask_ssn('909-63-6922') | mask_ssn('cdefghijk')   |
    +-------------------------+-------------------------+
    | ***-**-6922             | *******hijk             |
    +-------------------------+-------------------------+
    mysql> SELECT mask_ssn('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_ssn'; Argument 0 is too short.
    mysql> SELECT mask_ssn('123456789123456789');
    ERROR 1123 (HY000): Can't initialize function 'mask_ssn'; Argument 0 is too long.
    
  • mask_uk_nin(*str* [, *mask_char*])

    掩码一个英国国民保险号码(UK NIN)并返回除了前两位数字外所有字符都被'*'字符替换的数字��可以指定一个可选的掩码字符。

    参数:

    • str:要掩码的字符串。接受的格式有:

      • 九个非分隔数字。

      • 以模式分组的九个数字:xxx-xx-xxxx('-'是任何分隔符字符)。

      • 以模式分组的九个数字:xx-xxxxxx-x('-'是任何分隔符字符)。

      此参数转换为utf8mb4字符集。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,则默认为'*'

    返回值:

    作为字符串编码在utf8mb4字符集中的掩码英国国民保险号码,如果参数长度不正确则报错,或者如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_uk_nin('QQ 12 34 56 C'), mask_uk_nin('abcdefghi');
    +------------------------------+--------------------------+
    | mask_uk_nin('QQ 12 34 56 C') | mask_uk_nin('abcdefghi') |
    +------------------------------+--------------------------+
    | QQ ** ** ** *                | ab*******                |
    +------------------------------+--------------------------+
    mysql> SELECT mask_uk_nin('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_uk_nin'; Argument 0 is too short.
    mysql> SELECT mask_uk_nin('abcdefghijk');
    ERROR 1123 (HY000): Can't initialize function 'mask_uk_nin'; Argument 0 is too long.
    
  • mask_uuid(*str* [, *mask_char*])

    掩码一个通用唯一标识符(UUID)并返回所有有意义字符被'*'字符替换的数字。可以指定一个可选的掩码字符。

    参数:

    • str:要掩码的字符串。接受的格式为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,其中'X'是任何数字,'-'是任何分隔符字符。此参数转换为utf8mb4字符集。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,则默认为'*'

    返回值:

    作为字符串编码在utf8mb4字符集中的掩码 UUID,如果参数长度不正确则报错,或者如果str格式不正确或包含多字节字符则返回NULL

    示例:

    mysql> SELECT mask_uuid(gen_rnd_uuid());
    +--------------------------------------+
    | mask_uuid(gen_rnd_uuid())            |
    +--------------------------------------+
    | ********-****-****-****-************ |
    +--------------------------------------+
    mysql> SELECT mask_uuid('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_uuid'; Argument 0 is too short.
    mysql> SELECT mask_uuid('123e4567-e89b-12d3-a456-426614174000-123e4567-e89b-12d3');
    ERROR 1123 (HY000): Can't initialize function 'mask_uuid'; Argument 0 is too long.
    
随机数据生成组件函数

本节中的组件函数为不同类型的数据生成随机值。在可能的情况下,生成的值具有保留用于演示或测试值的特征,以避免将它们误认为是合法数据。例如,gen_rnd_us_phone()返回一个使用未分配给实际使用的电话号码的 555 区号的美国电话号码。各个函数的描述会说明任何违反此原则的情况。

  • gen_range(*lower*, *upper*)

    生成从指定范围中选择的随机数。

    参数:

    • lower:指定范围的下限的整数。

    • upper:指定范围的上限,必须不小于下限。

    返回值:

    lowerupper范围内的随机整数(以utf8mb4字符集编码),包括lowerupper,如果upper参数小于lower则返回NULL

    注意

    为了获得更好质量的随机值,请使用RAND()而不是此函数。

    示例:

    mysql> SELECT gen_range(100, 200), gen_range(-1000, -800);
    +---------------------+------------------------+
    | gen_range(100, 200) | gen_range(-1000, -800) |
    +---------------------+------------------------+
    |                 177 |                   -917 |
    +---------------------+------------------------+
    mysql> SELECT gen_range(1, 0);
    +-----------------+
    | gen_range(1, 0) |
    +-----------------+
    |            NULL |
    +-----------------+
    
  • gen_rnd_canada_sin()

    *AAA*-*BBB*-*CCC*格式生成一个随机的加拿大社会保险号码。生成的号码通过 Luhn 检查算法,确保此号码的一致性。

    警告

    gen_rnd_canada_sin()返回的值仅用于测试目的,不适合发布。无法保证给定的返回值不会分配给合法的加拿大社会保险号码。如果需要发布gen_rnd_canada_sin()的结果,请考虑使用mask_canada_sin()进行掩码处理。

    参数:

    无。

    返回值:

    一个以utf8mb4字符集编码的随机加拿大社会保险号码。

    示例:

    mysql> SELECT gen_rnd_canada_sin();
    +----------------------+
    | gen_rnd_canada_sin() |
    +----------------------+
    | 046-454-286          |
    +----------------------+
    
  • gen_rnd_email(*name_size*, *surname_size*, *domain*)

    生成一个以random_name.random_surname@domain形式的随机电子邮件地址。

    参数:

    • name_size: (可选)一个整数,指定地址中名称部分的字符数。如果未提供name_size,默认值为五。

    • surname_size: (可选)一个整数,指定地址中姓氏部分的字符数。如果未提供surname_size,默认值为七。

    • domain: (可选)一个字符串,指定地址的域部分。如果未提供domain,默认值为example.com

    返回值:

    一个以utf8mb4字符集编码的随机电子邮件地址。

    示例:

    mysql> SELECT gen_rnd_email(name_size = 4, surname_size = 5, domain = 'mynet.com');
    +----------------------------------------------------------------------+
    | gen_rnd_email(name_size = 4, surname_size = 5, domain = 'mynet.com') |
    +----------------------------------------------------------------------+
    | lsoy.qwupp@mynet.com                                                 |
    +----------------------------------------------------------------------+
    mysql> SELECT gen_rnd_email();
    +---------------------------+
    | gen_rnd_email()           |
    +---------------------------+
    | ijocv.mwvhhuf@example.com |
    +---------------------------+
    
  • gen_rnd_iban([*country*, *size*])

    *AAAA* *BBBB* *CCCC* *DDDD*格式生成一个随机的国际银行账号(IBAN)。生成的字符串以两位字符的国家代码开头,根据 IBAN 规范计算的两位校验数字和随机的字母数字字符,直到达到所需大小。

    警告

    gen_rnd_iban()返回的值仅用于测试目的,如果与有效的国家代码一起使用,则不适合发布。无法保证给定的返回值不会分配给合法的银行账户。如果需要发布gen_rnd_iban()的结果,请考虑使用mask_iban()进行掩码处理。

    参数:

    • country: (可选)两位字符的国家代码;默认值为ZZ

    • size: (可选)有意义字符的数量;默认 16,最小 15,最大 34

    返回值:

    utf8mb4字符集编码的随机 IBAN。

    示例:

    mysql> SELECT gen_rnd_iban();
    +-----------------------------+
    | gen_rnd_iban()              |
    +-----------------------------+
    | ZZ79 3K2J WNH9 1V0DI        |
    +-----------------------------+
    
  • gen_rnd_pan([*size*])

    生成一个随机的支付卡主帐号。该号码通过 Luhn 检查(执行校验和验证以对检查位进行检查的算法)。

    警告

    gen_rnd_pan()返回的数值仅应用于测试目的,不适合发布。无法保证给定的返回值不会分配给合法的支付账户。如果需要发布gen_rnd_pan()的结果,考虑使用mask_pan()mask_pan_relaxed()进行掩码处理。

    参数:

    • size:(可选)一个指定结果大小的整数。如果未给出size,默认值为 16。如果给出,size必须是 12 到 19 范围内的整数。

    返回值:

    作为字符串的随机支付号码,或者如果给定超出允许范围的size参数,则返回错误。

    示例:

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX5805        |
    +-------------------------+
    mysql> SELECT mask_pan(gen_rnd_pan(19));
    +---------------------------+
    | mask_pan(gen_rnd_pan(19)) |
    +---------------------------+
    | XXXXXXXXXXXXXXX5067       |
    +---------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 398403XXXXXX9547                |
    +---------------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan(19));
    +-----------------------------------+
    | mask_pan_relaxed(gen_rnd_pan(19)) |
    +-----------------------------------+
    | 578416XXXXXXXXX6509               |
    +-----------------------------------+
    mysql> SELECT gen_rnd_pan(20);
    ERROR 1123 (HY000): Can't initialize function 'gen_rnd_pan'; Minimal value of argument 0 is 14.
    
  • gen_rnd_ssn()

    *AAA*-*BB*-*CCCC*格式生成一个随机的美国社会保障号码。AAA部分大于 900,这些特征不用于合法的社会保障号码。

    参数:

    无。

    返回值:

    作为以utf8mb4字符集编码的字符串的随机社会保障号码。

    示例:

    mysql> SELECT gen_rnd_ssn();
    +---------------+
    | gen_rnd_ssn() |
    +---------------+
    | 951-26-0058   |
    +---------------+
    
  • gen_rnd_uk_nin()

    生成一个随机的英国国民保险号码(UK NIN),格式为九个字符。NIN 以从有效前缀集合中随机选择的两个字符前缀开始,接着是六个随机数字,以及从有效后缀集合中随机选择的一个字符后缀。

    警告

    gen_rnd_uk_nin()返回的数值仅应用于测试目的,不适合发布。无法保证给定的返回值不会分配给合法的 NIN。如果需要发布gen_rnd_uk_nin()的结果,考虑使用mask_uk_nin()进行掩码处理。

    参数:

    无。

    返回值:

    作为以utf8mb4字符集编码的字符串的随机英国国民保险号码。

    示例:

    mysql> SELECT gen_rnd_uk_nin();
    +----------------------+
    | gen_rnd_uk_nin()     |
    +----------------------+
    | QQ123456C            |
    +----------------------+
    
  • gen_rnd_us_phone()

    1-555-*AAA*-*BBBB*格式生成一个随机的美国电话号码。555���号不用于合法的电话号码。

    参数:

    无。

    返回值:

    作为以utf8mb4字符集编码的字符串的随机美国电话号码。

    示例:

    mysql> SELECT gen_rnd_us_phone();
    +--------------------+
    | gen_rnd_us_phone() |
    +--------------------+
    | 1-555-682-5423     |
    +--------------------+
    
  • gen_rnd_uuid()

    生成带有破折号分隔的随机通用唯一标识符(UUID)。

    参数:

    无。

    返回值:

    作为utf8mb4字符集中编码的字符串的随机 UUID。

    示例:

    mysql> SELECT gen_rnd_uuid();
    +--------------------------------------+
    | gen_rnd_uuid()                       |
    +--------------------------------------+
    | 123e4567-e89b-12d3-a456-426614174000 |
    +--------------------------------------+
    
字典掩码管理组件函数

本节中的组件函数操作术语字典并根据其执行管理掩码操作。所有这些函数都需要MASKING_DICTIONARIES_ADMIN权限。

创建术语字典时,它将成为字典注册表的一部分,并被分配一个名称供其他字典函数使用。

  • masking_dictionary_remove(*dictionary_name*)

    从字典注册表中删除一个字典及其所有术语。此函数需要MASKING_DICTIONARIES_ADMIN权限。

    参数:

    • dictionary_name:命名要从字典表中移除的字典的字符串。此参数转换为utf8mb4字符集。

    返回值:

    一个字符串,指示移除操作是否成功。1表示成功。NULL表示未找到字典名称。

    示例:

    mysql> SELECT masking_dictionary_remove('mydict');
    +-------------------------------------+
    | masking_dictionary_remove('mydict') |
    +-------------------------------------+
    |                                   1 |
    +-------------------------------------+
    mysql> SELECT masking_dictionary_remove('no-such-dict');
    +-------------------------------------------+
    | masking_dictionary_remove('no-such-dict') |
    +-------------------------------------------+
    |                                      NULL |
    +-------------------------------------------+
    
  • masking_dictionary_term_add(*dictionary_name*, *term_name*)

    向命名字典添加一个术语。此函数需要MASKING_DICTIONARIES_ADMIN权限。

    重要

    字典及其术语持久保存在mysql模式的表中。如果用户重复执行gen_dictionary(),则字典中的所有术语对任何用户帐户都是可访问的。避免向字典中添加敏感信息。

    每个术语由一个命名的字典定义。masking_dictionary_term_add()允许您一次添加一个字典术语。

    参数:

    • dictionary_name:为字典提供名称的字符串。此参数转换为utf8mb4字符集。

    • term_name:指定字典表中术语名称的字符串。此参数转换为utf8mb4字符集。

    返回值:

    一个字符串,指示添加术语操作是否成功。1表示成功。NULL表示失败。术语添加失败可能出现多种原因,包括:

    • 已经添加了具有给定名称的术语。

    • 未找到字典名称。

    示例:

    mysql> SELECT masking_dictionary_term_add('mydict','newterm');
    +-------------------------------------------------+
    | masking_dictionary_term_add('mydict','newterm') |
    +-------------------------------------------------+
    |                                               1 |
    +-------------------------------------------------+
    mysql> SELECT masking_dictionary_term_add('mydict','');
    +------------------------------------------+
    | masking_dictionary_term_add('mydict','') |
    +------------------------------------------+
    |                                     NULL |
    +------------------------------------------+
    
  • masking_dictionary_term_remove(*dictionary_name*, *term_name*)

    从命名字典中删除一个术语。此函数需要MASKING_DICTIONARIES_ADMIN权限。

    参数:

    • dictionary_name: 为字典提供名称的字符串。此参数转换为utf8mb4字符集。

    • term_name: 指定字典表中术语名称的字符串。此参数转换为utf8mb4字符集。

    返回值:

    一个指示删除术语操作是否成功的字符串。1表示成功。NULL表示失败。术语删除失败可能出现多种原因,包括:

    • 未找到具有给定名称的术语。

    • 未找到字典名称。

    示例:

    mysql> SELECT masking_dictionary_term_add('mydict','newterm');
    +-------------------------------------------------+
    | masking_dictionary_term_add('mydict','newterm') |
    +-------------------------------------------------+
    |                                               1 |
    +-------------------------------------------------+
    mysql> SELECT masking_dictionary_term_remove('mydict','');
    +---------------------------------------------+
    | masking_dictionary_term_remove('mydict','') |
    +---------------------------------------------+
    |                                        NULL |
    +---------------------------------------------+
    
字典生成组件函数

本节中的组件函数操作术语字典并基于其执行生成操作。

创建术语字典时,它将成为字典注册表的一部分,并被分配一个名称供其他字典函数使用。

  • gen_blocklist(*str*, *from_dictionary_name*, *to_dictionary_name*)

    用第二个字典中的术语替换第一个字典中的术语,并返回替换的术语。这通过替换掩盖了原始术语。

    参数:

    • term: 指示要替换的术语的字符串。此参数转换为utf8mb4字符集。

    • from_dictionary_name: 命名包含要替换的术语的字典的字符串。此参数转换为utf8mb4字符集。

    • to_dictionary_name: 命名要从中选择替换术语的字典的字符串。此参数转换为utf8mb4字符集。

    返回值:

    to_dictionary_name中随机选择的以utf8mb4字符集编码的字符串作为term的替换,如果term不在from_dictionary_name中出现,则返回term,或者如果任一字典名称不在字典注册表中,则返回错误。

    注意

    如果要替换的术语出现在两个字典中,则返回值可能是相同的术语。

    示例:

    mysql> SELECT gen_blocklist('Berlin', 'DE_Cities', 'US_Cities');
    +---------------------------------------------------+
    | gen_blocklist('Berlin', 'DE_Cities', 'US_Cities') |
    +---------------------------------------------------+
    | Phoenix                                           |
    +---------------------------------------------------+
    
  • gen_dictionary(*dictionary_name*)

    返回一个字典中的随机术语。

    参数:

    • dictionary_name: 命名要从中选择术语的字典的字符串。此参数转换为utf8mb4字符集。

    返回值:

    从字典中以utf8mb4字符集编码的字符串中返回一个随机术语,如果字典名称不在字典注册表中,则返回NULL

    示例:

    mysql> SELECT gen_dictionary('mydict');
    +--------------------------+
    | gen_dictionary('mydict') |
    +--------------------------+
    | My term                  |
    +--------------------------+
    mysql> SELECT gen_dictionary('no-such-dict');
    ERROR 1123 (HY000): Can't initialize function 'gen_dictionary'; Cannot access 
    dictionary, check if dictionary name is valid.
    

8.5.3 MySQL 企业数据脱敏和去标识化插件

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-plugin.html

8.5.3.1 MySQL 企业数据脱敏和去标识化插件安装

8.5.3.2 使用 MySQL 企业数据脱敏和去标识化插件

8.5.3.3 MySQL 企业数据脱敏和去标识化插件功能参考

8.5.3.4 MySQL 企业数据脱敏和去标识化插件功能描述

MySQL 企业数据脱敏和去标识化基于一个实现这些元素的插件库:

  • 一个名为data_masking的服务器端插件。

  • 一组可加载的函数提供了一个 SQL 级别的 API,用于执行脱敏和去标识化操作。其中一些函数需要SUPER权限。

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-plugin-installation.html

8.5.3.1 MySQL 企业数据脱敏和去标识化插件安装

本节描述了如何安装或卸载 MySQL 企业数据脱敏和去标识化,它是作为一个包含插件和几个可加载函数的插件库文件实现的。有关安装或卸载插件和可加载函数的一般信息,请参见 Section 7.6.1, “Installing and Uninstalling Plugins”和 Section 7.7.1, “Installing and Uninstalling Loadable Functions”。

要被服务器使用,插件库文件必须位于 MySQL 插件目录中(由plugin_dir系统变量命名的目录)。如有必要,在服务器启动时通过设置plugin_dir的值来配置插件目录位置。

插件库文件的基本名称是data_masking。文件名后缀因平台而异(例如,Unix 和类 Unix 系统使用.so,Windows 使用.dll)。

要安装 MySQL 企业数据脱敏和去标识化插件和函数,请使用INSTALL PLUGINCREATE FUNCTION语句,并根据需要调整平台的.so后缀:

INSTALL PLUGIN data_masking SONAME 'data_masking.so';
CREATE FUNCTION gen_blocklist RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_dictionary RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_dictionary_drop RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_dictionary_load RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_range RETURNS INTEGER
  SONAME 'data_masking.so';
CREATE FUNCTION gen_rnd_email RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_rnd_pan RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_rnd_ssn RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION gen_rnd_us_phone RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION mask_inner RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION mask_outer RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION mask_pan RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION mask_pan_relaxed RETURNS STRING
  SONAME 'data_masking.so';
CREATE FUNCTION mask_ssn RETURNS STRING
  SONAME 'data_masking.so';

如果插件和函数在复制源服务器上使用,则还需在所有副本服务器上安装它们,以避免复制问题。

一旦按照上述描述安装,插件和函数将保持安装状态,直到被卸载。要移除它们,请使用UNINSTALL PLUGINDROP FUNCTION语句:

UNINSTALL PLUGIN data_masking;
DROP FUNCTION gen_blocklist;
DROP FUNCTION gen_dictionary;
DROP FUNCTION gen_dictionary_drop;
DROP FUNCTION gen_dictionary_load;
DROP FUNCTION gen_range;
DROP FUNCTION gen_rnd_email;
DROP FUNCTION gen_rnd_pan;
DROP FUNCTION gen_rnd_ssn;
DROP FUNCTION gen_rnd_us_phone;
DROP FUNCTION mask_inner;
DROP FUNCTION mask_outer;
DROP FUNCTION mask_pan;
DROP FUNCTION mask_pan_relaxed;
DROP FUNCTION mask_ssn;

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-plugin-usage.html

8.5.3.2 使用 MySQL 企业数据脱敏和去标识化插件

在使用 MySQL 企业数据脱敏和去标识化之前,请根据提供的说明安装它,详情请参阅第 8.5.3.1 节,“MySQL 企业数据脱敏和去标识化插件安装”。

要在应用程序中使用 MySQL 企业数据脱敏和去标识化,请调用适用于所需操作的函数。有关详细的函数描述,请参阅第 8.5.3.4 节,“MySQL 企业数据脱敏和去标识化插件函数描述”。本节演示如何使用这些函数执行一些代表性任务。首先概述可用函数,然后展示这些函数在实际环境中的使用示例:

  • 脱敏数据以删除识别特征

  • 生成具有特定特征的随机数据

  • 使用字典生成随机数据

  • 使用脱敏数据进行客户识别

  • 创建显示脱敏数据的视图

脱敏数据以删除识别特征

MySQL 提供通用脱敏函数,用于脱敏任意字符串,以及特定类型值的专用脱敏函数。

通用脱敏函数

mask_inner()mask_outer() 是根据字符串内部位置脱敏任意字符串的通用函数:

  • mask_inner() 脱敏其字符串参数的内部,保留末尾未脱敏。其他参数指定未脱敏末尾的大小。

    mysql> SELECT mask_inner('This is a string', 5, 1);
    +--------------------------------------+
    | mask_inner('This is a string', 5, 1) |
    +--------------------------------------+
    | This XXXXXXXXXXg                     |
    +--------------------------------------+
    mysql> SELECT mask_inner('This is a string', 1, 5);
    +--------------------------------------+
    | mask_inner('This is a string', 1, 5) |
    +--------------------------------------+
    | TXXXXXXXXXXtring                     |
    +--------------------------------------+
    
  • mask_outer() 做相反的操作,遮盖其字符串参数的末尾,保留内部不遮盖。其他参数指定了遮盖末尾的大小。

    mysql> SELECT mask_outer('This is a string', 5, 1);
    +--------------------------------------+
    | mask_outer('This is a string', 5, 1) |
    +--------------------------------------+
    | XXXXXis a strinX                     |
    +--------------------------------------+
    mysql> SELECT mask_outer('This is a string', 1, 5);
    +--------------------------------------+
    | mask_outer('This is a string', 1, 5) |
    +--------------------------------------+
    | Xhis is a sXXXXX                     |
    +--------------------------------------+
    

默认情况下,mask_inner()mask_outer() 使用'X'作为遮盖字符,但允许一个可选的遮盖字符参数:

mysql> SELECT mask_inner('This is a string', 5, 1, '*');
+-------------------------------------------+
| mask_inner('This is a string', 5, 1, '*') |
+-------------------------------------------+
| This **********g                          |
+-------------------------------------------+
mysql> SELECT mask_outer('This is a string', 5, 1, '#');
+-------------------------------------------+
| mask_outer('This is a string', 5, 1, '#') |
+-------------------------------------------+
| #####is a strin#                          |
+-------------------------------------------+
特殊用途的遮盖函数

其他遮盖函数期望一个表示特定类型值的字符串参数,并对其进行遮盖以消除识别特征。

注意

这里的示例使用返回适当类型值的随机值生成函数来提供函数参数。有关生成函数的更多信息,请参阅使用特定特征生成随机数据。

支付卡主帐号遮盖。 遮盖函数提供主帐号数字的严格和宽松遮盖。

  • mask_pan() 遮盖号码除最后四位外的所有内容:

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX2461        |
    +-------------------------+
    
  • mask_pan_relaxed() 类似,但不遮盖表示支付卡发行者的前六位数字:

    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 770630XXXXXX0807                |
    +---------------------------------+
    

美国社会安全号码遮盖。 mask_ssn() 遮盖号码除最后四位外的所有内容:

mysql> SELECT mask_ssn(gen_rnd_ssn());
+-------------------------+
| mask_ssn(gen_rnd_ssn()) |
+-------------------------+
| XXX-XX-1723             |
+-------------------------+
使用特定特征生成随机数据

几个函数生成随机值。这些值可用于测试、模拟等用途。

gen_range() 返回从给定范围中选择的随机整数:

mysql> SELECT gen_range(1, 10);
+------------------+
| gen_range(1, 10) |
+------------------+
|                6 |
+------------------+

gen_rnd_email() 返回一个在example.com域中的随机电子邮件地址:

mysql> SELECT gen_rnd_email();
+---------------------------+
| gen_rnd_email()           |
+---------------------------+
| ayxnq.xmkpvvy@example.com |
+---------------------------+

gen_rnd_pan() 返回一个随机的支付卡主帐号数字:

mysql> SELECT gen_rnd_pan();

gen_rnd_pan() 函数的结果未显示,因为其返回值仅应用于测试目的,而不用于发布。不能保证该号码未分配给合法支付帐户。)

gen_rnd_ssn() 返回一个随机的美国社会安全号码,第一部分和第二部分分别从未用于合法号码的范围中选择:

mysql> SELECT gen_rnd_ssn();
+---------------+
| gen_rnd_ssn() |
+---------------+
| 912-45-1615   |
+---------------+

gen_rnd_us_phone() 返回一个在未用于合法号码的 555 区号中的随机美国电话号码:

mysql> SELECT gen_rnd_us_phone();
+--------------------+
| gen_rnd_us_phone() |
+--------------------+
| 1-555-747-5627     |
+--------------------+
使用字典生成随机数据

MySQL 企业数据蒙面和去标识化使得可以将字典用作随机值的来源。要使用字典,必须首先从文件加载它并赋予一个名称。每个加载的字典都成为字典注册表的一部分。然后可以从注册的字典中选择项目并用作随机值或替换其他值。

有效的字典文件具有以下特征:

  • 文件内容为纯文本,每行一个术语。

  • 空行将被忽略。

  • 文件必须至少包含一个术语。

假设名为de_cities.txt的文件包含德国这些城市名称:

Berlin
Munich
Bremen

还假设名为us_cities.txt的文件包含美国这些城市名称:

Chicago
Houston
Phoenix
El Paso
Detroit

假设secure_file_priv系统变量设置为/usr/local/mysql/mysql-files。在这种情况下,将字典文件复制到该目录,以便 MySQL 服务器可以访问它们。然后使用gen_dictionary_load()加载字典到字典注册表并分配名称:

mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities');
+--------------------------------------------------------------------------------+
| gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities') |
+--------------------------------------------------------------------------------+
| Dictionary load success                                                        |
+--------------------------------------------------------------------------------+
mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities');
+--------------------------------------------------------------------------------+
| gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities') |
+--------------------------------------------------------------------------------+
| Dictionary load success                                                        |
+--------------------------------------------------------------------------------+

要从字典中选择一个随机术语,请使用gen_dictionary()

mysql> SELECT gen_dictionary('DE_Cities');
+-----------------------------+
| gen_dictionary('DE_Cities') |
+-----------------------------+
| Berlin                      |
+-----------------------------+
mysql> SELECT gen_dictionary('US_Cities');
+-----------------------------+
| gen_dictionary('US_Cities') |
+-----------------------------+
| Phoenix                     |
+-----------------------------+

要从多个字典中选择一个随机术语,随机选择其中一个字典,然后从中选择���个术语:

mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Detroit                                                       |
+---------------------------------------------------------------+
mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Bremen                                                        |
+---------------------------------------------------------------+

gen_blocklist()函数使得可以用另一个字典中的术语替换一个字典中的术语,从而通过替换实现蒙面。它的参数是要替换的术语,术语出现的字典,以及要选择替换的字典。例如,要用美国城市替换德国城市,或者反之,可以像这样使用gen_blocklist()

mysql> SELECT gen_blocklist('Munich', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Munich', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Houston                                           |
+---------------------------------------------------+
mysql> SELECT gen_blocklist('El Paso', 'US_Cities', 'DE_Cities');
+----------------------------------------------------+
| gen_blocklist('El Paso', 'US_Cities', 'DE_Cities') |
+----------------------------------------------------+
| Bremen                                             |
+----------------------------------------------------+

如果要替换的术语不在第一个字典中,gen_blocklist()将不做任何更改返回它:

mysql> SELECT gen_blocklist('Moscow', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Moscow', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Moscow                                            |
+---------------------------------------------------+
使用蒙面数据进行客户识别

在客户服务呼叫中心,一个常见的身份验证技术是要求客户提供他们社会安全号码(SSN)的最后四位数字。例如,一个客户可能说她的名字是乔安娜邦德,她的最后四位 SSN 数字是0007

假设包含客户记录的customer表具有以下列:

  • id:客户 ID 号码。

  • first_name:客户名字。

  • last_name:客户姓氏。

  • ssn:客户社会安全号码。

例如,表可以定义如下:

CREATE TABLE customer
(
  id         BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(40),
  last_name  VARCHAR(40),
  ssn        VARCHAR(11)
);

由客户服务代表使用的应用程序检查客户社会安全号码可能执行类似这样的查询:

mysql> SELECT id, ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | ssn         |
+-----+-------------+
| 786 | 906-39-0007 |
+-----+-------------+

然而,这会将社会安全号码暴露给客户服务代表,他们没有必要看到除最后四位数字之外的任何内容。相反,应用程序可以使用此查询仅显示蒙面的社会安全号码:

mysql> SELECT id, mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | XXX-XX-0007 |
+-----+-------------+

现在代表只能看到必要的内容,客户隐私得到保护。

为什么在mask_ssn()的参数中使用了CONVERT()函数?因为mask_ssn()需要一个长度为 11 的参数。因此,即使ssn被定义为VARCHAR(11),如果ssn列具有多字节字符集,当传递给可加载函数时,它可能看起来比 11 个字节长,从而导致错误。将值转换为二进制字符串可以确保函数看到一个长度为 11 的参数。

当字符串参数没有单字节字符集时,可能需要类似的技术来处理其他数据掩码函数。

创建显示掩码数据的视图

如果来自表的掩码数据用于多个查询,定义一个生成掩码数据的视图可能会更方便。这样,应用程序可以从视图中选择,而无需在单个查询中执行掩码操作。

例如,可以像这样定义前一节中customer表的掩码视图:

CREATE VIEW masked_customer AS
SELECT id, first_name, last_name,
mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
FROM customer;

查询客户信息的操作变得更简单,但仍返回掩码数据:

mysql> SELECT id, masked_ssn
mysql> FROM masked_customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | XXX-XX-0007 |
+-----+-------------+

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-plugin-function-reference.html

8.5.3.3 MySQL 企业数据掩码和去识别插件函数参考

表 8.47 MySQL 企业数据掩码和去识别插件函数

名称 描述 引入 废弃
gen_blacklist() 执行字典术语替换 8.0.23
gen_blocklist() 执行字典术语替换 8.0.23
gen_dictionary_drop() 从注册表中删除字典
gen_dictionary_load() 将字典加载到注册表中
gen_dictionary() 从字典返回随机术语
gen_range() 在范围内生成随机数
gen_rnd_email() 生成随机电子邮件地址
gen_rnd_pan() 生成随机支付卡主帐号
gen_rnd_ssn() 生成随机美国社会安全号码
gen_rnd_us_phone() 生成随机美国电话号码
mask_inner() 掩盖字符串的内部部分
mask_outer() 掩盖字符串的左右部分
mask_pan() 掩盖字符串的支付卡主帐号部分
mask_pan_relaxed() 掩盖字符串的支付卡主帐号部分
mask_ssn() 掩盖美国社会安全号码
名称 描述 引入 废弃

原文:dev.mysql.com/doc/refman/8.0/en/data-masking-plugin-functions.html

8.5.3.4 MySQL 企业数据脱敏和去标识化插件函数描述

MySQL 企业数据脱敏和去标识化插件库包括多个函数,可分为以下类别:

  • 数据脱敏插件函数

  • 随机数据生成插件函数

  • 随机数据基于字典的插件函数

从 MySQL 8.0.19 开始,这些函数支持单字节latin1字符集用于字符串参数和返回值。在 MySQL 8.0.19 之前,这些函数将字符串参数视为二进制字符串(这意味着它们不区分大小写),并且字符串返回值为二进制字符串。您可以通过以下方式查看返回值字符集的差异:

MySQL 8.0.19 及更高版本:

mysql> SELECT CHARSET(gen_rnd_email());
+--------------------------+
| CHARSET(gen_rnd_email()) |
+--------------------------+
| latin1                   |
+--------------------------+

MySQL 8.0.19 之前:

mysql> SELECT CHARSET(gen_rnd_email());
+--------------------------+
| CHARSET(gen_rnd_email()) |
+--------------------------+
| binary                   |
+--------------------------+

对于任何版本,如果字符串返回值应该使用不同的字符集,请进行转换。以下示例显示如何将gen_rnd_email()的结果转换为utf8mb4字符集:

SET @email = CONVERT(gen_rnd_email() USING utf8mb4);

要明确生成二进制字符串(例如,生成 MySQL 8.0.19 之前版本的结果),请执行以下操作:

SET @email = CONVERT(gen_rnd_email() USING binary);

有时可能需要转换字符串参数,如使用脱敏数据进行客户识别中所示。

如果从mysql客户端内调用 MySQL 企业数据脱敏和去标识化函数,则二进制字符串结果将以十六进制表示,具体取决于--binary-as-hex的值。有关该选项的更多信息,请参见第 6.5.1 节,“mysql — MySQL 命令行客户端”。

数据脱敏插件函数

本节中的每个插件函数都对其字符串参数执行脱敏操作并返回脱敏结果。

  • mask_inner(*str*, *margin1*, *margin2* [, *mask_char*])

    脱敏字符串的内部部分,保留末尾不变,并返回结果。可以指定可选的脱敏字符。

    参数:

    • str: 需要脱敏的字符串。

    • margin1:非负整数,指定要保留未掩码的字符串左端字符数。如果值为 0,则不保留左端字符未掩码。

    • margin2:非负整数,指定要保留未掩码的字符串右端字符数。如果值为 0,则不保留右端字符未掩码。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'X'

      掩码字符必须是单字节字符。尝试使用多字节字符会产生错误。

    返回值:

    掩码字符串,如果任一边距为负则为NULL

    如果边距值的总和大于参数长度,则不进行掩码,参数返回不变。

    示例:

    mysql> SELECT mask_inner('abcdef', 1, 2), mask_inner('abcdef',0, 5);
    +----------------------------+---------------------------+
    | mask_inner('abcdef', 1, 2) | mask_inner('abcdef',0, 5) |
    +----------------------------+---------------------------+
    | aXXXef                     | Xbcdef                    |
    +----------------------------+---------------------------+
    mysql> SELECT mask_inner('abcdef', 1, 2, '*'), mask_inner('abcdef',0, 5, '#');
    +---------------------------------+--------------------------------+
    | mask_inner('abcdef', 1, 2, '*') | mask_inner('abcdef',0, 5, '#') |
    +---------------------------------+--------------------------------+
    | a***ef                          | #bcdef                         |
    +---------------------------------+--------------------------------+
    
  • mask_outer(*str*, *margin1*, *margin2* [, *mask_char*])

    掩盖字符串的左右端,保留内部未掩码,并返回结果。可以指定一个可选的掩码字符。

    参数:

    • str:要掩码的字符串。

    • margin1:非负整数,指定要掩码的字符串左端字符数。如果值为 0,则不掩盖左端字符。

    • margin2:非负整数,指定要掩码的字符串右端字符数。如果值为 0,则不掩盖右端字符。

    • mask_char:(可选)用于掩码的单个字符。如果未提供mask_char,默认为'X'

      掩码字符必须是单字节字符。尝试使用多字节字符会产生错误。

    返回值:

    掩码字符串,如果任一边距为负则为NULL

    如果边距值的总和大于参数长度,则整个参数将被掩码。

    示例:

    mysql> SELECT mask_outer('abcdef', 1, 2), mask_outer('abcdef',0, 5);
    +----------------------------+---------------------------+
    | mask_outer('abcdef', 1, 2) | mask_outer('abcdef',0, 5) |
    +----------------------------+---------------------------+
    | XbcdXX                     | aXXXXX                    |
    +----------------------------+---------------------------+
    mysql> SELECT mask_outer('abcdef', 1, 2, '*'), mask_outer('abcdef',0, 5, '#');
    +---------------------------------+--------------------------------+
    | mask_outer('abcdef', 1, 2, '*') | mask_outer('abcdef',0, 5, '#') |
    +---------------------------------+--------------------------------+
    | *bcd**                          | a#####                         |
    +---------------------------------+--------------------------------+
    
  • mask_pan(*str*)

    掩码支付卡主帐号并返回除了最后四位以外的所有数字都替换为'X'字符的数字。

    参数:

    • str:要掩码的字符串。字符串必须适合主帐号的长度,但不进行其他检查。

    返回值:

    掩盖的支付号码作为字符串。如果参数长度不足,则返回不变。

    示例:

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX9102        |
    +-------------------------+
    mysql> SELECT mask_pan(gen_rnd_pan(19));
    +---------------------------+
    | mask_pan(gen_rnd_pan(19)) |
    +---------------------------+
    | XXXXXXXXXXXXXXX8268       |
    +---------------------------+
    mysql> SELECT mask_pan('a*Z');
    +-----------------+
    | mask_pan('a*Z') |
    +-----------------+
    | a*Z             |
    +-----------------+
    
  • mask_pan_relaxed(*str*)

    掩码支付卡主帐号并返回除了前六位和最后四位以外的所有数字都替换为'X'字符的数字。前六位数字表示支付卡发行者。

    参数:

    • str:要掩码的字符串。字符串必须适合主帐号的长度,但不进行其他检查。

    返回值:

    掩盖的支付号码作为字符串。如果参数长度不足,则返回不变。

    示例:

    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 551279XXXXXX3108                |
    +---------------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan(19));
    +-----------------------------------+
    | mask_pan_relaxed(gen_rnd_pan(19)) |
    +-----------------------------------+
    | 462634XXXXXXXXX6739               |
    +-----------------------------------+
    mysql> SELECT mask_pan_relaxed('a*Z');
    +-------------------------+
    | mask_pan_relaxed('a*Z') |
    +-------------------------+
    | a*Z                     |
    +-------------------------+
    
  • mask_ssn(*str*)

    掩码美国社会保障号码,并将除最后四位数字外的所有内容替换为'X'字符。

    参数:

    • str:要掩码的字符串。字符串必须是 11 个字符长。

    返回值:

    掩码的社会保障号码作为字符串,如果参数长度不正确则返回错误。

    示例:

    mysql> SELECT mask_ssn('909-63-6922'), mask_ssn('abcdefghijk');
    +-------------------------+-------------------------+
    | mask_ssn('909-63-6922') | mask_ssn('abcdefghijk') |
    +-------------------------+-------------------------+
    | XXX-XX-6922             | XXX-XX-hijk             |
    +-------------------------+-------------------------+
    mysql> SELECT mask_ssn('909');
    ERROR 1123 (HY000): Can't initialize function 'mask_ssn'; MASK_SSN: Error:
    String argument width too small
    mysql> SELECT mask_ssn('123456789123456789');
    ERROR 1123 (HY000): Can't initialize function 'mask_ssn'; MASK_SSN: Error:
    String argument width too large
    
随机数据生成插件函数

本节中的插件函数会为不同类型的数据生成随机值。在可能的情况下,生成的值具有用于演示或测试值的特征,以避免将它们误认为是合法数据。例如,gen_rnd_us_phone() 返回一个使用未分配给实际使用电话号码的 555 区号的美国电话号码。各个函数描述会说明此原则的任何例外情况。

  • gen_range(*lower*, *upper*)

    生成从指定范围中选择的随机数。

    参数:

    • lower:指定范围下限的整数。

    • upper:指定范围上限的整数,必须不小于下限。

    返回值:

    一个在从lowerupper(包括)范围内的随机整数,如果upper参数小于lower则返回NULL

    示例:

    mysql> SELECT gen_range(100, 200), gen_range(-1000, -800);
    +---------------------+------------------------+
    | gen_range(100, 200) | gen_range(-1000, -800) |
    +---------------------+------------------------+
    |                 177 |                   -917 |
    +---------------------+------------------------+
    mysql> SELECT gen_range(1, 0);
    +-----------------+
    | gen_range(1, 0) |
    +-----------------+
    |            NULL |
    +-----------------+
    
  • gen_rnd_email()

    生成example.com域中的随机电子邮件地址。

    参数:

    无。

    返回值:

    作为字符串的随机电子邮件地址。

    示例:

    mysql> SELECT gen_rnd_email();
    +---------------------------+
    | gen_rnd_email()           |
    +---------------------------+
    | ijocv.mwvhhuf@example.com |
    +---------------------------+
    
  • gen_rnd_pan([*size*])

    生成随机支付卡主帐号。该号码通过 Luhn 检查(执行校验和验证以对抗检查位的算法)。

    警告

    gen_rnd_pan()返回的值仅应用于测试目的,不适合发布。无法保证给定的返回值未分配给合法支付账户。如果需要发布gen_rnd_pan()结果,请考虑使用mask_pan()mask_pan_relaxed()进行掩码处理。

    参数:

    • size:(可选)指定结果大小的整数。如果未给出size,则默认为 16。如果给出,size必须是 12 到 19 范围内的整数。

    返回值:

    作为字符串的随机支付号码,如果给定超出允许范围的size参数,则返回NULL

    示例:

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX5805        |
    +-------------------------+
    mysql> SELECT mask_pan(gen_rnd_pan(19));
    +---------------------------+
    | mask_pan(gen_rnd_pan(19)) |
    +---------------------------+
    | XXXXXXXXXXXXXXX5067       |
    +---------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 398403XXXXXX9547                |
    +---------------------------------+
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan(19));
    +-----------------------------------+
    | mask_pan_relaxed(gen_rnd_pan(19)) |
    +-----------------------------------+
    | 578416XXXXXXXXX6509               |
    +-----------------------------------+
    mysql> SELECT gen_rnd_pan(11), gen_rnd_pan(20);
    +-----------------+-----------------+
    | gen_rnd_pan(11) | gen_rnd_pan(20) |
    +-----------------+-----------------+
    | NULL            | NULL            |
    +-----------------+-----------------+
    
  • gen_rnd_ssn()

    *AAA*-*BB*-*CCCC*格式生成一个随机的美国社会安全号码。AAA部分大于 900,BB部分小于 70,这些特征不用于合法的社会安全号码。

    参数:

    无。

    返回值:

    一个随机的社会安全号码作为一个字符串。

    示例:

    mysql> SELECT gen_rnd_ssn();
    +---------------+
    | gen_rnd_ssn() |
    +---------------+
    | 951-26-0058   |
    +---------------+
    
  • gen_rnd_us_phone()

    1-555-*AAA*-*BBBB*格式生成一个随机的美国电话号码。555 区号不用于合法的电话号码。

    参数:

    无。

    返回值:

    一个随机的美国电话号码作为一个字符串。

    示例:

    mysql> SELECT gen_rnd_us_phone();
    +--------------------+
    | gen_rnd_us_phone() |
    +--------------------+
    | 1-555-682-5423     |
    +--------------------+
    
基于随机数据字典的插件函数

本节中的插件函数操作术语字典,并根据它们执行生成和掩盖操作。其中一些函数需要SUPER权限。

当加载字典时,它成为字典注册表的一部分,并被分配一个名称供其他字典函数使用。字典是从包含每行一个术语的纯文本文件中加载的。空行将被忽略。为了有效,字典文件必须至少包含一行非空行。

  • gen_blacklist(*str*, *dictionary_name*, *replacement_dictionary_name*)

    用第二个字典中的术语替换第一个字典中存在的术语,并返回替换术语。这通过替换掩盖了原始术语。此函数在 MySQL 8.0.23 中已弃用;请改用gen_blocklist()

  • gen_blocklist(*str*, *dictionary_name*, *replacement_dictionary_name*)

    用第二个字典中的术语替换第一个字典中存在的术语,并返回替换术语。这通过替换掩盖了原始术语。此函数在 MySQL 8.0.23 中添加;请改用gen_blacklist()

    参数:

    • str:指示要替换的术语的字符串。

    • dictionary_name:命名包含要替换的术语的字典的字符串。

    • replacement_dictionary_name:命名要选择替换术语的字典的字符串。

    返回值:

    replacement_dictionary_name中随机选择的字符串作为str的替换,如果它不在dictionary_name中,则为str,如果任一字典名称不在字典注册表中,则为NULL

    如果要替换的术语出现在两个字典中,返回值可能是相同的术语。

    示例:

    mysql> SELECT gen_blocklist('Berlin', 'DE_Cities', 'US_Cities');
    +---------------------------------------------------+
    | gen_blocklist('Berlin', 'DE_Cities', 'US_Cities') |
    +---------------------------------------------------+
    | Phoenix                                           |
    +---------------------------------------------------+
    
  • gen_dictionary(*dictionary_name*)

    从字典中返回一个随机术语。

    参数:

    • dictionary_name:命名要选择术语的字典的字符串。

    返回值:

    从字典中随机选择一个术语作为字符串,如果字典名称不在字典注册表中,则返回NULL

    示例:

    mysql> SELECT gen_dictionary('mydict');
    +--------------------------+
    | gen_dictionary('mydict') |
    +--------------------------+
    | My term                  |
    +--------------------------+
    mysql> SELECT gen_dictionary('no-such-dict');
    +--------------------------------+
    | gen_dictionary('no-such-dict') |
    +--------------------------------+
    | NULL                           |
    +--------------------------------+
    
  • gen_dictionary_drop(*dictionary_name*)

    从字典注册表中移除一个字典。

    此函数需要SUPER权限。

    参数:

    • dictionary_name:一个字符串,用于指定要从字典注册表中移除的字典的名称。

    返回值:

    一个指示删除操作是否成功的字符串。Dictionary removed表示成功。Dictionary removal error表示失败。

    示例:

    mysql> SELECT gen_dictionary_drop('mydict');
    +-------------------------------+
    | gen_dictionary_drop('mydict') |
    +-------------------------------+
    | Dictionary removed            |
    +-------------------------------+
    mysql> SELECT gen_dictionary_drop('no-such-dict');
    +-------------------------------------+
    | gen_dictionary_drop('no-such-dict') |
    +-------------------------------------+
    | Dictionary removal error            |
    +-------------------------------------+
    
  • gen_dictionary_load(*dictionary_path*, *dictionary_name*)

    将文件加载到字典注册表中,并为字典分配一个名称,以便在其他需要字典名称参数的函数中使用。

    此函数需要SUPER权限。

    重要提示

    字典不是持久的。应用程序使用的任何字典都必须在每次服务器启动时加载。

    一旦加载到注册表中,字典将按原样使用,即使底层字典文件发生更改。要重新加载字典,首先使用gen_dictionary_drop()将其删除,然后再次使用gen_dictionary_load()加载。

    参数:

    • dictionary_path:一个字符串,指定字典文件的路径名。

    • dictionary_name:一个字符串,为字典提供名称。

    返回值:

    一个指示加载操作是否成功的字符串。Dictionary load success表示成功。Dictionary load error表示失败。字典加载失败可能出现多种原因,包括:

    • 已加载具有给定名称的字典。

    • 未找到字典文件。

    • 字典文件不包含任何术语。

    • secure_file_priv系统变量已设置,但字典文件未位于该变量指定的目录中。

    示例:

    mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/mydict','mydict');
    +---------------------------------------------------------------------+
    | gen_dictionary_load('/usr/local/mysql/mysql-files/mydict','mydict') |
    +---------------------------------------------------------------------+
    | Dictionary load success                                             |
    +---------------------------------------------------------------------+
    mysql> SELECT gen_dictionary_load('/dev/null','null');
    +-----------------------------------------+
    | gen_dictionary_load('/dev/null','null') |
    +-----------------------------------------+
    | Dictionary load error                   |
    +-----------------------------------------+
    
posted @ 2024-06-23 16:26  绝不原创的飞龙  阅读(8)  评论(0编辑  收藏  举报