Documentation Home

6.4.5.7 审计日志过滤

笔记

要使审计日志过滤按此处所述工作,必须安装审计日志插件和随附的审计表和函数。如果插件安装时没有附带基于规则的过滤所需的审计表和函数,插件将在旧过滤模式下运行,如 第 6.4.5.10 节“旧模式审计日志过滤”中所述。Legacy 模式是 MySQL 5.7.13 之前的过滤行为;也就是说,在引入基于规则的过滤之前。

审计日志过滤的属性

审计日志插件能够通过过滤来控制审计事件的日志记录:

  • 可以使用以下特征过滤已审计的事件:

    • 用户帐号

    • 审计事件类

    • 审计事件子类

    • 审计事件字段,例如指示操作状态或执行的 SQL 语句的字段

  • 审计过滤是基于规则的:

    • 过滤器定义创建一组审计规则。定义可以配置为包括或排除基于刚刚描述的特征的日志记录事件。

    • 除了现有的事件记录功能外,过滤规则还具有阻止(中止)执行符合条件的事件的能力。

    • 可以定义多个过滤器,并且可以将任何给定的过滤器分配给任意数量的用户帐户。

    • 可以定义默认过滤器以用于没有明确分配过滤器的任何用户帐户。

    从 MySQL 8.0.30 开始,审计日志过滤用于实现组件服务。要从该版本中获取可用的可选查询统计信息,您可以使用服务组件将它们设置为过滤器,该服务组件实现将统计信息写入审计日志的服务。有关设置此过滤器的说明,请参阅 为离群值检测添加查询统计信息

    有关编写过滤规则的信息,请参阅 第 6.4.5.8 节,“编写审计日志过滤器定义”

  • 可以使用基于函数调用的 SQL 接口定义、显示和修改审计过滤器。

  • 审计过滤器定义存储在 mysql系统数据库的表中。

  • 在给定的会话中,只读 audit_log_filter_id 系统变量的值指示是否将过滤器分配给会话。

笔记

默认情况下,基于规则的审计日志过滤不会记录任何用户的可审计事件。要记录所有用户的所有可审核事件,请使用以下语句,这些语句创建一个简单的过滤器以启用日志记录并将其分配给默认帐户:

SELECT audit_log_filter_set_filter('log_all', '{ "filter": { "log": true } }');
SELECT audit_log_filter_set_user('%', 'log_all');

分配给的过滤器%用于来自没有明确分配过滤器的任何帐户的连接(最初对所有帐户都是如此)。

如前所述,审计过滤控制的 SQL 接口是基于函数的。以下列表简要总结了这些功能:

有关过滤功能的使用示例和完整详细信息,请参阅 使用审核日志过滤功能审核日志功能

审计日志过滤功能的约束

审核日志过滤功能受以下限制:

  • 要使用任何过滤功能, audit_log必须启用插件,否则会发生错误。此外,审计表必须存在,否则会出错。要安装 audit_log插件及其附带的函数和表,请参阅 第 6.4.5.2 节,“安装或卸载 MySQL Enterprise Audit”

  • 要使用任何过滤功能,用户必须拥有 权限,否则会发生错误。要将这些权限之一授予用户帐户,请使用以下语句: AUDIT_ADMIN SUPER

    GRANT privilege ON *.* TO user;

    或者,如果您希望避免授予 AUDIT_ADMINSUPER特权,同时仍允许用户访问特定的过滤功能, 则可以定义包装器”存储程序。此技术在使用通用密钥环函数中的密钥环函数的上下文中进行了描述;它可以适应与过滤功能一起使用。

  • audit_log如果安装了插件但未创建随附的审计表和函数,则 该插件以旧模式运行。该插件在服务器启动时将这些消息写入错误日志:

    [Warning] Plugin audit_log reported: 'Failed to open the audit log filter tables.'
    [Warning] Plugin audit_log reported: 'Audit Log plugin supports a filtering,
    which has not been installed yet. Audit Log plugin will run in the legacy
    mode, which will be disabled in the next release.'

    在传统模式下,可以仅根据事件帐户或状态进行过滤。有关详细信息,请参阅 第 6.4.5.10 节,“传统模式审计日志过滤”

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

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

使用审计日志过滤功能

在使用审计日志功能之前,请按照 第 6.4.5.2 节“安装或卸载 MySQL Enterprise Audit”中提供的说明安装它们。使用这些 功能中的任何功能都需要 AUDIT_ADMIN或 特权。SUPER

审计日志过滤功能通过提供一个接口来创建、修改和删除过滤器定义以及将过滤器分配给用户帐户来启用过滤控制。

过滤器定义是JSON 值。有关 JSON在 MySQL 中使用数据的信息,请参阅 第 11.5 节,“JSON 数据类型”。本节显示一些简单的过滤器定义。有关过滤器定义的更多信息,请参阅第 6.4.5.8 节,“编写审计日志过滤器定义”

当连接到达时,审计日志插件通过在当前过滤器分配中搜索用户帐户名来确定将哪个过滤器用于新会话:

  • 如果为用户分配了过滤器,则审核日志将使用该过滤器。

  • 否则,如果不存在特定于用户的筛选器分配,但有一个筛选器分配给默认帐户 ( %),则审核日志将使用默认筛选器。

  • 否则,审计日志不会从会话中选择任何审计事件进行处理。

如果在会话期间发生更改用户操作(请参阅 mysql_change_user()),则使用相同的规则更新会话的过滤器分配,但针对新用户。

默认情况下,没有帐户分配过滤器,因此任何帐户都不会处理可审计事件。

假设您希望将默认设置更改为仅记录与连接相关的活动(例如,查看连接、更改用户和断开连接事件,但不查看用户在连接时执行的 SQL 语句)。为此,定义一个过滤器(此处显示为log_conn_events),仅允许记录 connection类中的事件,并将该过滤器分配给默认帐户,由% 帐户名称表示:

SET @f = '{ "filter": { "class": { "name": "connection" } } }';
SELECT audit_log_filter_set_filter('log_conn_events', @f);
SELECT audit_log_filter_set_user('%', 'log_conn_events');

现在,审计日志使用此默认帐户过滤器来处理来自没有明确定义过滤器的任何帐户的连接。

要将过滤器显式分配给特定用户帐户,请定义过滤器,然后将其分配给相关帐户:

SELECT audit_log_filter_set_filter('log_all', '{ "filter": { "log": true } }');
SELECT audit_log_filter_set_user('user1@localhost', 'log_all');
SELECT audit_log_filter_set_user('user2@localhost', 'log_all');

现在为 user1@localhost和 启用了完整的日志记录user2@localhost。来自其他帐户的连接将继续使用默认帐户过滤器进行过滤。

要取消用户帐户与其当前过滤器的关联,请取消分配过滤器或分配不同的过滤器:

  • 要从用户帐户取消分配过滤器:

    SELECT audit_log_filter_remove_user('user1@localhost');

    该帐户的当前会话过滤不受影响。来自该帐户的后续连接将使用默认帐户过滤器进行过滤(如果有的话),否则不会被记录。

  • 要为用户帐户分配不同的过滤器:

    SELECT audit_log_filter_set_filter('log_nothing', '{ "filter": { "log": false } }');
    SELECT audit_log_filter_set_user('user1@localhost', 'log_nothing');

    该帐户的当前会话过滤不受影响。来自该帐户的后续连接将使用新过滤器进行过滤。对于此处显示的过滤器,这意味着不记录来自 user1@localhost.

对于审计日志过滤,用户名和主机名比较区分大小写。这不同于特权检查的比较,后者的主机名比较不区分大小写。

要删除过滤器,请执行以下操作:

SELECT audit_log_filter_remove_filter('log_nothing');

删除过滤器还会将其从分配给它的任何用户取消分配,包括这些用户的任何当前会话。

刚刚描述的过滤功能会立即影响审计过滤并更新 mysql系统数据库中存储过滤器和用户帐户的审计日志表(请参阅审计日志表)。也可以直接使用 、 和 等语句修改审计日志表INSERTUPDATEDELETE此类更改不会立即影响过滤。要刷新您的更改并使它们可操作,请调用 audit_log_filter_flush()

SELECT audit_log_filter_flush();
警告

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

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

要确定过滤器是否分配给当前会话,请检查只读 audit_log_filter_id系统变量的会话值。如果值为 0,则不分配过滤器。非零值表示分配的过滤器的内部维护 ID:

mysql> SELECT @@audit_log_filter_id;
+-----------------------+
| @@audit_log_filter_id |
+-----------------------+
|                     2 |
+-----------------------+