Documentation Home
MySQL 8.0 参考手册  / 第 6 章 安全  / 6.4 安全组件和插件  / 6.4.5 MySQL企业审计  /  6.4.5.5 配置审计日志特征

6.4.5.5 配置审计日志特征

本节介绍如何配置审计日志特性,例如审计日志插件写入事件的文件、写入事件的格式、是否启用日志文件压缩和加密以及空间管理。

笔记

此处描述的加密功能适用于 MySQL 8.0.17,但将当前加密功能与以前的更有限功能进行比较的部分除外;请参阅 MySQL 8.0.17 之前的审核日志文件加密

有关影响审计日志记录的函数和系统变量的其他信息,请参阅 审计日志函数审计日志选项和变量

审计日志插件还可以根据事件内容或事件发起的帐户来控制将哪些审计事件写入审计日志文件。请参阅 第 6.4.5.7 节,“审计日志过滤”

审计日志文件的命名约定

要配置审核日志文件名,请 audit_log_file在服务器启动时设置系统变量。默认名称 audit.log位于服务器数据目录中。为了获得最佳安全性,将审计日志写入一个目录,该目录只能由 MySQL 服务器和有正当理由查看日志的用户访问。

该插件将该 audit_log_file值解释为由可选的前导目录名称、基本名称和可选的后缀组成。如果启用了压缩或加密,则有效文件名(实际用于创建日志文件的名称)与配置的文件名不同,因为它具有额外的后缀:

  • 如果启用压缩,插件会添加一个后缀 .gz.

  • 如果启用了加密,插件会添加后缀 ,其中指示用于日志文件操作的加密密码。审计日志插件将加密密码存储在密钥环中;请参阅加密审计日志文件.pwd_id.encpwd_id

有效审计日志文件名是将适用的压缩和加密后缀添加到配置的文件名后得到的名称。例如,如果配置 audit_log_file值为 audit.log,则有效文件名是下表中显示的值之一。

启用的功能 有效文件名
无压缩或加密 audit.log
压缩 audit.log.gz
加密 audit.log.pwd_id.enc
压缩、加密 audit.log.gz.pwd_id.enc

pwd_id表示用于加密或解密文件的密码的ID。 pwd_id格式为 pwd_timestamp-seq,其中:

  • pwd_timestamp是一个 UTC 值, 格式表示密码的创建时间。 YYYYMMDDThhmmss

  • seq是一个序号。序列号从 1 开始,对于具有相同 pwd_timestamp值的密码递增。

以下是一些示例pwd_id 密码 ID 值:

20190403T142359-1
20190403T142400-1
20190403T142400-2

要构造相应的密钥环 ID 以将密码存储在密钥环中,审计日志插件会audit_log-为这些 pwd_id值添加一个前缀。对于刚刚显示的示例密码 ID,相应的密钥环 ID 为:

audit_log-20190403T142359-1
audit_log-20190403T142400-1
audit_log-20190403T142400-2

审计日志插件当前用于加密的密码ID是 pwd_timestamp取值最大的那个。如果多个密码都具有该pwd_timestamp 值,则当前密码 ID 是具有最大序列号的那个。例如,在上述一组密码ID中,其中有两个密码ID的时间戳最大 20190403T142400,因此当前密码ID就是序列号(2)最大的密码ID。

审计日志插件根据有效的审计日志文件名在初始化和终止期间执行某些操作:

  • 在初始化期间,插件会检查是否存在具有审计日志文件名的文件,如果存在则重命名它。(在这种情况下,插件假定先前的服务器调用在审核日志插件运行时意外退出。)插件然后写入一个新的空审核日志文件。

  • 在终止期间,插件重命名审计日志文件。

  • 文件重命名(无论是在插件初始化还是终止期间)根据自动基于大小的日志文件轮换的通常规则发生;请参阅 手动审核日志文件轮换(MySQL 8.0.31 之前)

选择审核日志文件格式

要配置审计日志文件格式,请 audit_log_format在服务器启动时设置系统变量。这些格式可用:

  • NEW: 新型 XML 格式。这是默认值。

  • OLD: 旧式 XML 格式。

  • JSON: JSON 格式。将审核日志写入 JSON 数组。只有这种格式支持可选的查询时间和大小统计信息,这些信息从 MySQL 8.0.30 开始可用。

有关每种格式的详细信息,请参阅 第 6.4.5.4 节,“审计日志文件格式”

添加异常值检测的查询统计信息

从 MySQL 8.0.30 开始,您可以使用可选数据字段扩展 JSON 格式的日志文件,以显示查询时间、发送和接收的字节数、返回给客户端的行数以及检查的行数。此数据在慢速查询日志中可用于符合条件的查询,在审计日志的上下文中,它同样有助于检测异常值以进行活动分析。只有当审计日志是JSON格式( )时才可以添加扩展数据字段audit_log_format=JSON,这不是默认设置。

查询统计信息通过您设置为审核日志过滤功能的组件服务传送到审核日志。这些服务被命名为 mysql_audit_print_service_longlong_data_source and mysql_audit_print_service_double_data_source。您可以为每个输出项选择任一数据类型。对于查询时间,longlong以微秒为单位double输出值,以秒为单位输出值。

audit_log_filter_set_filter() 您使用审计日志功能 添加查询统计信息 ,作为serviceJSON 过滤语法的元素,如下所示:

SELECT audit_log_filter_set_filter('QueryStatistics',  
                                   '{ "filter": { "class": { "name": "general", "event": { "name": “status", "print" : '
                                   '{ "service": { "implementation": "mysql_server", "tag": "query_statistics", "element": [ '
                                   '{ "name": "query_time",     "type": "double" }, '
                                   '{ "name": "bytes_sent",     "type": "longlong" }, '
                                   '{ "name": "bytes_received", "type": "longlong" }, '
                                   '{ "name": "rows_sent",      "type": "longlong" }, '
                                   '{ "name": "rows_examined",  "type": "longlong" } ] } } } } } }');

对于要填充的bytes_sentbytes_received字段,系统变量 log_slow_extra必须设置为 ON。如果系统变量值为 value is OFF,则将空值写入这些字段的日志文件。

如果要停止收集查询统计信息,使用 audit_log_filter_set_filter() 审计日志功能去除过滤器,例如:

SELECT audit_log_filter_remove_filter('QueryStatistics');
压缩审计日志文件

可以为任何日志记录格式启用审核日志文件压缩。

要配置审计日志文件压缩,请 audit_log_compression在服务器启动时设置系统变量。允许的值为 NONE(无压缩;默认值)和 GZIP(GNU Zip 压缩)。

如果同时启用压缩和加密,则压缩发生在加密之前。要手动恢复原始文件,请先解密,然后解压缩。请参阅 手动解压缩和解密审计日志文件

加密审计日志文件

可以为任何日志记录格式启用审计日志文件加密。加密基于用户定义的密码(审计日志插件生成的初始密码除外)。要使用此功能,必须启用 MySQL 密钥环,因为审核日志记录使用它来存储密码。可以使用任何密钥环组件或插件;有关说明,请参阅第 6.4.4 节,“MySQL 密钥环”

要配置审计日志文件加密,请 audit_log_encryption在服务器启动时设置系统变量。允许的值为 NONE(无加密;默认值)和 AES(AES-256-CBC 密码加密)。

要在运行时设置或获取加密密码,请使用这些审计日志函数:

  • 要设置当前加密密码,请调用 audit_log_encryption_password_set()。此函数将新密码存储在密钥环中。如果启用了加密,它还会执行重命名当前日志文件的日志文件轮换操作,并开始使用密码加密的新日志文件。文件重命名是根据基于大小的日志文件自动轮换的通常规则进行的;请参阅 手动审核日志文件轮换(MySQL 8.0.31 之前)

    如果 audit_log_password_history_keep_days 系统变量不为零,调用 audit_log_encryption_password_set() 还会导致旧存档审计日志加密密码过期。有关审计日志密码历史的信息,包括密码存档和过期,请参阅该变量的描述。

  • 要获取当前加密密码,请 audit_log_encryption_password_get() 不带参数调用。要通过 ID 获取密码,请传递指定当前密码或存档密码的密钥环 ID 的参数。

    要确定存在哪些审计日志密钥环 ID,请查询 Performance Schema keyring_keys表:

    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 |
    +-----------------------------+

有关审核日志加密功能的其他信息,请参阅审核日志功能

审计日志插件在初始化时,如果发现启用了日志文件加密,则检查keyring是否包含审计日志加密密码。如果没有,插件会自动生成一个随机的初始加密密码并将其存储在密钥环中。要发现此密码,请调用 audit_log_encryption_password_get().

如果同时启用压缩和加密,则压缩发生在加密之前。要手动恢复原始文件,请先解密,然后解压缩。请参阅 手动解压缩和解密审计日志文件

手动解压缩和解密审计日志文件

可以使用标准工具解压缩和解密审计日志文件。这应该只对已关闭(存档)且不再使用的日志文件执行,而不是审计日志插件当前正在写入的日志文件。您可以识别归档日志文件,因为它们已被审计日志插件重命名为在基本名称之后的文件名中包含时间戳。

对于此讨论,假设 audit_log_file设置为 audit.log。在这种情况下,存档的审核日志文件具有下表中显示的名称之一。

启用的功能 归档文件名
无压缩或加密 audit.timestamp.log
压缩 audit.timestamp.log.gz
加密 audit.timestamp.log.pwd_id.enc
压缩、加密 audit.timestamp.log.gz.pwd_id.enc

审核日志文件的命名约定中所述, pwd_id格式为 pwd_timestamp-seq. 因此,归档的加密日志文件的名称实际上包含两个时间戳。第一个表示文件轮换时间,第二个表示创建加密密码的时间。

考虑以下一组归档的加密日志文件名:

audit.20190410T205827.log.20190403T185337-1.enc
audit.20190410T210243.log.20190403T185337-1.enc
audit.20190415T145309.log.20190414T223342-1.enc
audit.20190415T151322.log.20190414T223342-2.enc

每个文件名都有一个唯一的旋转时间戳。相比之下,密码时间戳不是唯一的:

  • 前两个文件具有相同的密码 ID 和序列号 ( 20190403T185337-1)。它们具有相同的加密密码。

  • 后两个文件具有相同的密码 ID ( 20190414T223342) 但不同的序列号 ( 1, 2)。这些文件具有不同的加密密码。

要手动解压缩压缩日志文件,请使用 gunzipgzip -d或等效命令。例如:

gunzip -c audit.timestamp.log.gz > audit.timestamp.log

要手动解密加密的日志文件,请使用 openssl命令。例如:

openssl enc -d -aes-256-cbc -pass pass:password -md sha256
    -in audit.timestamp.log.pwd_id.enc
    -out audit.timestamp.log

要执行该命令,您必须获得 password加密密码。为此,请使用 audit_log_encryption_password_get(). 例如,如果审计日志文件名为 audit.20190415T151322.log.20190414T223342-2.enc,则密码 ID 为20190414T223342-2,密钥环 ID 为 audit-log-20190414T223342-2。像这样检索密钥环密码:

SELECT audit_log_encryption_password_get('audit-log-20190414T223342-2');

如果为审计日志启用了压缩和加密,则压缩发生在加密之前。在这种情况下,文件名添加了.gz和 后缀,对应于这些操作发生的顺序。要手动恢复原始文件,请执行相反的操作。即先解密文件,再解压: .pwd_id.enc

openssl enc -d -aes-256-cbc -pass pass:password -md sha256
    -in audit.timestamp.log.gz.pwd_id.enc
    -out audit.timestamp.log.gz
gunzip -c audit.timestamp.log.gz > audit.timestamp.log
MySQL 8.0.17 之前的审计日志文件加密

本节介绍 MySQL 8.0.17 之前和之后审计日志文件加密功能的差异,这是在实施密码历史记录(包括密码存档和过期)时。它还指示审计日​​志插件如何处理从低于 8.0.17 的版本升级到 MySQL 8.0.17 或更高版本。

特征 MySQL 8.0.17 之前 从 MySQL 8.0.17 开始
密码数量 仅限单一密码 允许多个密码
加密的日志文件名 .enc后缀 .pwd_id.enc后缀
密码密钥环 ID audit_log audit_log-pwd_id
密码历史 是的

MySQL 8.0.17之前没有密码历史记录,设置新密码会使旧密码无法访问,导致MySQL Enterprise Audit无法读取旧密码加密的日志文件。如果您预计需要手动解密这些文件,则必须保留以前密码的记录。

如果在从较低版本升级到 MySQL 8.0.17 或更高版本时启用了审计日志文件加密,审计日志插件将执行以下升级操作:

  • 在插件初始化期间,插件会检查密钥环 ID 为 audit_log. 如果找到,插件会使用密钥环 ID 格式复制密码,并将其用作当前的加密密码。(有关 语法的详细信息,请参阅审计日志文件的命名约定。) audit_log-pwd_idpwd_id

  • 现有的加密日志文件的后缀为 .enc. 该插件不会将这些重命名为后缀为 ,但只要 ID 为 的密钥 保留在密钥环中,就可以读取它们。 .pwd_id.encaudit_log

  • 发生密码清理时,如果插件使密钥环 ID 格式的任何密码过期,它也会使密钥环 ID 为 的密码过期 (如果存在)。(此时,插件无法读取后缀为 而非 的加密日志文件 ,因此假设您不再需要它们。) audit_log-pwd_idaudit_log.enc.pwd_id.enc

审计日志文件的空间管理

审核日志文件有可能变得非常大并占用大量磁盘空间。如果您正在收集 MySQL 8.0.30 提供的可选查询时间和大小统计信息,这会增加空间要求。查询统计信息仅支持 JSON 格式。

要管理使用的空间,请使用以下方法:

  • 日志文件轮换。这涉及通过重命名来旋转当前日志文件,然后使用原始名称打开一个新的当前日志文件。旋转可以手动执行,或配置为自动发生。

  • 如果启用了自动轮换,则对轮换的 JSON 格式日志文件进行修剪。可以根据日志文件年龄(从 MySQL 8.0.24 开始)或合并的日志文件大小(从 MySQL 8.0.26 开始)执行修剪。

要配置审计日志文件空间管理,请使用以下系统变量:

笔记

对于 JSON 格式的日志文件,当 audit_log_format_unix_timestamp 系统变量的值在运行时发生更改时,也会发生轮换。但是,这不会出于空间管理目的而发生,而是为了使对于给定的 JSON 格式日志文件,文件中的所有记录都包含或不包含该time 字段。

笔记

轮换(重命名)的日志文件不会自动删除。例如,对于基于大小的日志文件轮换,重命名的日志文件具有唯一的名称并无限期地累积。它们不会旋转到名称序列的末尾。为避免过度使用空间:

  • 从 MySQL 8.0.24 开始(对于 JSON 格式的日志文件):启用日志文件修剪,如 审计日志文件修剪中所述。

  • 否则(对于非 JSON 文件,或 MySQL 8.0.24 之前的所有日志格式):定期删除旧文件,必要时先备份它们。如果备份的日志文件被加密,也请将相应的加密密码备份到安全的地方,以备日后需要解密文件时使用。

以下部分更详细地描述了日志文件轮换和修剪。

手动审计日志文件轮转(MySQL 8.0.31 之前)
笔记

从 MySQL 8.0.31 开始, audit_log_flush审计日志文件轮换的变量和方法被弃用;期望在未来版本的 MySQL 中删除支持。

如果audit_log_rotate_on_size 为 0(默认值),除非手动执行,否则不会发生日志轮换。在这种情况下,审核日志插件会在 audit_log_flush值从禁用更改为启用时关闭并重新打开日志文件。日志文件重命名必须在服务器外部完成。假设日志文件名为 , audit.log并且您想要维护三个最近的日志文件,通过 循环显示 audit.log.1名称 audit.log.3。在 Unix 上,像这样手动执行旋转:

  1. 从命令行重命名当前日志文件:

    mv audit.log.2 audit.log.3
    mv audit.log.1 audit.log.2
    mv audit.log audit.log.1

    此策略会覆盖当前 audit.log.3内容,限制归档日志文件的数量和它们使用的空间。

  2. 此时,插件仍在写入当前日志文件,该文件已重命名为 audit.log.1. 连接到服务器并刷新日志文件,以便插件关闭它并重新打开一个新audit.log文件:

    SET GLOBAL audit_log_flush = ON;

    audit_log_flush特殊之处在于它的值仍然存在OFF ,因此您无需在再次启用它以执行另一次刷新之前明确禁用它。

笔记

如果启用了压缩或加密,则日志文件名包括表示已启用功能的后缀,以及密码 ID(如果启用了加密)。如果文件名包含密码 ID,请务必在您手动重命名的任何文件的名称中保留该 ID,以便可以确定用于解密操作的密码。

笔记

对于 JSON 格式的日志记录,手动重命名审计日志文件会使它们无法用于日志读取功能,因为审计日志插件无法再确定它们是日志文件序列的一部分(请参阅 第 6.4.5.6 节,“读取审计日志文件”)。考虑设置 audit_log_rotate_on_size 大于 0 以改为使用基于大小的旋转。

手动审核日志文件轮换(来自 MySQL 8.0.31)

如果audit_log_rotate_on_size 为 0(默认值),除非手动执行,否则不会发生日志轮换。

要手动轮换审计日志文件,请运行SELECT audit_log_rotate();以重命名当前审计日志文件并打开一个新的审计日志文件。文件根据 审计日志文件的命名约定中描述的约定重命名。

使用该功能AUDIT_ADMIN需要权限 audit_log_rotate()

管理归档日志文件(已重命名的文件)的数量和它们使用的空间是一项手动任务,涉及从文件系统中删除不再需要的归档审计日志文件。

使用函数重命名的审计日志文件的内容 audit_log_rotate()可以按 audit_log_read()函数读取。

自动审核日志文件轮换

如果audit_log_rotate_on_size 大于 0, audit_log_flush则设置无效。相反,每当对当前日志文件的写入导致其大小超过该 audit_log_rotate_on_size 值时,审计日志插件会自动重命名当前日志文件并使用原始名称打开一个新的当前日志文件。

在这些条件下也会发生基于大小的自动旋转:

该插件通过在其基本名称后插入时间戳来重命名原始文件。例如,如果文件名为 audit.log,插件会将其重命名为诸如audit.20210115T140633.log. 时间戳是 格式的 UTC 值。对于 XML 日志记录,时间戳表示轮换时间。对于 JSON 日志记录,时间戳是写入文件的最后一个事件的时间戳。 YYYYMMDDThhmmss

如果日志文件被加密,原始文件名已经包含一个时间戳,指示加密密码创建时间(参见审计日志文件的命名约定)。在这种情况下,旋转后的文件名包含两个时间戳。例如,名为 的加密日志文件被重命名 audit.log.20210110T130749-1.enc为诸如 audit.20210115T140633.log.20210110T130749-1.enc.

审计日志文件修剪

如果启用了自动日志文件轮换,审计日志插件支持修剪轮换的 JSON 格式审计日志文件。要使用此功能:

JSON 格式日志文件的修剪(如果启用)如下所示:

对于基于组合旋转日志文件大小的修剪,如果组合大小大于指定的限制 audit_log_max_size,审计日志插件将删除最旧的文件,直到它们的组合大小不超过限制。

对于基于旋转日志文件年龄的剪枝,剪枝点是当前时间减去 audit_log_prune_seconds. 在轮换的 JSON 格式日志文件中,每个文件名的时间戳部分表示写入文件的最后一个事件的时间戳。审计日志插件使用文件名时间戳来确定哪些文件只包含早于修剪点的事件,并删除它们。

为审计日志编写策略

审计日志插件可以使用多种日志写入策略中的任何一种。无论策略如何,日志记录都是在尽力而为的基础上进行的,不保证一致性。

要指定写入策略,请 audit_log_strategy在服务器启动时设置系统变量。默认情况下,策略值为 ASYNCHRONOUS,插件异步记录到缓冲区,等待缓冲区是否已满。可以告诉插件不要等待 ( PERFORMANCE) 或同步记录,使用文件系统缓存 ( ) 或在每次写入请求后SEMISYNCHRONOUS通过调用强制输出 ( )。 sync()SYNCHRONOUS

对于异步写入策略, audit_log_buffer_size系统变量是以字节为单位的缓冲区大小。在服务器启动时设置此变量以更改缓冲区大小。该插件使用单个缓冲区,它在初始化时分配并在终止时删除。该插件不会为非异步写入策略分配此缓冲区。

异步日志记录策略具有以下特点:

  • 对服务器性能和可伸缩性的影响最小。

  • 在尽可能短的时间内阻塞生成审计事件的线程;也就是说,分配缓冲区的时间加上将事件复制到缓冲区的时间。

  • 输出进入缓冲区。一个单独的线程处理从缓冲区到日志文件的写入。

使用异步日志记录时,如果在写入文件期间出现问题或插件未完全关闭(例如,在服务器主机意外退出的情况下),则日志文件的完整性可能会受到损害。为了降低这种风险,设置 audit_log_strategy为使用同步日志记录。

策略的一个缺点PERFORMANCE是它会在缓冲区已满时丢弃事件。对于负载很重的服务器,审计日志可能缺少事件。