MySQL8-中文参考-十四-

MySQL8 中文参考(十四)

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

原文:dev.mysql.com/doc/refman/8.0/en/keyring-hashicorp-plugin.html

8.4.4.10 使用 HashiCorp Vault 密钥环插件

注意

keyring_hashicorp 插件是包含在 MySQL Enterprise Edition 中的扩展,这是一款商业产品。要了解更多关于商业产品的信息,请参阅 www.mysql.com/products/

keyring_hashicorp 密钥环插件与 HashiCorp Vault 进行后端存储通信。该插件支持 HashiCorp Vault AppRole 认证。没有密钥信息永久存储在 MySQL 服务器本地存储中(可使用可选的内存中密钥缓存作为中间存储)。随机密钥生成在 MySQL 服务器端执行,然后将密钥存储到 Hashicorp Vault。

keyring_hashicorp 插件支持组成标准 MySQL 密钥环服务接口的函数。这些函数执行的密钥环操作可在两个级别访问:

  • SQL 接口:在 SQL 语句中,调用 第 8.4.4.15 节,“通用密钥环密钥管理函数” 中描述的函数。

  • C 接口:在 C 语言代码中,调用 第 7.6.9.2 节,“密钥环服务” 中描述的密钥环服务函数。

示例(使用 SQL 接口):

SELECT keyring_key_generate('MyKey', 'AES', 32);
SELECT keyring_key_remove('MyKey');

有关 keyring_hashicorp 允许的密钥值特性的信息,请参阅 第 8.4.4.13 节,“支持的密钥环密钥类型和长度”。

要安装 keyring_hashicorp,请使用 第 8.4.4.3 节,“密钥环插件安装” 中找到的一般说明,以及此处找到的特定于 keyring_hashicorp 的配置信息。插件特定配置包括准备连接到 HashiCorp Vault 所需的证书和密钥文件,以及配置 HashiCorp Vault 本身。以下部分提供了必要的说明。

  • 证书和密钥准备

  • HashiCorp Vault 设置

  • keyring_hashicorp 配置

证书和密钥准备

keyring_hashicorp 插件需要与 HashiCorp Vault 服务器建立安全连接,使用 HTTPS 协议。典型设置包括一组证书和密钥文件:

  • company.crt: 组织拥有的自定义 CA 证书。此文件同时被 HashiCorp Vault 服务器和 keyring_hashicorp 插件使用。

  • vault.key:HashiCorp Vault 服务器实例的私钥。此文件由 HashiCorp Vault 服务器使用。

  • vault.crt:HashiCorp Vault 服务器实例的证书。此文件必须由组织 CA 证书签名。

以下说明描述了如何使用 OpenSSL 创建证书和密钥文件。(如果您已经有这些文件,请继续进行 HashiCorp Vault 设置。)所示的说明适用于 Linux 平台,可能需要调整以适用于其他平台。

重要提示

根据这些说明生成的证书是自签名的,可能不太安全。在使用这些文件获得经验后,考虑从注册的证书颁发机构获取证书/密钥材料。

  1. 准备公司和 HashiCorp Vault 服务器密钥。

    使用以下命令生成密钥文件:

    openssl genrsa -aes256 -out company.key 4096
    openssl genrsa -aes256 -out vault.key 2048
    

    这些命令生成包含公司私钥(company.key)和 Vault 服务器私钥(vault.key)的文件。这些密钥分别是随机生成的 4,096 位和 2,048 位的 RSA 密钥。

    每个命令都会提示输入密码。为了测试目的,密码不是必需的。要禁用密码,请省略-aes256参数。

    密钥文件包含敏感信息,应存储在安全位置。密码(也是敏感信息)稍后会被要求,因此请记下并将其存储在安全位置。

    (可选)使用以下命令检查密钥文件内容和有效性:

    openssl rsa -in company.key -check
    openssl rsa -in vault.key -check
    
  2. 创建公司 CA 证书。

    使用以下命令创建一个有效期为 365 天的名为company.crt的公司 CA 证书文件(在一行上输入命令):

    openssl req -x509 -new -nodes -key company.key
      -sha256 -days 365 -out company.crt
    

    如果在生成密钥时使用了-aes256参数进行密钥加密,则在创建 CA 证书时会提示输入公司密钥密码。还会提示输入有关证书持有者(即您或您的公司)的信息,如下所示:

    Country Name (2 letter code) [AU]:
    State or Province Name (full name) [Some-State]:
    Locality Name (eg, city) []:
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:
    Organizational Unit Name (eg, section) []:
    Common Name (e.g. server FQDN or YOUR name) []:
    Email Address []:
    

    用适当的值回答提示。

  3. 创建证书签名请求。

    要为新创建的服务器密钥准备一个 HashiCorp Vault 服务器证书,必须创建一个名为request.conf的配置文件,其中包含以下行。如果 HashiCorp Vault 服务器不在本地主机上运行,请替换适当的 CN 和 IP 值,并进行任何其他必要的更改。

    [req]
    distinguished_name = vault
    x509_entensions = v3_req
    prompt = no
    
    [vault]
    C = US
    ST = CA
    L = RWC
    O = Company
    CN = 127.0.0.1
    
    [v3_req]
    subjectAltName = @alternatives
    authorityKeyIdentifier = keyid,issuer
    basicConstraints = CA:TRUE
    
    [alternatives]
    IP = 127.0.0.1
    

    使用以下命令创建签名请求:

    openssl req -new -key vault.key -config request.conf -out request.csr
    

    输出文件(request.csr)是一个中间文件,用作创建服务器证书的输入。

  4. 创建 HashiCorp Vault 服务器证书。

    使用公司证书(company.crt)对 HashiCorp Vault 服务器密钥(vault.key)和 CSR(request.csr)中的组合信息进行签名,以创建 HashiCorp Vault 服务器证书(vault.crt)。使用以下命令执行此操作(在一行上输入命令):

    openssl x509 -req -in request.csr
      -CA company.crt -CAkey company.key -CAcreateserial
      -out vault.crt -days 365 -sha256
    

    要使 vault.crt 服务器证书有效,将 company.crt 公司证书的内容附加到其中。这是必需的,以便公司证书在请求中与服务器证书一起传递。

    cat company.crt >> vault.crt
    

    如果显示 vault.crt 文件的内容,它应该如下所示:

    -----BEGIN CERTIFICATE-----
    ... *content of HashiCorp Vault server certificate* ...
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    ... *content of company certificate* ...
    -----END CERTIFICATE-----
    
HashiCorp Vault 设置

以下说明描述了如何创建一个 HashiCorp Vault 设置,以便测试 keyring_hashicorp 插件。

重要

测试设置类似于生产设置,但是 HashiCorp Vault 的生产使用涉及额外的安全考虑,例如使用非自签名证书和将公司证书存储在系统信任存储中。您必须实施任何额外的安全步骤以满足您的运营需求。

这些说明假定在 证书和密钥准备 中创建了证书和密钥文件。如果您没有这些文件,请参阅该部分。

  1. 获取 HashiCorp Vault 二进制文件。

    www.vaultproject.io/downloads.html 下载适合您平台的 HashiCorp Vault 二进制文件。

    解压缩存档内容以生成可执行的 vault 命令,该命令用于执行 HashiCorp Vault 操作。如有必要,将安装该命令的目录添加到系统路径中。

    (可选)HashiCorp Vault 支持自动补全选项,使其更易于使用。有关更多信息,请参阅 learn.hashicorp.com/vault/getting-started/install#command-completion

  2. 创建 HashiCorp Vault 服务器配置文件。

    准备一个名为 config.hcl 的配置文件,内容如下。对于 tls_cert_filetls_key_filepath 值,请替换适合您系统的路径名。

    listener "tcp" {
      address="127.0.0.1:8200"
      tls_cert_file="/home/username/certificates/vault.crt"
      tls_key_file="/home/username/certificates/vault.key"
    }
    
    storage "file" {
      path = "/home/username/vaultstorage/storage"
    }
    
    ui = true
    
  3. 启动 HashiCorp Vault 服务器。

    要启动 Vault 服务器,请使用以下命令,其中 -config 选项指定刚创建的配置文件的路径:

    vault server -config=config.hcl
    

    在此步骤中,您可能会被要求为存储在 vault.key 文件中的 Vault 服务器私钥输入密码。

    服务器应该启动,并在控制台上显示一些信息(IP、端口等)。

    为了能够输入剩余的命令,请将 vault server 命令放在后台运行或在继续之前打开另一个终端。

  4. 初始化 HashiCorp Vault 服务器。

    注意

    在启动 Vault 第一次时,执行本步骤中描述的操作以获取解封密钥和根令牌。后续 Vault 实例重新启动仅需要使用解封密钥进行解封。

    发出以下命令(假设 Bourne shell 语法):

    export VAULT_SKIP_VERIFY=1
    vault operator init -n 1 -t 1
    

    第一个命令使vault命令暂时忽略尚未添加到系统信任存储库的公司证书的事实。它弥补了我们的自签名 CA 未添加到该存储库的事实。(对于生产使用,应添加这样的证书。)

    第二个命令创建一个具有单个解封密钥的要求,要求一个解封密钥存在以解封。 (对于生产使用,一个实例将具有多个解封密钥,最多需要输入相同数量的密钥来解封。解封密钥应交付给公司内的密钥保管员。使用单个密钥可能被视为安全问题,因为这允许单个密钥保管员解封保险库。)

    Vault 应该回复有关解封密钥和 root 令牌的信息,以及一些附加文本(实际的解封密钥和 root 令牌值与此处显示的值不同):

    ...
    Unseal Key 1: I2xwcFQc892O0Nt2pBiRNlnkHzTUrWS+JybL39BjcOE=
    Initial Root Token: s.vTvXeo3tPEYehfcd9WH7oUKz
    ...
    

    将解封密钥和 root 令牌存储在安全位置。

  5. 解封 HashiCorp Vault 服务器。

    使用此命令解封 Vault 服务器:

    vault operator unseal
    

    在提示输入解封密钥时,使用在 Vault 初始化期间先前获得的密钥。

    Vault 应该生成指示设置完成并解封保险库的输出。

  6. 登录到 HashiCorp Vault 服务器并验证其状态。

    准备登录为 root 所需的环境变量:

    vault login s.vTvXeo3tPEYehfcd9WH7oUKz
    

    在该命令中的令牌值中,用之前在 Vault 初始化期间获得的 root 令牌的内容替换。

    验证 Vault 服务器状态:

    vault status
    

    输出应包含以下行(以及其他内容):

    ...
    Initialized     true
    Sealed          false
    ...
    
  7. 设置 HashiCorp Vault 身份验证和存储。

    注意

    在运行 Vault 实例时,描述的操作仅在第一次运行时需要。之后不需要重复。

    启用 AppRole 身份验证方法并验证其是否在身份验证方法列表中:

    vault auth enable approle
    vault auth list
    

    启用 Vault KeyValue 存储引擎:

    vault secrets enable -version=1 kv
    

    为与keyring_hashicorp插件一起使用设置一个角色(在一行上输入命令):

    vault write auth/approle/role/mysql token_num_uses=0
      token_ttl=20m token_max_ttl=30m secret_id_num_uses=0
    
  8. 添加一个 AppRole 安全策略。

    注意

    在运行 Vault 实例时,描述的操作仅在第一次运行时需要。之后不需要重复。

    准备一个策略,以允许先前创建的角色访问适当的机密。创建一个名为mysql.hcl的新文件,内容如下:

    path "kv/mysql/*" {
      capabilities = ["create", "read", "update", "delete", "list"]
    }
    

    注意

    在这个示例中,kv/mysql/可能需要根据您的本地安装政策和安全要求进行调整。如果需要,无论这些说明中的kv/mysql/出现在哪里,都要进行相同的调整。

    将策略文件导入 Vault 服务器以创建名为mysql-policy的策略,然后将策略分配给新角色:

    vault policy write mysql-policy mysql.hcl
    vault write auth/approle/role/mysql policies=mysql-policy
    

    获取新创建角色的 ID 并将其存储在安全位置:

    vault read auth/approle/role/mysql/role-id
    

    为角色生成一个秘密 ID,并将其存储在安全位置:

    vault write -f auth/approle/role/mysql/secret-id
    

    生成这些 AppRole 角色 ID 和密钥 ID 凭证后,它们预计会无限期保持有效。不需要再次生成它们,keyring_hashicorp插件可以配置它们以供持续使用。有关 AuthRole 身份验证的更多信息,请访问www.vaultproject.io/docs/auth/approle.html

keyring_hashicorp 配置

插件库文件包含keyring_hashicorp插件和一个可加载的函数,keyring_hashicorp_update_config()。当插件初始化和终止时,它会自动加载和卸载该函数。无需手动加载和卸载该函数。

keyring_hashicorp插件支持以下表中显示的配置参数。要指定这些参数,请为相应的系统变量赋值。

配置参数 系统变量 必须
HashiCorp 服务器 URL keyring_hashicorp_server_url
AppRole 角色 ID keyring_hashicorp_role_id
AppRole 密钥 ID keyring_hashicorp_secret_id
存储路径 keyring_hashicorp_store_path
授权路径 keyring_hashicorp_auth_path
CA 证书文件路径 keyring_hashicorp_ca_path
缓存控制 keyring_hashicorp_caching

为了在服务器启动过程中可用,必须使用--early-plugin-load选项加载keyring_hashicorp。如前表所示,还必须设置几个与插件相关的系统变量。例如,在服务器的my.cnf文件中使用以下行,根据需要调整.so后缀和文件位置:

[mysqld]
early-plugin-load=keyring_hashicorp.so
keyring_hashicorp_role_id='ee3b495c-d0c9-11e9-8881-8444c71c32aa'
keyring_hashicorp_secret_id='0512af29-d0ca-11e9-95ee-0010e00dd718'
keyring_hashicorp_store_path='/v1/kv/mysql'
keyring_hashicorp_auth_path='/v1/auth/approle/login'

注意

根据HashiCorp 文档,所有 API 路由都以协议版本为前缀(在前面的示例中可以看到为/v1/,在keyring_hashicorp_store_pathkeyring_hashicorp_auth_path的值中)。如果 HashiCorp 开发新的协议版本,可能需要在配置中将/v1/更改为其他内容。

MySQL 服务器使用 AppRole 身份验证对 HashiCorp Vault 进行身份验证。成功的身份验证需要向 Vault 提供两个秘密,一个角色 ID 和一个秘密 ID,类似于用户名和密码的概念。要指定这两个 ID,将它们的值分配给keyring_hashicorp_role_idkeyring_hashicorp_secret_id系统变量。设置过程还会导致存储路径为/v1/kv/mysql,这个值应分配给keyring_hashicorp_commit_store_path

在插件初始化时,keyring_hashicorp尝试使用配置数值连接到 HashiCorp Vault 服务器。如果连接成功,插件会将这些数值存储在相应的系统变量中,这些变量的名称中包含_commit_。例如,连接成功后,插件会将keyring_hashicorp_role_idkeyring_hashicorp_store_path的数值存储在keyring_hashicorp_commit_role_idkeyring_hashicorp_commit_store_path中。

可以通过keyring_hashicorp_update_config()函数在运行时重新配置:

  1. 使用SET语句将所需的新值分配给前表中显示的配置系统变量。这些分配本身对正在进行的插件操作没有影响。

  2. 调用keyring_hashicorp_update_config()函数会导致插件重新配置并使用新的变量值重新连接到 HashiCorp Vault 服务器。

  3. 如果连接成功,插件会将更新后的配置数值存储在相应的系统变量中,这些变量的名称中包含_commit_

例如,如果已将 HashiCorp Vault 重新配置为监听端口 8201 而不是默认的 8200,则像这样重新配置keyring_hashicorp

mysql> SET GLOBAL keyring_hashicorp_server_url = 'https://127.0.0.1:8201';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT keyring_hashicorp_update_config();
+--------------------------------------+
| keyring_hashicorp_update_config()    |
+--------------------------------------+
| Configuration update was successful. |
+--------------------------------------+
1 row in set (0.03 sec)

如果插件在初始化或重新配置期间无法连接到 HashiCorp Vault,并且没有现有连接,则对于字符串值变量,_commit_系统变量将设置为'Not committed',对于布尔值变量,将设置为OFF。如果插件无法连接但存在现有连接,则该连接保持活动状态,并且_commit_变量反映用于它的值。

注意

如果在服务器启动时未设置必需的系统变量,或者发生其他插件初始化错误,初始化将失败。在这种情况下,您可以使用运行时重新配置过程来初始化插件,而无需重新启动服务器。

有关keyring_hashicorp插件特定系统变量和功能的其他信息,请参见 Section 8.4.4.19, “Keyring System Variables”和 Section 8.4.4.16, “Plugin-Specific Keyring Key-Management Functions”。

原文:dev.mysql.com/doc/refman/8.0/en/keyring-oci-component.html

8.4.4.11 使用 Oracle Cloud Infrastructure Vault 密钥环组件

注意

Oracle Cloud Infrastructure Vault 密钥环组件包含在 MySQL Enterprise Edition 中,这是一个商业产品。要了解更多关于商业产品的信息,请参见 www.mysql.com/products/

component_keyring_oci 是与 Oracle Cloud Infrastructure Vault 进行后端存储通信的组件基础设施的一部分。没有任何密钥信息永久存储在 MySQL 服务器本地存储中。所有密钥都存储在 Oracle Cloud Infrastructure Vault 中,使得这个组件非常适合 Oracle Cloud Infrastructure MySQL 客户管理他们的 MySQL Enterprise Edition 密钥。

在 MySQL 8.0.24 中,MySQL Keyring 开始从插件过渡到使用组件基础设施。MySQL 8.0.31 中引入的 component_keyring_oci 是这一努力的延续。有关更多信息,请参见 密钥环组件与密钥环插件。

注意

一次只能启用一个密钥环组件或插件。启用多个密钥环组件或插件是不受支持的,结果可能不如预期。

要使用 component_keyring_oci 进行密钥库管理,您必须:

  1. 编写一个清单,告诉服务器加载 component_keyring_oci,如 Section 8.4.4.2, “密钥环组件安装” 中所述。

  2. 编写一个 component_keyring_oci 的配置文件,如此处所述。

在编写清单和配置文件之后,只要您指定相同的配置选项集来初始化密钥环组件,您就应该能够访问使用 keyring_oci 插件创建的密钥。component_keyring_oci 的内置向后兼容性简化了从密钥环插件迁移到组件的过程。

  • 配置注意事项

  • 验证组件安装

  • Vault 密钥环组件使用

配置注意事项

当初始化时,component_keyring_oci 会读取全局配置文件,或者全局配置文件与本地配置文件配对:

  • 该组件尝试从安装组件库文件的目录(即服务器插件目录)读取其全局配置文件。

  • 如果全局配置文件指示使用本地配置文件,则组件将尝试从数据目录读取其本地配置文件。

  • 尽管全局和本地配置文件位于不同的目录中,但文件名在两个位置都是 component_keyring_oci.cnf

  • 如果不存在配置文件,则会出现错误。没有有效配置时,component_keyring_oci 无法初始化。

本地配置文件允许设置多个服务器实例以使用 component_keyring_oci,因此每个服务器实例的组件配置特定于给定的数据目录实例。这使得可以为每个实例使用不同的 Oracle Cloud Infrastructure 保险库来使用相同的密钥环组件。

假设您熟悉 Oracle Cloud Infrastructure 概念,但在设置资源以供 component_keyring_oci 使用时,以下文档可能会有所帮助:

component_keyring_oci 配置文件具有以下属性:

  • 配置文件必须采用有效的 JSON 格式。

  • 配置文件允许这些配置项:

    • "read_local_config":此项仅允许在全局配置文件中。如果该项不存在,则组件仅使用全局配置文件。如果该项存在,则其值为 truefalse,表示组件是否应从本地配置文件中读取配置信息。

      如果全局配置文件中同时存在 "read_local_config" 项和其他项,则组件首先检查 "read_local_config" 项的值:

      • 如果值为 false,组件将处理全局配置文件中的其他项,并忽略本地配置文件。

      • 如果值为 true,组件将忽略全局配置文件中的其他项,并尝试读取本地配置文件。

    • “user”component_keyring_oci 用于连接的 Oracle Cloud Infrastructure 用户的 OCID。在使用 component_keyring_oci 之前,用户帐户必须存在并被授予访问权限以使用配置的 Oracle Cloud Infrastructure 租户、区段和保险库资源。要从控制台获取用户 OCID,请使用 所需密钥和 OCID 中的说明。

      此值为必填项。

    • “tenancy”: Oracle Cloud Infrastructure 租户的 OCID,component_keyring_oci用作 MySQL 区域的位置。在使用component_keyring_oci之前,如果租户不存在,则必须创建一个租户。要从控制台获取租户 OCID,请使用必需的密钥和 OCID中的说明。

      此值为必填项。

    • “compartment”: 租户区域的 OCID,component_keyring_oci用作 MySQL 密钥的位置。在使用component_keyring_oci之前,如果 MySQL 区域或子区域不存在,则必须创建一个。此区域不应包含保险库密钥或保险库机密。它不应被除 MySQL Keyring 之外的系统使用。有关管理区域和获取 OCID 的信息,请参阅管理区域

      此值为必填项。

    • “virtual_vault”: Oracle Cloud Infrastructure Vault 的 OCID,component_keyring_oci用于加密操作。在使用component_keyring_oci之前,如果 MySQL 区域不存在,则必须在 MySQL 区域中创建一个新的保险库。(或者,您可以重用位于 MySQL 区域的父区域中的现有保险库。)区域用户只能看到并使用其各自区域中的密钥。有关创建保险库和获取保险库 OCID 的信息,请参阅管理保险库

      此值为必填项。

    • “encryption_endpoint”: Oracle Cloud Infrastructure 加密服务器的端点,component_keyring_oci用于为新密钥生成加密或编码信息(密文)。加密端点是与保险库相关的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取端点 OCID,请查看您的 keyring_oci 保险库的配置详细信息,使用管理保险库中的说明。

      此值为必填项。

    • "management_endpoint": Oracle Cloud Infrastructure 密钥管理服务器的端点,component_keyring_oci用于列出现有密钥的端点。密钥管理端点是与保险库相关的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取端点 OCID,请查看您的 keyring_oci 保险库的配置详细信息,使用管理保险库中的说明。

      此值为必填项。

    • “vaults_endpoint”: Oracle Cloud Infrastructure 保险库服务器的终端点,component_keyring_oci用于获取秘密的值。保险库终端点是特定于保险库的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取终端点 OCID,请查看您的 keyring_oci 保险库的配置详细信息,使用管理保险库中的说明。

      此值为必填项。

    • “secrets_endpoint”: Oracle Cloud Infrastructure 秘密服务器的终端点,component_keyring_oci用于列出、创建和撤销秘密。秘密终端点是特定于保险库的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取终端点 OCID,请查看您的 keyring_oci 保险库的配置详细信息,使用管理保险库中的说明。

      此值为必填项。

    • “master_key”: Oracle Cloud Infrastructure 主加密密钥的 OCID,component_keyring_oci用于加密秘密。在使用component_keyring_oci之前,如果不存在,您必须为 Oracle Cloud Infrastructure 区段创建一个加密密钥。为生成的密钥提供一个特定于 MySQL 的名称,并且不要将其用于其他目的。有关密钥创建的信息,请参阅管理密钥

      此值为必填项。

    • “key_file”: 包含 RSA 私钥的文件路径名,component_keyring_oci用于 Oracle Cloud Infrastructure 身份验证。您还必须使用控制台上传相应的 RSA 公钥。控制台显示密钥指纹值,您可以使用它来设置"key_fingerprint"值。有关生成和上传 API 密钥的信息,请参阅必需的密钥和 OCIDs

      此值为必填项。

    • “key_fingerprint”: RSA 私钥的指纹,component_keyring_oci用于 Oracle Cloud Infrastructure 身份验证。在创建 API 密钥时获取密钥指纹,请执行此命令:

      openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c
      

      或者,从控制台获取指纹,当您上传 RSA 公钥时,控制台会自动显示指纹。有关获取密钥指纹的信息,请参阅必需的密钥和 OCID

      此值为必填项。

    • “ca_certificate”component_keyring_oci组件用于 Oracle Cloud Infrastructure 证书验证的 CA 证书捆绑文件的路径名。该文件包含一个或多个用于对等验证的证书。如果未指定文件,则使用系统上安装的默认 CA 捆绑。如果值设置为disabled(区分大小写),component_keyring_oci不执行证书验证。

鉴于上述配置文件属性,要配置component_keyring_oci,请在安装component_keyring_oci库文件的目录中创建一个名为component_keyring_oci.cnf的全局配置文件,并可选地在数据目录中创建一个名为component_keyring_oci.cnf的本地配置文件。

验证组件安装

执行任何特定于组件的配置后,启动服务器。通过检查性能模式keyring_component_status表来验证组件安装:

mysql> SELECT * FROM performance_schema.keyring_component_status;
+---------------------+--------------------------------------------------------------------+
| STATUS_KEY          | STATUS_VALUE                                                       |
+---------------------+--------------------------------------------------------------------+
| Component_name      | component_keyring_oci                                              |
| Author              | Oracle Corporation                                                 |
| License             | PROPRIETARY                                                        |
| Implementation_name | component_keyring_oci                                              |
| Version             | 1.0                                                                |
| Component_status    | Active                                                             |
| user                | ocid1.user.oc1..aaaaaaaasqly<...>                                  |
| tenancy             | ocid1.tenancy.oc1..aaaaaaaai<...>                                  |
| compartment         | ocid1.compartment.oc1..aaaaaaaah2swh<...>                          |
| virtual_vault       | ocid1.vault.oc1.iad.bbo5xyzkaaeuk.abuwcljtmvxp4r<...>              |
| master_key          | ocid1.key.oc1.iad.bbo5xyzkaaeuk.abuwcljrbsrewgap<...>              |
| encryption_endpoint | bbo5xyzkaaeuk-crypto.kms.us-<...>                                  |
| management_endpoint | bbo5xyzkaaeuk-management.kms.us-<...>                              |
| vaults_endpoint     | vaults.us-<...>                                                    |
| secrets_endpoint    | secrets.vaults.us-<...>                                            |
| key_file            | ~/.oci/oci_api_key.pem                                             |
| key_fingerprint     | ca:7c:e1:fa:86:b6:40:af:39:d6<...>                                 |
| ca_certificate      | disabled                                                           |
+---------------------+--------------------------------------------------------------------+

Component_status值为Active表示组件初始化成功。

如果组件无法加载,服务器启动将失败。检查服务器错误日志以获取诊断消息。如果组件加载但由于配置问题而无法初始化,则服务器启动,但Component_status值为Disabled。检查服务器错误日志,纠正配置问题,并使用ALTER INSTANCE RELOAD KEYRING语句重新加载配置。

可以查询 MySQL 服务器以获取现有密钥列表。要查看存在哪些密钥,请检查性能模式keyring_keys表。

mysql> SELECT * FROM performance_schema.keyring_keys;
+-----------------------------+--------------+----------------+
| KEY_ID                      | KEY_OWNER    | BACKEND_KEY_ID |
+-----------------------------+--------------+----------------+
| audit_log-20210322T130749-1 |              |                |
| MyKey                       | me@localhost |                |
| YourKey                     | me@localhost |                |
+-----------------------------+--------------+----------------+
保险库密钥环组件用法

component_keyring_oci支持组成标准 MySQL 密钥环服务接口的函数。这些函数执行的密钥环操作可在两个级别访问:

  • SQL 接口:在 SQL 语句中,调用第 8.4.4.15 节,“通用密钥环密钥管理函数”中描述的函数。

  • C 接口:在 C 语言代码中,调用第 7.6.9.2 节,“密钥环服务”中描述的密钥环服务函数。

示例(使用 SQL 接口):

SELECT keyring_key_generate('MyKey', 'AES', 32);
SELECT keyring_key_remove('MyKey');

有关component_keyring_oci允许的密钥值特性的信息,请参见第 8.4.4.13 节,“支持的密钥类型和长度”。

原文:dev.mysql.com/doc/refman/8.0/en/keyring-oci-plugin.html

8.4.4.12 使用 Oracle Cloud 基础设施 Vault Keyring 插件

注意

keyring_oci 插件是包含在 MySQL 企业版中的扩展,这是一个商业产品。要了解更多关于商业产品的信息,请参阅 www.mysql.com/products/

keyring_oci 插件是一个与 Oracle Cloud 基础设施 Vault 通信的 keyring 插件,用于后端存储。没有密钥信息永久存储在 MySQL 服务器本地存储中。所有密钥都存储在 Oracle Cloud 基础设施 Vault 中,使得这个插件非常适合 Oracle Cloud 基础设施 MySQL 客户管理他们的 MySQL 企业版密钥。

截至 MySQL 8.0.31,此插件已被弃用,并可能在将来的 MySQL 版本中被移除。相反,考虑使用 component_keyring_oci 组件来存储 keyring 数据(请参阅 第 8.4.4.11 节,“使用 Oracle Cloud 基础设施 Vault Keyring 组件”)。

keyring_oci 插件支持组成标准 MySQL Keyring 服务接口的函数。这些函数执行的 keyring 操作可在两个级别访问:

  • SQL 接口:在 SQL 语句中,调用 第 8.4.4.15 节,“通用 Keyring 密钥管理函数” 中描述的函数。

  • C 接口:在 C 语言代码中,调用 第 7.6.9.2 节,“Keyring 服务” 中描述的 keyring 服务函数。

示例(使用 SQL 接口):

SELECT keyring_key_generate('MyKey', 'AES', 32);
SELECT keyring_key_remove('MyKey');

有关 keyring_oci 允许的密钥值特性的信息,请参阅 第 8.4.4.13 节,“支持的 Keyring 密钥类型和长度”。

要安装 keyring_oci,请使用 第 8.4.4.3 节,“Keyring 插件安装” 中的通用说明,以及此处找到的特定于 keyring_oci 的配置信息。插件特定的配置涉及设置多个系统变量以指示 Oracle Cloud 基础设施资源的名称或值。

假设您熟悉 Oracle Cloud 基础设施概念,但在设置资源以供 keyring_oci 插件使用时,以下文档可能会有所帮助:

keyring_oci 插件支持下表中显示的配置参数。要指定这些参数,请为相应的系统变量赋值。

配置参数 系统变量 强制
用户 OCID keyring_oci_user
租户 OCID keyring_oci_tenancy
区段 OCID keyring_oci_compartment
保险柜 OCID keyring_oci_virtual_vault
主密钥 OCID keyring_oci_master_key
加密服务器端点 keyring_oci_encryption_endpoint
密钥管理服务器端点 keyring_oci_management_endpoint
保险柜服务器端点 keyring_oci_vaults_endpoint
机密服务器端点 keyring_oci_secrets_endpoint
RSA 私钥文件 keyring_oci_key_file
RSA 私钥指纹 keyring_oci_key_fingerprint
CA 证书捆绑文件 keyring_oci_ca_certificate
配置参数 系统变量 强制

为了在服务器启动过程中可用,必须使用 --early-plugin-load 选项加载 keyring_oci。如前表所示,几个与插件相关的系统变量是强制性的,也必须设置:

  • Oracle Cloud 基础设施广泛使用 Oracle Cloud ID(OCID)来指定资源,而且几个 keyring_oci 参数指定要使用的资源的 OCID 值。因此,在使用 keyring_oci 插件之前,必须满足这些先决条件:

    • 必须存在用于连接到 Oracle Cloud Infrastructure 的用户。如有必要,请创建用户并将用户 OCID 分配给 keyring_oci_user 系统变量。

    • 必须存在要使用的 Oracle Cloud Infrastructure 租户,以及租户内的 MySQL 专用区和专用区内的保险库。如有必要,请创建这些资源,并确保用户已启用以使用它们。将租户、专用区和保险库的 OCID 分配给 keyring_oci_tenancykeyring_oci_compartmentkeyring_oci_virtual_vault 系统变量。

    • 必须存在用于加密的主密钥。如有必要,请创建它并将其 OCID 分配给 keyring_oci_master_key 系统变量。

  • 必须指定几个服务器端点。这些端点是特定于保险库的,Oracle Cloud Infrastructure 在创建保险库时分配它们。从保险库详细信息页面获取它们的值,并将其分配给 keyring_oci_encryption_endpointkeyring_oci_management_endpointkeyring_oci_vaults_endpointkeyring_oci_secrets_endpoint 系统变量。

  • Oracle Cloud Infrastructure API 使用 RSA 公钥/私钥对进行身份验证。要创建此密钥对并获取密钥指纹,请使用 必需的密钥和 OCID 中的说明。将私钥文件名和密钥指纹分配给 keyring_oci_key_filekeyring_oci_key_fingerprint 系统变量。

除了必填的系统变量外,keyring_oci_ca_certificate 可以选择设置以指定用于对等身份验证的证书颁发机构(CA)证书包文件。

重要提示

如果从 Oracle Cloud Infrastructure 控制台复制参数,则复制的值可能包含初始的 https:// 部分。在设置相应的 keyring_oci 系统变量时,请省略该部分。

例如,要加载和配置 keyring_oci,请在服务器的 my.cnf 文件中使用以下行(根据需要调整平台的 .so 后缀和文件位置):

[mysqld]
early-plugin-load=keyring_oci.so
keyring_oci_user=ocid1.user.oc1..*longAlphaNumericString*
keyring_oci_tenancy=ocid1.tenancy.oc1..*longAlphaNumericString*
keyring_oci_compartment=ocid1.compartment.oc1..*longAlphaNumericString*
keyring_oci_virtual_vault=ocid1.vault.oc1.iad.*shortAlphaNumericString*.*longAlphaNumericString*
keyring_oci_master_key=ocid1.key.oc1.iad.*shortAlphaNumericString*.*longAlphaNumericString*
keyring_oci_encryption_endpoint=*shortAlphaNumericString*-crypto.kms.us-ashburn-1.oraclecloud.com
keyring_oci_management_endpoint=*shortAlphaNumericString*-management.kms.us-ashburn-1.oraclecloud.com
keyring_oci_vaults_endpoint=vaults.us-ashburn-1.oci.oraclecloud.com
keyring_oci_secrets_endpoint=secrets.vaults.us-ashburn-1.oci.oraclecloud.com
keyring_oci_key_file=*file_name*
keyring_oci_key_fingerprint=12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef

有关 keyring_oci 插件特定系统变量的更多信息,请参见 第 8.4.4.19 节,“Keyring 系统变量”。

keyring_oci 插件不支持运行时重新配置,其系统变量均无法在运行时修改。要更改配置参数,请执行以下操作:

  • 修改 my.cnf 文件中的参数设置,或者对于持久化到 mysqld-auto.conf 的参数,使用 SET PERSIST_ONLY

  • 重新启动服务器。

原文:dev.mysql.com/doc/refman/8.0/en/keyring-key-types.html

8.4.4.13 支持的关键环关键类型和长度

MySQL 关键环支持不同类型(加密算法)和长度的关键:

  • 可用的关键类型取决于安装了哪个关键环插件。

  • 允许的关键长度受多个因素影响:

    • 一般关键环可加载函数接口限制(用于使用第 8.4.4.15 节,“通用关键环关键管理函数”中描述的关键环函数之一管理的关键),或来自后端实现的限制。这些长度限制可以根据关键操作类型而变化。

    • 除了一般限制外,单独的关键环插件可能对每种关键类型的关键长度施加限制。

表 8.32,“一般关键环关键长度限制”显示了一般关键长度限制。(keyring_aws的较低限制由 AWS KMS 接口而不是关键环函数强加。)对于关键环插件,表 8.33,“关键环插件关键类型和长度”显示了每个关键环插件允许的关键类型,以及任何插件特定的关键长度限制。对于大多数关键环组件,一般关键长度限制适用,没有关键类型限制。

注意

component_keyring_oci(类似于keyring_oci插件)只能生成大小为 16, 24 或 32 字节的AES类型的关键。

表 8.32 一般关键环关键长度限制

关键操作 最大关键长度
生成关键 16,384 字节(MySQL 8.0.18 之前为 2,048);keyring_aws为 1,024
存储关键 16,384 字节(MySQL 8.0.18 之前为 2,048);keyring_aws为 4,096
获取关键 16,384 字节(MySQL 8.0.18 之前为 2,048);keyring_aws为 4,096

表 8.33 关键环插件关键类型和长度

插件名称 允许的关键类型 插件特定长度限制
keyring_aws AES``SECRET 16, 24 或 32 字节 None
keyring_encrypted_file AES``DSA``RSA``SECRET NoneNoneNoneNone
keyring_file AES``DSA``RSA``SECRET NoneNoneNoneNone
keyring_hashicorp AES``DSA``RSA``SECRET NoneNoneNoneNone
keyring_oci AES 16, 24 或 32 字节
keyring_okv AES``SECRET 16, 24 或 32 字节 None

SECRET关键类型,自 MySQL 8.0.19 起可用,旨在使用 MySQL 关键环对敏感数据进行通用存储,并受大多数关键环组件和关键环插件支持。关键环在存储和检索时将SECRET数据加密和解密为字节流。

涉及SECRET关键类型的示例关键环操作:

SELECT keyring_key_generate('MySecret1', 'SECRET', 20);
SELECT keyring_key_remove('MySecret1');

SELECT keyring_key_store('MySecret2', 'SECRET', 'MySecretData');
SELECT keyring_key_fetch('MySecret2');
SELECT keyring_key_length_fetch('MySecret2');
SELECT keyring_key_type_fetch('MySecret2');
SELECT keyring_key_remove('MySecret2');

原文:dev.mysql.com/doc/refman/8.0/en/keyring-key-migration.html

8.4.4.14 在密钥环密钥库之间迁移密钥

密钥环迁移将密钥从一个密钥库复制到另一个,使得 DBA 可以将 MySQL 安装切换到不同的密钥库。成功的迁移操作会产生以下结果:

  • 目标密钥库包含迁移前具有的密钥,以及源密钥库中的密钥。

  • 在迁移前后,源密钥库保持不变(因为密钥是复制而不是移动)。

如果要复制的密钥已经存在于目标密钥库中,则会发生错误,并且目标密钥库将恢复到迁移前的状态。

密钥环使用密钥环组件和密钥环插件管理密钥库。这与迁移策略有关,因为源密钥库和目标密钥库的管理方式决定了是否可能进行特定类型的密钥迁移以及执行该操作的程序:

  • 从一个密钥环插件迁移到另一个:MySQL 服务器具有提供此功能的操作模式。

  • 从密钥环插件迁移到密钥环组件:MySQL 服务器在 MySQL 8.0.24 版本中提供了此功能的操作模式。

  • 从一个密钥环组件迁移到另一个:mysql_migrate_keyring 实用程序提供了这种能力。mysql_migrate_keyring 自 MySQL 8.0.24 版本起可用。

  • 从密钥环组件迁移到密钥环插件:没有提供此功能。

以下部分讨论了离线和在线迁移的特点,并描述了如何执行迁移。

  • 离线和在线密钥迁移

  • 使用迁移服务器进行密钥迁移

  • 使用 mysql_migrate_keyring 实用程序进行密钥迁移

  • 涉及多个运行服务器的密钥迁移

离线和在线密钥迁移

密钥迁移可以是离线或在线的:

  • 离线迁移:用于确保本地主机上没有运行中的服务器使用源或目标密钥库时使用。在这种情况下,迁移操作可以将密钥从源密钥库复制到目标密钥库,而在操作期间不会发生运行中服务器修改密钥库内容的可能性。

  • 在线迁移:用于当本地主机上运行的服务器正在使用源密钥库时。在这种情况下,必须小心防止服务器在迁移过程中更新密钥库。这涉及连接到运行的服务器并指示其暂停密钥环操作,以便可以安全地从源密钥库复制密钥到目标位置。当密钥复制完成后,允许运行的服务器恢复密钥环操作。

当计划进行密钥迁移时,请使用以下要点来决定是离线还是在线:

  • 不要执行涉及正在运行的服务器使用的密钥库的离线迁移。

  • 在线迁移过程中暂停密钥环操作是通过连接到运行的服务器并将其全局 keyring_operations 系统变量设置为 OFF 来实现的,然后在复制密钥之前设置为 ON。这有几个影响:

    • keyring_operations 是在 MySQL 5.7.21 中引入的,因此只有运行的服务器是 MySQL 5.7.21 或更高版本时才能进行在线迁移。如果运行的服务器较旧,则必须停止它,执行离线迁移,然后重新启动。所有其他地方提到的与 keyring_operations 相关的迁移说明都受到此条件的约束。

    • 用于连接到运行的服务器的帐户必须具有修改 keyring_operations 所需的特权。这些特权是 ENCRYPTION_KEY_ADMIN 以及 SYSTEM_VARIABLES_ADMIN 或已弃用的 SUPER 特权。

    • 如果在线迁移操作异常退出(例如,被强制终止),则可能导致 keyring_operations 在运行的服务器上保持禁用,导致无法执行密钥环操作。在这种情况下,可能需要连接到运行的服务器并使用以下语句手动启用 keyring_operations

      SET GLOBAL keyring_operations = ON;
      
  • 在线密钥迁移允许在单个运行的服务器上暂停密钥环操作。如果多个运行的服务器正在使用涉及的密钥库,则使用在 涉及多个运行服务器的密钥迁移 中描述的过程。

使用迁移服务器进行密钥迁移

注意

仅当运行的服务器允许套接字连接或使用 TLS 的 TCP/IP 连接时,才支持使用迁移服务器进行在线密钥迁移;例如,当服务器在 Windows 平台上运行并且仅允许共享内存连接时,不支持此功能。

如果以支持密钥迁移的特殊操作模式调用,则 MySQL 服务器将成为迁移服务器。迁移服务器不接受客户端连接。相反,它只运行足够长的时间来迁移密钥,然后退出。迁移服务器将错误报告给控制台(标准错误输出)。

迁移服务器支持以下迁移类型:

  • 从一个密钥环插件迁移到另一个。

  • 从密钥环插件迁移到密钥环组件。此功能自 MySQL 8.0.24 版本开始提供。较旧的服务器仅支持从一个密钥环插件迁移到另一个,此时这些指令中涉及密钥环组件的部分不适用。

迁移服务器不支持从一个密钥环组件迁移到另一个密钥环组件。对于这种类型的迁移,请参阅使用 mysql_migrate_keyring 实用程序进行密钥迁移。

要使用迁移服务器执行密钥迁移操作,请确定需要的密钥迁移选项,以指定涉及哪些密钥环插件或组件,以及迁移是离线还是在线的:

  • 要指示源密钥环插件和目标密钥环插件或组件,请指定这些选项:

    • --keyring-migration-source: 管理要迁移的密钥的源密钥环插件。

    • --keyring-migration-destination: 要将迁移的密钥复制到的目标密钥环插件或组件。

    • --keyring-migration-to-component: 如果目标是密钥环组件而不是密钥环插件,则需要此选项。

    --keyring-migration-source--keyring-migration-destination 选项表示服务器应该运行在密钥迁移模式下。对于密钥迁移操作,这两个选项都是必需的。每个插件或组件都使用其库文件的名称指定,包括任何特定于平台的扩展,如.so.dll。源和目标必须不同,并且迁移服务器必须支持它们两者。

  • 对于离线迁移,不需要额外的密钥迁移选项。

  • 对于在线迁移,某个运行服务器当前正在使用源或目标密钥库。要调用迁移服务器,请指定额外的密钥迁移选项,指示如何连接到运行服务器。这是必要的,以便迁移服务器可以连接到运行服务器并告诉其在迁移操作期间暂停密钥环使用。

    使用以下任何选项表示在线迁移:

    • --keyring-migration-host:运行服务器所在的主机。这始终是本地主机,因为迁移服务器只能在本地插件和组件管理的密钥库之间迁移密钥。

    • --keyring-migration-user--keyring-migration-password:用于连接到运行服务器的帐户凭据。

    • --keyring-migration-port:对于 TCP/IP 连接,连接到运行服务器的端口号。

    • --keyring-migration-socket:对于 Unix 套接字文件或 Windows 命名管道连接,连接到运行服务器的套接字文件或命名管道。

有关密钥迁移选项的更多详细信息,请参见第 8.4.4.18 节,“密钥环命令选项”。

使用指示源和目标密钥库以及迁移是离线还是在线的密钥迁移选项启动迁移服务器,可能还有其他选项。请牢记以下考虑事项:

  • 可能需要其他服务器选项,例如两个密钥环插件的配置参数。例如,如果keyring_file是源或目标,则必须设置keyring_file_data系统变量,如果密钥环数据文件位置不是默认位置。还可能需要其他非密钥环选项。指定这些选项的一种方法是使用--defaults-file命名包含所需选项的选项文件。

  • 迁移服务器期望路径名选项值为完整路径。相对路径名可能不会按您的预期解析。

  • 调用服务器以密钥迁移模式启动的用户不得是root操作系统用户,除非使用--user选项指定一个非root用户名来以该用户身份运行服务器。

  • 以密钥迁移模式运行的服务器的用户必须具有读取和写入任何本地密钥环文件的权限,例如基于文件的插件的数据文件。

    如果您以不同于通常用于运行 MySQL 的系统帐户调用迁移服务器,则可能会创建对服务器在正常操作期间无法访问的密钥环目录或文件。假设mysqld通常以mysql操作系统用户运行,但您以isabel登录时调用迁移服务器。迁移服务器创建的任何新目录或文件都归isabel所有。当以mysql操作系统用户运行的服务器尝试访问由isabel拥有的文件系统对象时,后续启动将失败。

    为避免此问题,请将迁移服务器作为root操作系统用户启动,并提供--user=*user_name*选项,其中user_name是通常用于运行 MySQL 的系统帐户。或者,在迁移后,使用chownchmod或类似命令检查与密钥环相关的文件系统对象,并根据需要更改其所有权和权限,以便运行服务器可以访问这些对象。

离线迁移两个密钥环插件之间的示例命令行(在一行上输入命令):

mysqld --defaults-file=/usr/local/mysql/etc/my.cnf
  --keyring-migration-source=keyring_file.so
  --keyring-migration-destination=keyring_encrypted_file.so
  --keyring_encrypted_file_password=*password*

两个密钥环插件之间的在线迁移示例命令行:

mysqld --defaults-file=/usr/local/mysql/etc/my.cnf
  --keyring-migration-source=keyring_file.so
  --keyring-migration-destination=keyring_encrypted_file.so
  --keyring_encrypted_file_password=*password*
  --keyring-migration-host=127.0.0.1
  --keyring-migration-user=root
  --keyring-migration-password=*root_password*

若要执行将目标设置为密钥环组件而不是密钥环插件的迁移,请指定--keyring-migration-to-component选项,并将组件命名为--keyring-migration-destination选项的值。

从密钥环插件迁移到密钥环组件的离线迁移示例命令行:

mysqld --defaults-file=/usr/local/mysql/etc/my.cnf
  --keyring-migration-to-component
  --keyring-migration-source=keyring_file.so
  --keyring-migration-destination=component_keyring_encrypted_file.so

请注意,在这种情况下,未指定keyring_encrypted_file_password值。组件数据文件的密码列在组件配置文件中。

从密钥环插件迁移到密钥环组件的在线迁移示例命令行:

mysqld --defaults-file=/usr/local/mysql/etc/my.cnf
  --keyring-migration-to-component
  --keyring-migration-source=keyring_file.so
  --keyring-migration-destination=component_keyring_encrypted_file.so
  --keyring-migration-host=127.0.0.1
  --keyring-migration-user=root
  --keyring-migration-password=*root_password*

密钥迁移服务器执行以下迁移操作:

  1. (仅在线迁移)使用连接选项连接到运行中的服务器。

  2. (仅在线迁移)在运行中的服务器上禁用keyring_operations

  3. 加载源和目标密钥环插件/组件库。

  4. 将密钥从源密钥库复制到目标密钥库。

  5. 卸载源和目标密钥环插件/组件库。

  6. (仅在线迁移)在运行中的服务器上启用keyring_operations

  7. (仅在线迁移)断开与运行中的服务器的连接。

如果在密钥迁移过程中发生错误,则目标密钥库将恢复到迁移前的状态。

成功进行在线密钥迁移操作后,可能需要重新启动运行中的服务器:

  • 如果运行的服务器在迁移前使用源密钥库,并且在迁移后应继续使用它,则在迁移后无需重新启动。

  • 如果运行的服务器在迁移前使用目标密钥库,并且在迁移后应继续使用它,则应在迁移后重新启动以加载所有迁移到目标密钥库中的密钥。

  • 如果运行的服务器在迁移前使用源密钥库,但在迁移后应使用目标密钥库,则必须重新配置为使用目标密钥库并重新启动。在这种情况下,请注意,尽管在迁移过程中运行的服务器暂停修改源密钥库,但在迁移和随后的重新启动之间的间隔期间不会暂停。应注意在此间隔期间服务器不要修改源密钥库,因为这样的任何更改将不会反映在目标密钥库中。

使用 mysql_migrate_keyring 实用程序进行密钥迁移

mysql_migrate_keyring 实用程序将密钥从一个密钥环组件迁移到另一个。它不支持涉及密钥环插件的迁移。对于这种类型的迁移,请使用在密钥迁移模式下运行的 MySQL 服务器;参见使用迁移服务器进行密钥迁移。

使用mysql_migrate_keyring执行密钥迁移操作时,确定所需的密钥迁移选项,以指定涉及哪些密钥环组件,以及迁移是离线还是在线的:

  • 要指示源和目标密钥环组件及其位置,请指定以下选项:

    • --source-keyring:管理要迁移的密钥的源密钥环组件。

    • --destination-keyring:要将迁移的密钥复制到的目标密钥环组件。

    • --component-dir:包含密钥环组件库文件的目录。这通常是本地 MySQL 服务器的plugin_dir系统变量的值。

    所有三个选项都是必需的。每个密钥库组件名称都是一个组件库文件名,不带任何平台特定的扩展名,如.so.dll。例如,要使用库文件为component_keyring_file.so的组件,请将选项指定为--source-keyring=component_keyring_file。源和目标必须不同,并且mysql_migrate_keyring必须同时支持它们。

  • 对于离线迁移,不需要额外的选项。

  • 对于在线迁移,某个正在运行的服务器当前正在使用源或目标密钥库。在这种情况下,请指定--online-migration选项表示在线迁移。此外,请指定连接选项,指示如何连接到运行的服务器,以便mysql_migrate_keyring可以连接到它并告诉它在迁移操作期间暂停密钥环使用。

    --online-migration选项通常与这些连接选项一起使用:

    • --host:运行服务器所在的主机。这始终是本地主机,因为mysql_migrate_keyring只能在本地组件管理的密钥库之间迁移密钥。

    • --user--password:用于连接到运行服务器的帐户凭据。

    • --port:对于 TCP/IP 连接,在运行服务器上连接的端口号。

    • --socket:对于 Unix 套接字文件或 Windows 命名管道连接,在运行服务器上连接的套接字文件或命名管道。

要查看所有可用选项的描述,请参阅 Section 6.6.8, “mysql_migrate_keyring — Keyring Key Migration Utility”。

启动mysql_migrate_keyring时,需要指定源和目标密钥库以及迁移是离线还是在线,可能还有其他选项。请记住以下几点:

  • 调用mysql_migrate_keyring的用户不能是root操作系统用户。

  • 调用mysql_migrate_keyring的用户必须具有读取和写入任何本地密钥环文件的权限,例如基于文件的插件的数据文件。

    如果您以不同于通常用于运行 MySQL 的系统帐户调用mysql_migrate_keyring,可能会创建对运行服务器在正常操作期间无法访问的密钥环目录或文件。假设mysqld通常以mysql操作系统用户身份运行,但您在isabel登录时调用mysql_migrate_keyringmysql_migrate_keyring创建的任何新目录或文件都归isabel所有。当以mysql操作系统用户身份运行的服务器尝试访问由isabel拥有的文件系统对象时,随后的启动将失败。

    为避免此问题,请以mysql操作系统用户的身份调用mysql_migrate_keyring。或者,在迁移后,检查与密钥环相关的文件系统对象,并根据需要使用chownchmod或类似命令更改它们的所有权和权限,以便运行服务器可以访问这些对象。

假设您想要从component_keyring_file迁移密钥到component_keyring_encrypted_file,并且本地服务器将其密钥环组件库文件存储在/usr/local/mysql/lib/plugin中。

如果没有运行中的服务器正在使用密钥环,允许进行离线迁移。像这样调用mysql_migrate_keyring(在一行中输入命令):

mysql_migrate_keyring
  --component-dir=/usr/local/mysql/lib/plugin
  --source-keyring=component_keyring_file
  --destination-keyring=component_keyring_encrypted_file

如果运行中的服务器正在使用密钥环,则必须执行在线迁移。在这种情况下,必须提供--online-migration选项,以及指定要连接的服务器和要使用的 MySQL 帐户所需的任何连接选项。

以下命令执行在线迁移。它使用 TCP/IP 连接和admin帐户连接到本地服务器。命令提示输入密码,您应在提示时输入密码:

mysql_migrate_keyring
  --component-dir=/usr/local/mysql/lib/plugin
  --source-keyring=component_keyring_file
  --destination-keyring=component_keyring_encrypted_file
  --online-migration --host=127.0.0.1 --user=admin --password

mysql_migrate_keyring执行迁移操作如下:

  1. (仅限在线迁移)使用连接选项连接到运行中的服务器。

  2. (仅限在线迁移)在运行中的服务器上禁用keyring_operations

  3. 加载源和目标密钥库的密钥环组件库。

  4. 将密钥从源密钥库复制到目标密钥库。

  5. 卸载源和目标密钥库的密钥环组件库。

  6. (仅限在线迁移)在运行中的服务器上启用keyring_operations

  7. (仅限在线迁移)断开与运行中的服务器的连接。

如果在密钥迁移过程中发生错误,则目标密钥库将恢复到迁移前的状态。

在成功的在线密钥迁移操作之后,运行中的服务器可能需要重新启动:

  • 如果运行中的服务器在迁移前使用源密钥库,并且在迁移后应继续使用它,则在迁移后无需重新启动。

  • 如果在迁移前运行中的服务器使用目标密钥库,并且在迁移后应继续使用它,则应在迁移后重新启动以加载所有迁移到目标密钥库中的密钥。

  • 如果在迁移前运行中的服务器使用源密钥库,但在迁移后应使用目标密钥库,则必须重新配置以使用目标密钥库并重新启动。在这种情况下,请注意,尽管在迁移过程中暂停了运行中的服务器对源密钥库的修改,但在迁移和随后的重新启动之间的间隔期间,服务器并未暂停。应注意确保服务器在此间隔期间不修改源密钥库,因为这些更改不会反映在目标密钥库中。

涉及多个运行中的服务器的密钥迁移

在线密钥迁移允许暂停单个运行中的服务器上的密钥环操作。如果多个运行中的服务器正在使用涉及的密钥库,则使用以下过程执行迁移:

  1. 手动连接到每个运行中的服务器,并设置keyring_operations=OFF。这确保没有运行中的服务器正在使用源密钥库或目标密钥库,并满足离线迁移所需的条件。

  2. 使用迁移服务器或mysql_migrate_keyring为每个暂停的服务器执行离线密钥迁移。

  3. 手动连接到每个运行中的服务器,并设置keyring_operations=ON

所有运行中的服务器必须支持keyring_operations系统变量。任何不支持的服务器在迁移前必须停止,并在迁移后重新启动。

原文:dev.mysql.com/doc/refman/8.0/en/keyring-functions-general-purpose.html

8.4.4.15 通用密钥环密钥管理函数

MySQL 服务器支持一个密钥环服务,使内部组件和插件能够安全地存储敏感信息以供以后检索。

MySQL 服务器还包括一个用于密钥环密钥管理的 SQL 接口,实现为一组访问内部密钥环服务提供的功能的通用函数。密钥环函数包含在一个插件库文件中,该文件还包含一个必须在函数调用之前启用的keyring_udf插件。要使用这些函数,必须启用诸如keyring_filekeyring_okv之类的密钥环插件。

这里描述的函数是通用的,旨在与任何密钥环插件一起使用。特定的密钥环插件可能具有专为仅与该插件一起使用的自己的函数;请参见第 8.4.4.16 节,“特定插件的密钥环密钥管理函数”。

下面的章节提供了关于密钥环函数的安装说明,并演示如何使用它们。有关这些函数调用的密钥环服务函数的信息,请参见第 7.6.9.2 节,“密钥环服务”。有关一般密钥环信息,请参见第 8.4.4 节,“MySQL 密钥环”。

  • 安装或卸载通用密钥环函数

  • 使用通用密钥环函数

  • 通用密钥环函数参考

安装或卸载通用密钥环函数

本节描述了如何安装或卸载密钥环函数,这些函数实现在一个插件库文件中,该文件还包含一个keyring_udf插件。有关安装或卸载插件和可加载函数的一般信息,请参见第 7.6.1 节,“安装和卸载插件”,以及第 7.7.1 节,“安装和卸载可加载函数”。

密钥环函数使密钥环密钥管理操作成为可能,但必须安装keyring_udf插件,因为没有它,这些函数无法正常工作。尝试在没有keyring_udf插件的情况下使用这些函数会导致错误。

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

插件库文件基本名称为keyring_udf。文件名后缀因平台而异(例如,对于 Unix 和类 Unix 系统,为.so,对于 Windows 为.dll)。

要安装keyring_udf插件和钥匙环函数,请使用INSTALL PLUGINCREATE FUNCTION语句,根据需要调整.so后缀以适应您的平台:

INSTALL PLUGIN keyring_udf SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_generate RETURNS INTEGER
  SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_fetch RETURNS STRING
  SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_length_fetch RETURNS INTEGER
  SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_type_fetch RETURNS STRING
  SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_store RETURNS INTEGER
  SONAME 'keyring_udf.so';
CREATE FUNCTION keyring_key_remove RETURNS INTEGER
  SONAME 'keyring_udf.so';

如果插件和函数在源复制服务器上使用,则还必须在所有副本上安装它们,以避免复制问题。

一旦按照上述方式安装,插件和函数将保持安装状态直到卸载。要删除它们,请使用UNINSTALL PLUGINDROP FUNCTION语句:

UNINSTALL PLUGIN keyring_udf;
DROP FUNCTION keyring_key_generate;
DROP FUNCTION keyring_key_fetch;
DROP FUNCTION keyring_key_length_fetch;
DROP FUNCTION keyring_key_type_fetch;
DROP FUNCTION keyring_key_store;
DROP FUNCTION keyring_key_remove;
使用通用钥匙环函数

在使用钥匙环通用函数之前,请根据安装或卸载通用钥匙环函数中提供的说明安装它们。

钥匙环函数受以下约束:

  • 要使用任何钥匙环函数,必须启用keyring_udf插件。否则,会出现错误:

    ERROR 1123 (HY000): Can't initialize function 'keyring_key_generate';
    This function requires keyring_udf plugin which is not installed.
    Please install
    

    要安装keyring_udf插件,请参阅安装或卸载通用钥匙环函数。

  • 钥匙环函数调用钥匙环服务函数(参见第 7.6.9.2 节,“钥匙环服务”)。服务函数反过来使用安装的任何钥匙环插件(例如,keyring_filekeyring_okv)。因此,要使用任何钥匙环函数,必须启用某个基础钥匙环插件。否则,会出现错误:

    ERROR 3188 (HY000): Function 'keyring_key_generate' failed because
    underlying keyring service returned an error. Please check if a
    keyring plugin is installed and that provided arguments are valid
    for the keyring you are using.
    

    要安装钥匙环插件,请参阅第 8.4.4.3 节,“钥匙环插件安装”。

  • 用户必须拥有全局EXECUTE权限才能使用任何钥匙环函数。否则,会出现错误:

    ERROR 1123 (HY000): Can't initialize function 'keyring_key_generate';
    The user is not privileged to execute this function. User needs to
    have EXECUTE
    

    要向用户授予全局EXECUTE权限,请使用此语句:

    GRANT EXECUTE ON *.* TO *user*;
    

    或者,如果您希望避免授予全局EXECUTE权限,同时仍允许用户访问特定的密钥管理操作,可以定义“包装器”存储程序(这是本节稍后描述的一种技术)。

  • 由给定用户在密钥环中存储的密钥后续只能由同一用户操作。也就是说,在密钥操作时CURRENT_USER()函数的值必须与密钥存储在密钥环中时的值相同。(此约束排除了使用密钥环函数来操作实例范围密钥的情况,例如InnoDB创建的用于支持表空间加密的密钥。)

    为了使多个用户能够对同一密钥执行操作,可以定义“包装器”存储程序(这是本节稍后描述的一种技术)。

  • 密钥环函数支持底层密钥环插件支持的密钥类型和长度。有关特定于特定密钥环插件的密钥的信息,请参见第 8.4.4.13 节,“支持的密钥环密钥类型和长度”。

要创建一个新的随机密钥并将其存储在密钥环中,请调用keyring_key_generate(),传递给它一个密钥的 ID,以及密钥类型(加密方法)和以字节为单位的长度。以下调用创建一个名为MyKey的 2,048 位 DSA 加密密钥:

mysql> SELECT keyring_key_generate('MyKey', 'DSA', 256);
+-------------------------------------------+
| keyring_key_generate('MyKey', 'DSA', 256) |
+-------------------------------------------+
|                                         1 |
+-------------------------------------------+

返回值为 1 表示成功。如果无法创建密钥,则返回值为NULL并出现错误。可能的原因之一是底层密钥环插件不支持指定的密钥类型和密钥长度的组合;请参见第 8.4.4.13 节,“支持的密钥环密钥类型和长度”。

为了能够检查返回类型,无论是否发生错误,请使用SELECT ... INTO @*var_name*并测试变量值:

mysql> SELECT keyring_key_generate('', '', -1) INTO @x;
ERROR 3188 (HY000): Function 'keyring_key_generate' failed because
underlying keyring service returned an error. Please check if a
keyring plugin is installed and that provided arguments are valid
for the keyring you are using.
mysql> SELECT @x;
+------+
| @x   |
+------+
| NULL |
+------+
mysql> SELECT keyring_key_generate('x', 'AES', 16) INTO @x;
mysql> SELECT @x;
+------+
| @x   |
+------+
|    1 |
+------+

这种技术也适用于其他密钥环函数,对于失败返回一个值和一个错误。

传递给keyring_key_generate()的 ID 提供了在后续函数调用中引用密钥的方法。例如,使用密钥 ID 将其类型作为字符串或其长度作为整数检索:

mysql> SELECT keyring_key_type_fetch('MyKey');
+---------------------------------+
| keyring_key_type_fetch('MyKey') |
+---------------------------------+
| DSA                             |
+---------------------------------+
mysql> SELECT keyring_key_length_fetch('MyKey');
+-----------------------------------+
| keyring_key_length_fetch('MyKey') |
+-----------------------------------+
|                               256 |
+-----------------------------------+

要检索密钥值,请将密钥 ID 传递给keyring_key_fetch()。以下示例使用HEX()显示密钥值,因为它可能包含不可打印的字符。示例还使用了一个简短的密钥以简洁起见,但请注意,更长的密钥提供更好的安全性:

mysql> SELECT keyring_key_generate('MyShortKey', 'DSA', 8);
+----------------------------------------------+
| keyring_key_generate('MyShortKey', 'DSA', 8) |
+----------------------------------------------+
|                                            1 |
+----------------------------------------------+
mysql> SELECT HEX(keyring_key_fetch('MyShortKey'));
+--------------------------------------+
| HEX(keyring_key_fetch('MyShortKey')) |
+--------------------------------------+
| 1DB3B0FC3328A24C                     |
+--------------------------------------+

钥匙环函数将密钥 ID、类型和值视为二进制字符串,因此比较区分大小写。例如,MyKeymykey的 ID 指的是不同的密钥。

要移除一个密钥,请将密钥 ID 传递给keyring_key_remove()

mysql> SELECT keyring_key_remove('MyKey');
+-----------------------------+
| keyring_key_remove('MyKey') |
+-----------------------------+
|                           1 |
+-----------------------------+

要混淆和存储您提供的密钥,请将密钥 ID、类型和值传递给keyring_key_store()

mysql> SELECT keyring_key_store('AES_key', 'AES', 'Secret string');
+------------------------------------------------------+
| keyring_key_store('AES_key', 'AES', 'Secret string') |
+------------------------------------------------------+
|                                                    1 |
+------------------------------------------------------+

如前所述,用户必须具有全局EXECUTE权限才能调用钥匙环函数,并且最初将密钥存储在钥匙环中的用户必须是稍后执行密钥操作的同一用户,这是根据每个函数调用中生效的CURRENT_USER()值确定的。为了允许没有全局EXECUTE权限或可能不是密钥“所有者”的用户执行密钥操作,请使用以下技术:

  1. 定义“包装”存储程序,封装所需的密钥操作,并且DEFINER值等于密钥所有者。

  2. 为应该能够调用特定存储程序的个别用户授予EXECUTE权限。

  3. 如果包装存储程序实现的操作不包括密钥创建,请提前创建任何必要的密钥,使用存储程序定义中命名为DEFINER的账户。

该技术使密钥可以在用户之间共享,并为 DBA 提供了更精细的控制权,以确定谁可以对密钥执行什么操作,而无需授予全局权限。

以下示例显示如何设置一个名为SharedKey的共享密钥,由 DBA 拥有,并且提供对当前密钥值的访问的get_shared_key()存储函数。该值可以被具有EXECUTE权限的任何用户检索,该权限是在key_schema模式中创建的。

从 MySQL 管理账户(在此示例中为'root'@'localhost')中,创建管理模式和用于访问密钥的存储函数:

mysql> CREATE SCHEMA key_schema;

mysql> CREATE DEFINER = 'root'@'localhost'
       FUNCTION key_schema.get_shared_key()
       RETURNS BLOB READS SQL DATA
       RETURN keyring_key_fetch('SharedKey');

从管理账户中,确保共享密钥存在:

mysql> SELECT keyring_key_generate('SharedKey', 'DSA', 8);
+---------------------------------------------+
| keyring_key_generate('SharedKey', 'DSA', 8) |
+---------------------------------------------+
|                                           1 |
+---------------------------------------------+

从管理账户中,创建一个普通用户账户,以便授予密钥访问权限:

mysql> CREATE USER 'key_user'@'localhost'
       IDENTIFIED BY 'key_user_pwd';

key_user账户中,验证,如果没有适当的EXECUTE权限,新账户无法访问共享密钥:

mysql> SELECT HEX(key_schema.get_shared_key());
ERROR 1370 (42000): execute command denied to user 'key_user'@'localhost'
for routine 'key_schema.get_shared_key'

从管理账户中,为存储函数授予EXECUTEkey_user

mysql> GRANT EXECUTE ON FUNCTION key_schema.get_shared_key
       TO 'key_user'@'localhost';

key_user账户中,验证该密钥现在是可访问的:

mysql> SELECT HEX(key_schema.get_shared_key());
+----------------------------------+
| HEX(key_schema.get_shared_key()) |
+----------------------------------+
| 9BAFB9E75CEEB013                 |
+----------------------------------+
通用用途钥匙环函数参考

对于每个通用密钥环函数,本节描述了其目的、调用顺序和返回值。有关可以调用这些函数的条件的信息,请参见使用通用密钥环函数。

  • keyring_key_fetch(*key_id*)

    给定密钥 ID,解密并返回密钥值。

    参数:

    • key_id: 一个指定密钥 ID 的字符串。

    返回值:

    返回成功的字符串密钥值,如果密钥不存在则返回NULL,或者返回NULL和错误。

    注意

    使用keyring_key_fetch()检索的密钥值受第 8.4.4.13 节,“支持的密钥类型和长度”中描述的一般密钥函数限制的约束。超过该长度的密钥值可以使用密钥环服务函数存储(参见第 7.6.9.2 节,“密钥环服务”),但如果使用keyring_key_fetch()检索,则会被截断为一般密钥环函数限制的长度。

    示例:

    mysql> SELECT keyring_key_generate('RSA_key', 'RSA', 16);
    +--------------------------------------------+
    | keyring_key_generate('RSA_key', 'RSA', 16) |
    +--------------------------------------------+
    |                                          1 |
    +--------------------------------------------+
    mysql> SELECT HEX(keyring_key_fetch('RSA_key'));
    +-----------------------------------+
    | HEX(keyring_key_fetch('RSA_key')) |
    +-----------------------------------+
    | 91C2253B696064D3556984B6630F891A  |
    +-----------------------------------+
    mysql> SELECT keyring_key_type_fetch('RSA_key');
    +-----------------------------------+
    | keyring_key_type_fetch('RSA_key') |
    +-----------------------------------+
    | RSA                               |
    +-----------------------------------+
    mysql> SELECT keyring_key_length_fetch('RSA_key');
    +-------------------------------------+
    | keyring_key_length_fetch('RSA_key') |
    +-------------------------------------+
    |                                  16 |
    +-------------------------------------+
    

    该示例使用HEX()来显示密钥值,因为它可能包含不可打印字符。该示例还使用了一个简短的密钥以便简洁,但请注意,更长的密钥提供更���的安全性。

  • keyring_key_generate(*key_id*, *key_type*, *key_length*)

    生成具有给定 ID、类型和长度的新随机密钥,并将其存储在密钥环中。类型和长度值必须与底层密钥环插件支持的值一致。参见第 8.4.4.13 节,“支持的密钥类型和长度”。

    参数:

    • key_id: 一个指定密钥 ID 的字符串。

    • key_type: 一个指定密钥类型的字符串。

    • key_length: 一个指定以字节为单位的密钥长度的整数。

    返回值:

    返回成功的 1,或者返回NULL和错误。

    示例:

    mysql> SELECT keyring_key_generate('RSA_key', 'RSA', 384);
    +---------------------------------------------+
    | keyring_key_generate('RSA_key', 'RSA', 384) |
    +---------------------------------------------+
    |                                           1 |
    +---------------------------------------------+
    
  • keyring_key_length_fetch(*key_id*)

    给定密钥 ID,返回密钥长度。

    参数:

    • key_id: 一个指定密钥 ID 的字符串。

    返回值:

    返回成功的整数字节密钥长度,如果密钥不存在则返回NULL,或者返回NULL和错误。

    示例:

    请参阅keyring_key_fetch()的描述。

  • keyring_key_remove(*key_id*)

    从密钥环中删除具有给定 ID 的密钥。

    参数:

    • key_id: 指定密钥 ID 的字符串。

    返回值:

    返回成功时为 1,失败时返回NULL

    示例:

    mysql> SELECT keyring_key_remove('AES_key');
    +-------------------------------+
    | keyring_key_remove('AES_key') |
    +-------------------------------+
    |                             1 |
    +-------------------------------+
    
  • keyring_key_store(*key_id*, *key_type*, *key*)

    对密钥进行混淆并存储在密钥环中。

    参数:

    • key_id: 指定密钥 ID 的字符串。

    • key_type: 指定密钥类型的字符串。

    • key: 指定密钥值的字符串。

    返回值:

    返回成功时为 1,失败时返回NULL和错误。

    示例:

    mysql> SELECT keyring_key_store('new key', 'DSA', 'My key value');
    +-----------------------------------------------------+
    | keyring_key_store('new key', 'DSA', 'My key value') |
    +-----------------------------------------------------+
    |                                                   1 |
    +-----------------------------------------------------+
    
  • keyring_key_type_fetch(*key_id*)

    给定密钥 ID,返回密钥类型。

    参数:

    • key_id: 指定密钥 ID 的字符串。

    返回值:

    返回成功时的密钥类型字符串,如果密钥不存在则返回NULL,失败时返回NULL和错误。

    示例:

    参见keyring_key_fetch()的描述。

原文:dev.mysql.com/doc/refman/8.0/en/keyring-functions-plugin-specific.html

8.4.4.16 插件特定的密钥环密钥管理函数

对于每个密钥环插件特定的函数,本节描述了其目的、调用顺序和返回值。有关通用密钥环函数的信息,请参见第 8.4.4.15 节,“通用密钥环密钥管理函数”。

  • keyring_aws_rotate_cmk()

    关联的密钥环插件:keyring_aws

    keyring_aws_rotate_cmk()旋转 AWS KMS 密钥。旋转仅更改 AWS KMS 用于后续数据密钥加密操作的密钥。AWS KMS 保留先前的 CMK 版本,因此使用先前 CMK 生成的密钥在旋转后仍然可解密。

    旋转会更改 AWS KMS 内部使用的 CMK 值,但不会更改用于引用它的 ID,因此在调用keyring_aws_rotate_cmk()之后无需更改keyring_aws_cmk_id系统变量。

    此函数需要SUPER权限。

    参数:

    无。

    返回值:

    返回 1 表示成功,或者返回NULL和错误表示失败。

  • keyring_aws_rotate_keys()

    关联的密钥环插件:keyring_aws

    keyring_aws_rotate_keys()用于旋转存储在由keyring_aws_data_file系统变量命名的keyring_aws存储文件中的密钥。旋转将文件中的每个密钥发送到 AWS KMS 进行重新加密,使用keyring_aws_cmk_id系统变量的值作为 CMK 值,并将新加密的密钥存储在文件中。

    keyring_aws_rotate_keys()在以下情况下用于密钥重新加密:

    • 在旋转 CMK 之后;也就是在调用keyring_aws_rotate_cmk()函数之后。

    • 在更改keyring_aws_cmk_id系统变量为不同密钥值之后。

    此函数需要SUPER权限。

    参数:

    无。

    返回值:

    返回 1 表示成功,或者返回NULL和错误表示失败。

  • keyring_hashicorp_update_config()

    关联的密钥环插件:keyring_hashicorp

    调用keyring_hashicorp_update_config()函数会导致keyring_hashicorp执行运行时重新配置,如 keyring_hashicorp Configuration 中所述。

    此函数需要SYSTEM_VARIABLES_ADMIN权限,因为它修改全局系统变量。

    参数:

    无。

    返回值:

    返回成功时字符串'Configuration update was successful.',失败时返回'Configuration update failed.'

原文:dev.mysql.com/doc/refman/8.0/en/keyring-metadata.html

8.4.4.17 密钥环元数据

本节描述了关于密钥环使用的信息来源。

要查看密钥环插件是否已加载,请检查信息模式PLUGINS表或使用SHOW PLUGINS语句(参见第 7.6.2 节,“获取服务器插件信息”)。例如:

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
       FROM INFORMATION_SCHEMA.PLUGINS
       WHERE PLUGIN_NAME LIKE 'keyring%';
+--------------+---------------+
| PLUGIN_NAME  | PLUGIN_STATUS |
+--------------+---------------+
| keyring_file | ACTIVE        |
+--------------+---------------+

要查看存在哪些密钥,请检查性能模式keyring_keys表:

mysql> SELECT * FROM performance_schema.keyring_keys;
+-----------------------------+--------------+----------------+
| KEY_ID                      | KEY_OWNER    | BACKEND_KEY_ID |
+-----------------------------+--------------+----------------+
| audit_log-20210322T130749-1 |              |                |
| MyKey                       | me@localhost |                |
| YourKey                     | me@localhost |                |
+-----------------------------+--------------+----------------+

要查看密钥环组件是否已加载,请检查性能模式keyring_component_status表。例如:

mysql> SELECT * FROM performance_schema.keyring_component_status;
+---------------------+-------------------------------------------------+
| STATUS_KEY          | STATUS_VALUE                                    |
+---------------------+-------------------------------------------------+
| Component_name      | component_keyring_file                          |
| Author              | Oracle Corporation                              |
| License             | GPL                                             |
| Implementation_name | component_keyring_file                          |
| Version             | 1.0                                             |
| Component_status    | Active                                          |
| Data_file           | /usr/local/mysql/keyring/component_keyring_file |
| Read_only           | No                                              |
+---------------------+-------------------------------------------------+

Component_status值为Active表示组件初始化成功。如果组件加载但初始化失败,则值为Disabled

原文:dev.mysql.com/doc/refman/8.0/en/keyring-options.html

8.4.4.18 密钥环命令选项

MySQL 支持以下与密钥环相关的命令行选项:

  • --keyring-migration-destination=*plugin*

    命令行格式 --keyring-migration-destination=plugin_name
    类型 字符串

    用于密钥迁移的目标密钥环插件。参见第 8.4.4.14 节,“在密钥环密钥存储之间迁移密钥”。选项值的解释取决于是否指定了--keyring-migration-to-component

    • 如果没有指定,则选项值是一个密钥环插件,解释方式与--keyring-migration-source相同。

    • 如果是,则选项值是一个密钥环组件,指定为插件目录中的组件库名称,包括任何特定于平台的扩展,如.so.dll

    注意

    --keyring-migration-source--keyring-migration-destination对于所有密钥环迁移操作都是必需的。源和目标插件必须不同,并且迁移服务器必须支持这两个插件。

  • --keyring-migration-host=*host_name*

    命令行格式 --keyring-migration-host=host_name
    类型 字符串
    默认值 localhost

    当前正在使用其中一个密钥迁移密钥库的运行服务器的主机位置。参见第 8.4.4.14 节,“在密钥环密钥存储之间迁移密钥”。迁移始终在本地主机上进行,因此该选项始终指定用于连接到本地服务器的值,例如localhost127.0.0.1::1或本地主机 IP 地址或主机名。

  • --keyring-migration-password[=*password*]

    命令行格式 --keyring-migration-password[=password]
    类型 字符串

    用于连接到当前使用其中一个密钥迁移密钥库的运行服务器的 MySQL 帐户的密码。参见第 8.4.4.14 节,“在密钥环密钥存储之间迁移密钥”。

    密码值是可选的。如果未提供,则服务器会提示输入。如果提供了密码,则--keyring-migration-password=后面必须没有空格。如果未指定密码选项,则默认情况下不发送密码。

    在命令行上指定密码应被视为不安全。请参见第 8.1.2.1 节,“密码安全的最终用户指南”。您可以使用选项文件来避免在命令行上提供密码。在这种情况下,文件应具有严格的模式,并且只能由用于运行迁移服务器的帐户访问。

  • --keyring-migration-port=*端口号*

    命令行格式 --keyring-migration-port=端口号
    类型 数值
    默认值 3306

    对于 TCP/IP 连接,连接到当前使用密钥迁移密钥库之一的运行服务器的端口号。参见第 8.4.4.14 节,“在密钥环密钥存储之间迁移密钥”。

  • --keyring-migration-socket=*路径*

    命令行格式 --keyring-migration-socket={file_name&#124;pipe_name}
    类型 字符串

    对于 Unix 套接字文件或 Windows 命名管道连接,连接到当前使用密钥迁移密钥库之一的运行服务器的套接字文件或命名管道。参见第 8.4.4.14 节,“在密钥环密钥存储之间迁移密钥”。

  • --keyring-migration-source=*插件*

    命令行格式 --keyring-migration-source=plugin_name
    类型 字符串

    密钥迁移的源密钥环插件。参见第 8.4.4.14 节,“在密钥环密钥存储之间迁移密钥”。

    该选项的值类似于--plugin-load,但只能指定一个插件库。该值以plugin_libraryname=plugin_library的形式给出,其中plugin_library是包含插件代码的库文件的名称,name是要加载的插件的名称。如果命名了一个插件库而没有任何前置插件名称,服务器将加载库中的所有插件。有了前置插件名称,服务器将仅从库中加载指定的插件。服务器在由plugin_dir系统变量命名的目录中查找插件库文件。

    注意

    --keyring-migration-source--keyring-migration-destination对于所有密钥环迁移操作都是必需的。源和目标插件必须不同,并且迁移服务器必须支持这两个插件。

  • --keyring-migration-to-component

    命令行格式 --keyring-migration-to-component[={OFF&#124;ON}]
    引入版本 8.0.24
    类型 布尔值
    默认值 OFF

    表示密钥迁移是从密钥环插件到密钥环组件的。此选项使得可以从任何密钥环插件迁移密钥到任何密钥环组件,从而便于将 MySQL 安装从密钥环插件过渡到密钥环组件。

    对于从一个密钥环组件迁移密钥到另一个密钥环组件,请使用mysql_migrate_keyring实用程序。不支持从密钥环组件迁移到密钥环插件。请参阅第 8.4.4.14 节,“在密钥环密钥库之间迁移密钥”。

  • --keyring-migration-user=*user_name*

    命令行格式 --keyring-migration-user=user_name
    类型 字符串

    用于连接当前正在使用其中一个密钥迁移密钥库的运行服务器的 MySQL 帐户的用户名。请参阅第 8.4.4.14 节,“在密钥环密钥库之间迁移密钥”。

原文:dev.mysql.com/doc/refman/8.0/en/keyring-system-variables.html

8.4.4.19 密钥环系统变量

MySQL 密钥环插件支持以下系统变量。使用它们来配置密钥环插件操作。除非安装了适当的密钥环插件(请参阅第 8.4.4.3 节,“密钥环插件安装”),否则这些变量不可用。

  • keyring_aws_cmk_id

    命令行格式 --keyring-aws-cmk-id=value
    系统变量 keyring_aws_cmk_id
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    从 AWS KMS 服务器获取并由keyring_aws 插件使用的 KMS 密钥 ID。除非安装了该插件,否则此变量不可用。

    此变量为必填项。如果未指定,keyring_aws 初始化将失败。

  • keyring_aws_conf_file

    命令行格式 --keyring-aws-conf-file=file_name
    系统变量 keyring_aws_conf_file
    范围 全局
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 特定于平台

    keyring_aws 插件的配置文件位置。除非安装了该插件,否则此变量不可用。

    在插件启动时,keyring_aws 从配置文件中读取 AWS 秘密访问密钥 ID 和密钥。为了使keyring_aws 插件成功启动,配置文件必须存在并包含有效的秘密访问密钥信息,初始化如第 8.4.4.9 节,“使用 keyring_aws 亚马逊网络服务密钥环插件”中所述。

    默认文件名为keyring_aws_conf,位于默认密钥环文件目录中。此默认目录的位置与keyring_file_data系统变量相同。有关详细信息,请参阅该变量的描述,以及如果手动创建目录时要考虑的注意事项。

  • keyring_aws_data_file

    命令行格式 --keyring-aws-data-file
    系统变量 keyring_aws_data_file
    范围 全局
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 特定于平台

    存储keyring_aws插件的文件位置。除非安装了该插件,否则此变量不可用。

    在插件启动时,如果分配给keyring_aws_data_file的值指定不存在的文件,则keyring_aws插件会尝试创建它(以及必要时的父目录)。如果文件存在,keyring_aws会将文件中包含的任何加密密钥读入其内存缓存中。keyring_aws不会在内存中缓存未加密的密钥。

    默认文件名为keyring_aws_data,位于默认密钥环文件目录中。此默认目录的位置与keyring_file_data系统变量相同。有关详细信息,请参阅该变量的描述,以及如果手动创建目录时需要考虑的事项。

  • keyring_aws_region

    命令行格式 --keyring-aws-region=value
    系统变量 keyring_aws_region
    作用域 全局
    动态
    SET_VAR提示适用
    类型 枚举
    默认值 us-east-1
    有效值(≥ 8.0.30) af-south-1``ap-east-1``ap-northeast-1``ap-northeast-2``ap-northeast-3``ap-south-1``ap-southeast-1``ap-southeast-2``ca-central-1``cn-north-1``cn-northwest-1``eu-central-1``eu-north-1``eu-south-1``eu-west-1``eu-west-2``eu-west-3``me-south-1``sa-east-1``us-east-1``us-east-2``us-gov-east-1``us-iso-east-1``us-iso-west-1``us-isob-east-1``us-west-1``us-west-2
    有效值(≥ 8.0.17, ≤ 8.0.29) ap-northeast-1``ap-northeast-2``ap-south-1``ap-southeast-1``ap-southeast-2``ca-central-1``cn-north-1``cn-northwest-1``eu-central-1``eu-west-1``eu-west-2``eu-west-3``sa-east-1``us-east-1``us-east-2``us-west-1``us-west-2
    有效值(≤ 8.0.16) ap-northeast-1``ap-northeast-2``ap-south-1``ap-southeast-1``ap-southeast-2``eu-central-1``eu-west-1``sa-east-1``us-east-1``us-west-1``us-west-2

    keyring_aws插件的 AWS 区域。除非安装了该插件,否则此变量不可用。

  • keyring_encrypted_file_data

    命令行格式 --keyring-encrypted-file-data=file_name
    已弃用 8.0.34
    系统变量 keyring_encrypted_file_data
    作用域 全局
    动态
    SET_VAR提示适用
    类型 文件名
    默认值 特定于平台

    注意

    截至 MySQL 8.0.34 版本,keyring_encrypted_file 插件已被弃用,并可能在将来的 MySQL 版本中被移除。考虑使用 component_keyring_encrypted_file 替代;component_keyring_encrypted_file 组件取代了 keyring_encrypted_file 插件。

    keyring_encrypted_file 插件用于安全数据存储的数据文件的路径名。除非安装了该插件,否则此变量不可用。文件位置应位于仅供密钥环插件使用的目录中。例如,不要将文件放在数据目录下。

    密钥环操作是事务性的:keyring_encrypted_file 插件在写操作期间使用备份文件,以确保如果操作失败,可以回滚到原始文件。备份文件与 keyring_encrypted_file_data 系统变量的值相同,后缀为 .backup

    不要为多个 MySQL 实例使用相同的 keyring_encrypted_file 数据文件。每个实例应该有自己独特的数据文件。

    默认文件名为 keyring_encrypted,位于特定于平台的目录中,取决于 INSTALL_LAYOUT CMake 选项的值,如下表所示。如果您正在从源代码构建,并且要明确指定文件的默认目录,请使用 INSTALL_MYSQLKEYRINGDIR CMake 选项。

    INSTALL_LAYOUT 默认 keyring_encrypted_file_data
    DEB, RPM, SVR4 /var/lib/mysql-keyring/keyring_encrypted
    否则 CMAKE_INSTALL_PREFIX 值下的 keyring/keyring_encrypted

    在插件启动时,如果分配给 keyring_encrypted_file_data 的值指定一个不存在的文件,则 keyring_encrypted_file 插件会尝试创建它(以及必要时的父目录)。

    如果您手动创建目录,应该具有严格的模式,并且只能由用于运行 MySQL 服务器的帐户访问。例如,在 Unix 和类 Unix 系统上,要使用 /usr/local/mysql/mysql-keyring 目录,以下命令(以 root 执行)创建目录并设置其模式和所有权:

    cd /usr/local/mysql
    mkdir mysql-keyring
    chmod 750 mysql-keyring
    chown mysql mysql-keyring
    chgrp mysql mysql-keyring
    

    如果 keyring_encrypted_file 插件无法创建或访问其数据文件,它会将错误消息写入错误日志。如果尝试对 keyring_encrypted_file_data 进行运行时赋值导致错误,则变量值保持不变。

    重要

    一旦 keyring_encrypted_file 插件创建了其数据文件并开始使用它,重要的是不要删除该文件。文件丢失会导致使用其密钥加密的数据无法访问。(可以重命名或移动文件,只要您将 keyring_encrypted_file_data 的值相匹配即可。)

  • keyring_encrypted_file_password

    命令行格式 --keyring-encrypted-file-password=password
    已弃用 8.0.34
    系统变量 keyring_encrypted_file_password
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    注意

    截至 MySQL 8.0.34 版本,keyring_encrypted_file 插件已被弃用,并可能在未来的 MySQL 版本中被移除。考虑使用 component_keyring_encrypted_file 替代;component_keyring_encrypted_file 组件取代了 keyring_encrypted_file 插件。

    keyring_encrypted_file 插件使用的密码。除非安装了该插件,否则此变量不可用。

    此变量是强制性的。如果未指定,keyring_encrypted_file 初始化将失败。

    如果在选项文件中指定了此变量,则文件应具有限制模式,并且只能由用于运行 MySQL 服务器的帐户访问。

    重要

    一旦设置了 keyring_encrypted_file_password 的值,更改它不会旋转密钥环密码,并且可能导致服务器无法访问。如果提供了错误密码,则 keyring_encrypted_file 插件无法从加密的密钥环文件中加载密钥。

    密码数值无法在运行时通过 SHOW VARIABLES 或性能模式 global_variables 表显示,因为显示数值已被混淆。

  • keyring_file_data

    命令行格式 --keyring-file-data=file_name
    已弃用 8.0.34
    系统变量 keyring_file_data
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 特定于平台

    注意

    截至 MySQL 8.0.34 版本,keyring_file 插件已被弃用,并可能在未来的 MySQL 版本中被移除。考虑使用 component_keyring_file 替代;component_keyring_file 组件取代了 keyring_file 插件。

    keyring_file 插件用于安全数据存储的数据文件的路径名。除非安装了该插件,否则此变量不可用。文件位置应位于仅供密钥环插件使用的目录中。例如,不要将文件放在数据目录下。

    密钥环操作是事务性的:keyring_file 插件在写操作期间使用备份文件,以确保如果操作失败,它可以回滚到原始文件。备份文件与 keyring_file_data 系统变量的值相同,后缀为 .backup

    不要为多个 MySQL 实例使用相同的 keyring_file 数据文件。每个实例应具有其自己独特的数据文件。

    默认文件名为 keyring,位于特定于平台的目录中,并取决于 INSTALL_LAYOUT CMake 选项的值,如下表所示。如果您正在从源代码构建,则可以使用 INSTALL_MYSQLKEYRINGDIR CMake 选项显式指定文件的默认目录。

    INSTALL_LAYOUT 默认 keyring_file_data
    DEB, RPM, SVR4 /var/lib/mysql-keyring/keyring
    否则 CMAKE_INSTALL_PREFIX 值下的 keyring/keyring

    在插件启动时,如果分配给 keyring_file_data 的值指定一个不存在的文件,则 keyring_file 插件会尝试创建它(以及必要时的父目录)。

    如果您手动创建目录,则应具有限制模式,并且只能由用于运行 MySQL 服务器的帐户访问。例如,在 Unix 和类 Unix 系统上,要使用 /usr/local/mysql/mysql-keyring 目录,以下命令(以 root 执行)创建目录并设置其模式和所有权:

    cd /usr/local/mysql
    mkdir mysql-keyring
    chmod 750 mysql-keyring
    chown mysql mysql-keyring
    chgrp mysql mysql-keyring
    

    如果 keyring_file 插件无法创建或访问其数据文件,则会将错误消息写入错误日志。如果对 keyring_file_data 的尝试运行时赋值导致错误,则变量值保持不变。

    重要

    一旦keyring_file插件创建了其数据文件并开始使用它,重要的是不要删除该文件。例如,InnoDB使用该文件存储用于解密使用InnoDB表空间加密的数据的主密钥;请参阅第 17.13 节,“InnoDB 数据静态加密”。文件丢失会导致这些表中的数据无法访问。(可以重命名或移动文件,只要您更改keyring_file_data的值以匹配即可。)建议在创建第一个加密表之后立即创建密钥环数据文件的单独备份,并在主密钥轮换之前和之后创建备份。

  • keyring_hashicorp_auth_path

    命令行格式 --keyring-hashicorp-auth-path=value
    引入版本 8.0.18
    系统变量 keyring_hashicorp_auth_path
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认�� /v1/auth/approle/login

    在 HashiCorp Vault 服务器中启用 AppRole 认证的认证路径,供keyring_hashicorp插件使用。除非安装了该插件,否则此变量不可用。

  • keyring_hashicorp_ca_path

    命令行格式 --keyring-hashicorp-ca-path=file_name
    引入版本 8.0.18
    系统变量 keyring_hashicorp_ca_path
    范围 全局
    动态
    SET_VAR 提示适用
    类型 文件名
    默认值 空字符串

    MySQL 服务器可访问的本地文件的绝对路径名,其中包含供keyring_hashicorp插件使用的正确格式化的 TLS 证书颁发机构。除非安装了该插件,否则此变量不可用。

    如果未设置此变量,keyring_hashicorp插件将在不使用服务器证书验证的情况下打开 HTTPS 连接,并信任 HashiCorp Vault 服务器提供的任何证书。为了安全起见,必须假定 Vault 服务器不是恶意的,且不存在中间人攻击的可能性。如果这些假设是无效的,请将keyring_hashicorp_ca_path设置为受信任 CA 证书的路径。(例如,在证书和密钥准备中的说明中,这是company.crt文件。)

  • keyring_hashicorp_caching

    命令行格式 --keyring-hashicorp-caching[={OFF&#124;ON}]
    引入 8.0.18
    系统变量 keyring_hashicorp_caching
    范围 全局
    动态
    SET_VAR 提示适用
    类型 布尔值
    默认值 OFF

    是否启用keyring_hashicorp插件使用的可选内存中密钥缓存,以缓存来自 HashiCorp Vault 服务器的密钥。除非安装了该插件,否则此变量不可用。如果启用了缓存,插件将在初始化期间填充它。否则,插件仅在初始化期间填充密钥列表。

    启用缓存是一种折衷:它提高了性能,但在内存中保留了敏感密钥信息的副本,这可能不利于安全目的。

  • keyring_hashicorp_commit_auth_path

    引入 8.0.18
    系统变量 keyring_hashicorp_commit_auth_path
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    此变量与keyring_hashicorp_auth_path相关联,在keyring_hashicorp插件初始化期间从中获取其值。除非安装了该插件,否则此变量不可用。如果初始化成功,它反映了实际用于插件操作的“已提交”值。有关更多信息,请参见 keyring_hashicorp 配置。

  • keyring_hashicorp_commit_ca_path

    引入 8.0.18
    系统变量 keyring_hashicorp_commit_ca_path
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    此变量与keyring_hashicorp_ca_path相关联,在keyring_hashicorp插件初始化期间从中获取其值。除非安装了该插件,否则此变量不可用。如果初始化成功,它反映了实际用于插件操作的“已提交”值。有关更多信息,请参见 keyring_hashicorp 配置。

  • keyring_hashicorp_commit_caching

    引入版本 8.0.18
    系统变量 keyring_hashicorp_commit_caching
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    此变量与keyring_hashicorp_caching相关联,在keyring_hashicorp插件初始化期间从中获取其值。除非安装了该插件,否则此变量不可用。如果初始化成功,它反映了实际用于插件操作的“已提交”值。有关更多信息,请参见 keyring_hashicorp 配置。

  • keyring_hashicorp_commit_role_id

    引入版本 8.0.18
    系统变量 keyring_hashicorp_commit_role_id
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    此变量与keyring_hashicorp_role_id相关联,在keyring_hashicorp插件初始化期间从中获取其值。除非安装了该插件,否则此变量不可用。如果初始化成功,它反映了实际用于插件操作的“已提交”值。有关更多信息,请参见 keyring_hashicorp 配置。

  • keyring_hashicorp_commit_server_url

    引入版本 8.0.18
    系统变量 keyring_hashicorp_commit_server_url
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    此变量与keyring_hashicorp_server_url相关联,在keyring_hashicorp插件初始化期间从中获取其值。除非安装了该插件,否则此变量不可用。如果初始化成功,它反映了实际用于插件操作的“已提交”值。有关更多信息,请参见 keyring_hashicorp 配置。

  • keyring_hashicorp_commit_store_path

    引入版本 8.0.18
    系统变量 keyring_hashicorp_commit_store_path
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    此变量与keyring_hashicorp_store_path相关联,在keyring_hashicorp 插件初始化期间从中获取其值。除非安装了该插件,否则此变量不可用。如果初始化成功,它反映了实际用于插件操作的“已提交”值。有关更多信息,请参阅 keyring_hashicorp 配置。

  • keyring_hashicorp_role_id

    命令行格式 --keyring-hashicorp-role-id=value
    引入版本 8.0.18
    系统变量 keyring_hashicorp_role_id
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 空字符串

    HashiCorp Vault AppRole 认证角色 ID,供keyring_hashicorp 插件使用。除非安装了该插件,否则此变量不可用。值必须采用 UUID 格式。

    此变量为必填项。如果未指定,keyring_hashicorp 初始化将失败。

  • keyring_hashicorp_secret_id

    命令行格式 --keyring-hashicorp-secret-id=value
    引入版本 8.0.18
    系统变量 keyring_hashicorp_secret_id
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 空字符串

    HashiCorp Vault AppRole 认证秘钥 ID,供keyring_hashicorp 插件使用。除非安装了该插件,否则此变量不可用。值必须采用 UUID 格式。

    此变量为必填项。如果未指定,keyring_hashicorp 初始化将失败。

    此变量的值属于敏感信息,因此在显示时会被*字符掩盖。

  • keyring_hashicorp_server_url

    命令行格式 --keyring-hashicorp-server-url=value
    引入版本 8.0.18
    系统变量 keyring_hashicorp_server_url
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 https://127.0.0.1:8200

    HashiCorp Vault 服务器 URL,供 keyring_hashicorp ��件使用。除非安装了该插件,否则此变量不可用。值必须以 https:// 开头。

  • keyring_hashicorp_store_path

    命令行格式 --keyring-hashicorp-store-path=value
    引入版本 8.0.18
    系统变量 keyring_hashicorp_store_path
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 空字符串

    HashiCorp Vault 服务器内的存储路径,在适当提供 AppRole 凭据的情况下由 keyring_hashicorp 插件提供写入权限。除非安装了该插件,否则此变量不可用。要指定凭据,请设置 keyring_hashicorp_role_idkeyring_hashicorp_secret_id 系统变量(例如,在 keyring_hashicorp 配置 中所示)。

    此变量为必填项。如果未指定,keyring_hashicorp 初始化将失败。

  • keyring_oci_ca_certificate

    命令行格式 --keyring-oci-ca-certificate=file_name
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_ca_certificate
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串
    默认值 空字符串

    用于 Oracle Cloud Infrastructure 证书验证的 CA 证书包文件的路径名。除非安装了该插件,否则此变量不可用。

    文件包含一个或多个用于对等验证的证书。如果未指定文件,则使用系统上安装的默认 CA 包。如果值为 disabled(区分大小写),keyring_oci 将不执行证书验证。

  • keyring_oci_compartment

    命令行格式 --keyring-oci-compartment=ocid
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_compartment
    作用范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    keyring_oci 插件用作 MySQL 密钥位置的租户区段的 OCID。除非安装了该插件,否则此变量不可用。

    在使用 keyring_oci 之前,如果不存在 MySQL 区段或子区段,则必须创建一个。此区段不应包含任何保险库密钥或保险库密钥。它不应被 MySQL Keyring 以外的系统使用。

    有关管理区段和获取 OCID 的信息,请参阅管理区段

    此变量是必需的。如果未指定,keyring_oci 初始化将失败。

  • keyring_oci_encryption_endpoint

    命令行格式 --keyring-oci-encryption-endpoint=value
    引入 8.0.22
    弃用 8.0.31
    系统变量 keyring_oci_encryption_endpoint
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    Oracle Cloud Infrastructure 加密服务器的端点,keyring_oci 插件用于为新密钥生成密文。除非安装了该插件,否则此变量不可用。

    加密端点是特定于保险库的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取端点 OCID,请查看您的 keyring_oci 保险库的配置详细信息,使用管理保险库中的说明。

    此变量是必需的。如果未指定,keyring_oci 初始化将失败。

  • keyring_oci_key_file

    命令行格式 --keyring-oci-key-file=file_name
    引入 8.0.22
    弃用 8.0.31
    系统变量 keyring_oci_key_file
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    包含 keyring_oci 插件用于 Oracle Cloud Infrastructure 认证的 RSA 私钥文件的文件路径名。除非安装了该插件,否则此变量不可用。

    您还必须使用控制台上传相应的 RSA 公钥。控制台显示密钥指纹值,您可以使用它来设置keyring_oci_key_fingerprint 系统变量。

    有关生成和上传 API 密钥的信息,请参阅必需的密钥和 OCID

    此变量是强制性的。如果未指定,keyring_oci 初始化将失败。

  • keyring_oci_key_fingerprint

    命令行格式 --keyring-oci-key-fingerprint=value
    引入 8.0.22
    弃用 8.0.31
    系统变量 keyring_oci_key_fingerprint
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    RSA 私钥的指纹,keyring_oci 插件用于 Oracle Cloud Infrastructure 认证。除非安装了该插件,否则此变量不可用。

    在创建 API 密钥时获取密钥指纹,请执行此命令:

    openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c
    

    或者,从控制台获取指纹,当您上传 RSA 公钥时,控制台会自动显示指纹。

    有关获取密钥指纹的信息,请参阅必需的密钥和 OCID

    此变量是强制性的。如果未指定,keyring_oci 初始化将失败。

  • keyring_oci_management_endpoint

    命令行格式 --keyring-oci-management-endpoint=value
    引入 8.0.22
    弃用 8.0.31
    系统变量 keyring_oci_management_endpoint
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    Oracle Cloud Infrastructure 密钥管理服务器的端点,keyring_oci 插件用于列出现有密钥。除非安装了该插件,否则此变量不可用。

    密钥管理端点是特定于保险库的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取端点 OCID,请查看您的keyring_oci保险库的配置详细信息,使用管理保险库中的说明。

    此变量是强制性的。如果未指定,keyring_oci 初始化将失败。

  • keyring_oci_master_key

    命令行格式 --keyring-oci-master-key=ocid
    引入 8.0.22
    弃用 8.0.31
    系统变量 keyring_oci_master_key
    范围 全局
    动态
    SET_VAR 提示适用
    类型 字符串

    keyring_oci插件用于加密秘密的 Oracle Cloud Infrastructure 主加密密钥的 OCID。除非安装了该插件,否则此变量不可用。

    在使用keyring_oci之前,如果不存在 Oracle Cloud Infrastructure 区隔的加密密钥,则必须创建一个。为生成的密钥提供一个特定于 MySQL 的名称,并且不要将其用于其他目的。

    有关密钥创建的信息,请参阅管理密钥

    此变量是强制性的。如果未指定,keyring_oci初始化将失败。

  • keyring_oci_secrets_endpoint

    命令行格式 --keyring-oci-secrets-endpoint=value
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_secrets_endpoint
    范围 全局
    动态
    SET_VAR提示适用
    类型 字符串

    Oracle Cloud Infrastructure 秘密服务器的终端点,keyring_oci插件用于列出、创建和撤销秘密。除非安装了该插件,否则此变量不可用。

    秘密终端点是特定于保险库的,Oracle Cloud Infrastructure 在创建保险库时分配它。要获取终端点 OCID,请查看您的keyring_oci保险库的配置详细信息,使用管理保险库中的说明。

    此变量是强制性的。如果未指定,keyring_oci初始化将失败。

  • keyring_oci_tenancy

    命令行格式 --keyring-oci-tenancy=ocid
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_tenancy
    范围 全局
    动态
    SET_VAR提示适用
    类型 字符串

    keyring_oci插件用作 MySQL 区隔的 Oracle Cloud Infrastructure 租户的 OCID。除非安装了该插件,否则此变量不可用。

    在使用keyring_oci之前,如果不存在租户,则必须创建一个租户。要从控制台获取租户 OCID,请使用必需的密钥和 OCID中的说明。

    此变量是强制性的。如果未指定,keyring_oci初始化将失败。

  • keyring_oci_user

    命令行格式 --keyring-oci-user=ocid
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_user
    作用范围 全局
    动态
    SET_VAR提示适用
    类型 字符串

    keyring_oci插件用于云连接的 Oracle Cloud Infrastructure 用户的 OCID。除非安装了该插件,否则此变量不可用。

    在使用keyring_oci之前,此用户必须存在并被授予使用配置的 Oracle Cloud Infrastructure 租户、区域和 Vault 资源的访问权限。

    要从控制台获取用户 OCID,请使用必需密钥和 OCID中的说明。

    此变量是必需的。如果未指定,keyring_oci初始化将失败。

  • keyring_oci_vaults_endpoint

    命令行格式 --keyring-oci-vaults-endpoint=value
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_vaults_endpoint
    作用范围 全局
    动态
    SET_VAR提示适用
    类型 字符串

    keyring_oci插件用于获取密钥值的 Oracle Cloud Infrastructure Vaults 服务器的端点。除非安装了该插件,否则此变量不可用。

    Vault 端点是特定于 Vault 的,Oracle Cloud Infrastructure 在创建 Vault 时分配它。要获取端点 OCID,请查看您的keyring_oci Vault 的配置详细信息,使用管理 Vaults中的说明。

    此变量是必需的。如果未指定,keyring_oci初始化将失败。

  • keyring_oci_virtual_vault

    命令行格式 --keyring-oci-virtual-vault=ocid
    引入版本 8.0.22
    已弃用 8.0.31
    系统变量 keyring_oci_virtual_vault
    作用范围 全局
    动态
    SET_VAR提示适用
    类型 字符串

    Oracle Cloud Infrastructure Vault 的 OCID,keyring_oci插件用于加密操作的 Vault。除非安装了该插件,否则此变量不可用。

    在使用keyring_oci之前,如果 MySQL 区域不存在,则必须在 MySQL 区域中创建一个新的 Vault。(或者,您可以重用位于 MySQL 区域的父区域中的现有 Vault。)区域用户只能看到并使用其各自区域中的密钥。

    有关创建保险库并获取保险库 OCID 的信息,请参阅管理保险库

    该变量是强制性的。如果未指定,keyring_oci初始化将失败。

  • keyring_okv_conf_dir

    命令行格式 --keyring-okv-conf-dir=dir_name
    系统变量 keyring_okv_conf_dir
    范围 全局
    动态
    SET_VAR提示适用
    类型 目录名称
    默认值 空字符串

    存储keyring_okv插件使用的配置信息的目录路径。除非安装了该插件,否则此变量不可用。该位置应该是仅供keyring_okv插件使用的目录。例如,不要将目录放在数据目录下。

    默认keyring_okv_conf_dir值为空。为了让keyring_okv插件能够访问 Oracle Key Vault,该值必须设置为包含 Oracle Key Vault 配置和 SSL 材料的目录。有关设置此目录的说明,请参见第 8.4.4.8 节,“使用 keyring_okv KMIP 插件”。

    该目录应具有严格的模式,并且只能由用于运行 MySQL 服务器的帐户访问。例如,在 Unix 和类 Unix 系统上,要使用/usr/local/mysql/mysql-keyring-okv目录,以下命令(以root身份执行)创建目录并设置其模式和所有权:

    cd /usr/local/mysql
    mkdir mysql-keyring-okv
    chmod 750 mysql-keyring-okv
    chown mysql mysql-keyring-okv
    chgrp mysql mysql-keyring-okv
    

    如果分配给keyring_okv_conf_dir的值指定了一个不存在的目录,或者不包含启用与 Oracle Key Vault 建立连接的配置信息,keyring_okv会将错误消息写入错误日志。如果对keyring_okv_conf_dir的尝试运行时赋值导致错误,则变量值和 keyring 操作保持不变。

  • keyring_operations

    系统变量 keyring_operations
    范围 全局
    动态
    SET_VAR提示适用
    类型 布尔值
    默认值 ON

    是否启用了钥匙环操作。此变量在钥匙迁移操作期间使用。参见第 8.4.4.14 节,“在钥匙环密钥存储之间迁移密钥”。修改此变量所需的特权是ENCRYPTION_KEY_ADMIN,另外还需要SYSTEM_VARIABLES_ADMIN或已弃用的SUPER特权。

8.4.5 MySQL Enterprise Audit

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

8.4.5.1 MySQL Enterprise Audit 元素

8.4.5.2 安装或卸载 MySQL Enterprise Audit

8.4.5.3 MySQL Enterprise Audit 安全考虑

8.4.5.4 审计日志文件格式

8.4.5.5 配置审计日志记录特性

8.4.5.6 读取审计日志文件

8.4.5.7 审计日志过滤

8.4.5.8 编写审计日志过滤器定义

8.4.5.9 禁用审计日志记录

8.4.5.10 传统模式审计日志过滤

8.4.5.11 审计日志参考

8.4.5.12 审计日志限制

注意

MySQL Enterprise Audit 是包含在 MySQL Enterprise Edition 中的扩展,这是一个商业产品。要了解更多关于商业产品的信息,请参阅 www.mysql.com/products/

MySQL Enterprise Edition 包括 MySQL Enterprise Audit,使用名为 audit_log 的服务器插件实现。MySQL Enterprise Audit 使用开放的 MySQL Audit API,以启用对特定 MySQL 服务器上执行的连接和查询活动的标准、基于策略的监视、记录和阻止。设计符合 Oracle 审计规范,MySQL Enterprise Audit 为受内部和外部监管指导的应用程序提供了一个开箱即用、易于使用的审计和合规解决方案。

安装后,审计插件使 MySQL 服务器能够生成一个包含服务器活动审计记录的日志文件。日志内容包括客户端连接和断开的时间,以及连接时执行的操作,例如访问哪些数据库和表。从 MySQL 8.0.30 开始,您可以添加每个查询的时间和大小的统计信息以检测异常值。

默认情况下,MySQL Enterprise Audit 使用 mysql 系统数据库中的表来持久存储过滤器和用户帐户数据。要使用不同的数据库,请在服务器启动时设置 audit_log_database 系统变量(从 MySQL 8.0.33 开始)。

安装审计插件后(请参阅 第 8.4.5.2 节,“安装或卸载 MySQL Enterprise Audit”),它会写入一个审计日志文件。默认情况下,文件名为 audit.log,位于服务器数据目录中。要更改文件名,请在服务器启动时设置 audit_log_file 系统变量。

默认情况下,审计日志文件内容以新式 XML 格式编写,不进行压缩或加密。要选择文件格式,请在服务器启动时设置audit_log_format系统变量。有关文件格式和内容的详细信息,请参见 Section 8.4.5.4, “Audit Log File Formats”。

有关控制日志记录方式的更多信息,包括审计日志文件命名和格式选择,请参见 Section 8.4.5.5, “配置审计日志记录特性”。要执行审计事件的过滤,请参见 Section 8.4.5.7, “审计日志过滤”。有关配置审计日志插件所使用的参数的描述,请参见审计日志选项和变量。

如果启用了审计日志插件,则性能模式(参见 Chapter 29, MySQL 性能模式)具有相应的仪器。要识别相关仪器,请使用以下查询:

SELECT NAME FROM performance_schema.setup_instruments
WHERE NAME LIKE '%/alog/%';

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

8.4.5.1 MySQL 企业审计的元素

MySQL 企业审计基于审计日志插件和相关元素:

  • 一个名为audit_log的服务器端插件检查可审计事件,并确定是否将其写入审计日志。

  • 一组函数使得可以操作控制日志行为的过滤定义、加密密码和日志文件读取。

  • mysql系统数据库中的表提供过滤和用户账户数据的持久存储,除非您在服务器启动时设置audit_log_database系统变量以指定不同的数据库。

  • 系统变量使审计日志配置生效,状态变量提供运行时操作信息。

  • AUDIT_ADMIN权限使用户能够管理审计日志,并且(从 MySQL 8.0.28 开始)AUDIT_ABORT_EXEMPT权限使系统用户能够执行否则会被审计日志过滤器中的“中止”项阻止的查询。

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

8.4.5.2 安装或卸载 MySQL Enterprise Audit

本节描述了如何安装或卸载 MySQL Enterprise Audit,该功能使用审计日志插件和相关元素实现,详见第 8.4.5.1 节,“MySQL Enterprise Audit 的元素”。有关安装插件的一般信息,请参见第 7.6.1 节,“安装和卸载插件”。

在升级 MySQL 安装时,插件升级不是自动的,一些插件可加载函数必须手动加载(参见安装可加载函数)。或者,您可以在升级 MySQL 后重新安装插件以加载新函数。

重要

在按照说明操作之前,请阅读本节的全部内容。根据您的环境,过程的某些部分可能有所不同。

注意

如果安装了audit_log插件,即使禁用了,也会带来一些最小的开销。为了避免这种开销,请不要安装 MySQL Enterprise Audit,除非你打算使用它。

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

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

  • audit_log_filter_win_install.sql

  • audit_log_filter_linux_install.sql

按照以下方式运行脚本。这里的示例使用 Linux 安装脚本。请根据您的系统进行适当的替换。

在 MySQL 8.0.34 之前:

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

MySQL 8.0.34 及更高版本:

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

从 MySQL 8.0.34 开始,可以在运行安装脚本时选择用于存储 JSON 过滤表的数据库。首先创建数据库;其名称不应超过 64 个字符。例如:

mysql> CREATE DATABASE IF NOT EXISTS *database-name*;

接下来,使用替代数据库名称运行脚本。

$> mysql -u root -p -D *database-name* < audit_log_filter_linux_install.sql
Enter password: *(enter root password here)*

注意

一些 MySQL 版本已经对 MySQL Enterprise Audit 表的结构进行了更改。为了确保您的表在从 MySQL 8.0 的早期版本升级时是最新的,请执行 MySQL 升级过程,确保使用强制更新选项(参见第三章,“升级 MySQL”)。如果您希望仅对 MySQL Enterprise Audit 表运行更新语句,请参阅以下讨论。

截至 MySQL 8.0.12 版本,对于新的 MySQL 安装,MySQL 企业审计使用的audit_log_user表中的USERHOST列的定义更好地对应于mysql.user系统表中UserHost列的定义。对于已安装 MySQL 企业审计的升级安装,建议您按照以下方式修改表定义:

ALTER TABLE mysql.audit_log_user
  DROP FOREIGN KEY audit_log_user_ibfk_1;
ALTER TABLE mysql.audit_log_filter
  CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_ci;
ALTER TABLE mysql.audit_log_user
  CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_ci;
ALTER TABLE mysql.audit_log_user
  MODIFY COLUMN USER VARCHAR(32);
ALTER TABLE mysql.audit_log_user
  ADD FOREIGN KEY (FILTERNAME) REFERENCES mysql.audit_log_filter(NAME);

注意

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

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

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

要验证插件安装,请检查信息模式PLUGINS表,或使用SHOW PLUGINS语句(参见 Section 7.6.2, “Obtaining Server Plugin Information”)。例如:

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
       FROM INFORMATION_SCHEMA.PLUGINS
       WHERE PLUGIN_NAME LIKE 'audit%';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| audit_log   | ACTIVE        |
+-------------+---------------+

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

安装了 MySQL 企业审计后,您可以在后续服务器启动时使用--audit-log选项来控制audit_log插件的激活。例如,为了防止插件在运行时被移除,请使用此选项:

[mysqld]
audit-log=FORCE_PLUS_PERMANENT

如果希望防止服务器在没有审计插件的情况下运行,请使用--audit-log并将值设置为FORCEFORCE_PLUS_PERMANENT,以强制服务器启动失败,如果插件初始化失败。

重要

默认情况下,基于规则的审计日志过滤不会记录任何用户的可审计事件。这与传统审计日志行为不同,传统审计日志会记录所有用户的所有可审计事件(参见 Section 8.4.5.10, “Legacy Mode Audit Log Filtering”)。如果希望通过基于规则的过滤产生记录所有内容的行为,请创建一个简单的过滤器以启用日志记录,并将其分配给默认帐户:

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

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

当按照上述描述安装后,MySQL 企业审计将一直保留安装状态,直到被卸载。要在 MySQL 8.0.35 及更高版本中移除它,请运行位于 MySQL 安装的share目录中的卸载脚本。这里的示例指定了默认系统数据库mysql,请根据您的系统进行适当的替换。

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

如果脚本不可用,请执行以下语句手动移除表、插件和函数。

DROP TABLE IF EXISTS mysql.audit_log_user;
DROP TABLE IF EXISTS mysql.audit_log_filter;
UNINSTALL PLUGIN audit_log;
DROP FUNCTION audit_log_filter_set_filter;
DROP FUNCTION audit_log_filter_remove_filter;
DROP FUNCTION audit_log_filter_set_user;
DROP FUNCTION audit_log_filter_remove_user;
DROP FUNCTION audit_log_filter_flush;
DROP FUNCTION audit_log_encryption_password_get;
DROP FUNCTION audit_log_encryption_password_set;
DROP FUNCTION audit_log_read;
DROP FUNCTION audit_log_read_bookmark;
DROP FUNCTION audit_log_rotate;

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

8.4.5.3 MySQL 企业审计安全考虑

默认情况下,审计日志插件生成的审计日志文件的内容未加密,可能包含敏感信息,如 SQL 语句的文本。出于安全考虑,审计日志文件应写入仅对 MySQL 服务器和有合法查看日志原因的用户可访问的目录。默认文件名为audit.log,位于数据目录中。可以通过在服务器启动时设置audit_log_file系统变量来更改此设置。由于日志轮换,可能存在其他审计日志文件。

为了增强安全性,启用审计日志文件加密。参见加密审计日志文件。

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

8.4.5.4 审计日志文件格式

当发生可审计事件时,MySQL 服务器调用审计日志插件将审计记录写入其日志文件。通常,在插件启动后写入的第一条审计记录包含服务器描述和启动选项。随后的元素代表诸如客户端连接和断开事件、执行的 SQL 语句等事件。只记录顶层语句,不记录触发器或存储过程等存储程序中的语句。例如,LOAD DATA 中引用的文件内容不会被记录。

要选择审计日志插件用于编写其日志文件的日志格式,请在服务器启动时设置 audit_log_format 系统变量。这些格式可用:

  • 新式 XML 格式(audit_log_format=NEW):一种与 Oracle Audit Vault 更兼容的 XML 格式,MySQL 8.0 默认使用新式 XML 格式。

  • 旧式 XML 格式(audit_log_format=OLD):默认在旧版 MySQL 系列中使用的原始审计日志格式。

  • JSON 格式(audit_log_format=JSON):将审计日志写入 JSON 数组。只有此格式支持从 MySQL 8.0.30 开始提供的可选查询时间和大小统计信息。

默认情况下,审计日志文件内容以新式 XML 格式编写,不进行压缩或加密。

如果更改 audit_log_format,建议同时更改 audit_log_file。例如,如果将 audit_log_format 设置为 JSON,则将 audit_log_file 设置为 audit.json。否则,新的日志文件将具有不同的格式,但它们都将具有相同的基本名称,没有任何指示格式何时更改的内容。

  • 新式 XML 审计日志文件格式

  • 旧式 XML 审计日志文件格式

  • JSON 审计日志文件格式

新式 XML 审计日志文件格式

这是一个以新式 XML 格式(audit_log_format=NEW)编写的示例日志文件,为了可读性稍作重新格式化:

<?xml version="1.0" encoding="utf-8"?>
<AUDIT>
 <AUDIT_RECORD>
  <TIMESTAMP>2019-10-03T14:06:33 UTC</TIMESTAMP>
  <RECORD_ID>1_2019-10-03T14:06:33</RECORD_ID>
  <NAME>Audit</NAME>
  <SERVER_ID>1</SERVER_ID>
  <VERSION>1</VERSION>
  <STARTUP_OPTIONS>/usr/local/mysql/bin/mysqld
    --socket=/usr/local/mysql/mysql.sock
    --port=3306</STARTUP_OPTIONS>
  <OS_VERSION>i686-Linux</OS_VERSION>
  <MYSQL_VERSION>5.7.21-log</MYSQL_VERSION>
 </AUDIT_RECORD>
 <AUDIT_RECORD>
  <TIMESTAMP>2019-10-03T14:09:38 UTC</TIMESTAMP>
  <RECORD_ID>2_2019-10-03T14:06:33</RECORD_ID>
  <NAME>Connect</NAME>
  <CONNECTION_ID>5</CONNECTION_ID>
  <STATUS>0</STATUS>
  <STATUS_CODE>0</STATUS_CODE>
  <USER>root</USER>
  <OS_LOGIN/>
  <HOST>localhost</HOST>
  <IP>127.0.0.1</IP>
  <COMMAND_CLASS>connect</COMMAND_CLASS>
  <CONNECTION_TYPE>SSL/TLS</CONNECTION_TYPE>
  <CONNECTION_ATTRIBUTES>
   <ATTRIBUTE>
    <NAME>_pid</NAME>
    <VALUE>42794</VALUE>
   </ATTRIBUTE>
   ...
   <ATTRIBUTE>
    <NAME>program_name</NAME>
    <VALUE>mysqladmin</VALUE>
   </ATTRIBUTE>
  </CONNECTION_ATTRIBUTES>
  <PRIV_USER>root</PRIV_USER>
  <PROXY_USER/>
  <DB>test</DB>
 </AUDIT_RECORD>

...

 <AUDIT_RECORD>
  <TIMESTAMP>2019-10-03T14:09:38 UTC</TIMESTAMP>
  <RECORD_ID>6_2019-10-03T14:06:33</RECORD_ID>
  <NAME>Query</NAME>
  <CONNECTION_ID>5</CONNECTION_ID>
  <STATUS>0</STATUS>
  <STATUS_CODE>0</STATUS_CODE>
  <USER>root[root] @ localhost [127.0.0.1]</USER>
  <OS_LOGIN/>
  <HOST>localhost</HOST>
  <IP>127.0.0.1</IP>
  <COMMAND_CLASS>drop_table</COMMAND_CLASS>
  <SQLTEXT>DROP TABLE IF EXISTS t</SQLTEXT>
 </AUDIT_RECORD>

...

 <AUDIT_RECORD>
  <TIMESTAMP>2019-10-03T14:09:39 UTC</TIMESTAMP>
  <RECORD_ID>8_2019-10-03T14:06:33</RECORD_ID>
  <NAME>Quit</NAME>
  <CONNECTION_ID>5</CONNECTION_ID>
  <STATUS>0</STATUS>
  <STATUS_CODE>0</STATUS_CODE>
  <USER>root</USER>
  <OS_LOGIN/>
  <HOST>localhost</HOST>
  <IP>127.0.0.1</IP>
  <COMMAND_CLASS>connect</COMMAND_CLASS>
  <CONNECTION_TYPE>SSL/TLS</CONNECTION_TYPE>
 </AUDIT_RECORD>

...

 <AUDIT_RECORD>
  <TIMESTAMP>2019-10-03T14:09:43 UTC</TIMESTAMP>
  <RECORD_ID>11_2019-10-03T14:06:33</RECORD_ID>
  <NAME>Quit</NAME>
  <CONNECTION_ID>6</CONNECTION_ID>
  <STATUS>0</STATUS>
  <STATUS_CODE>0</STATUS_CODE>
  <USER>root</USER>
  <OS_LOGIN/>
  <HOST>localhost</HOST>
  <IP>127.0.0.1</IP>
  <COMMAND_CLASS>connect</COMMAND_CLASS>
  <CONNECTION_TYPE>SSL/TLS</CONNECTION_TYPE>
 </AUDIT_RECORD>
 <AUDIT_RECORD>
  <TIMESTAMP>2019-10-03T14:09:45 UTC</TIMESTAMP>
  <RECORD_ID>12_2019-10-03T14:06:33</RECORD_ID>
  <NAME>NoAudit</NAME>
  <SERVER_ID>1</SERVER_ID>
 </AUDIT_RECORD>
</AUDIT>

审计日志文件以 XML 格式编写,使用 UTF-8(每个字符最多 4 个字节)。根元素是<AUDIT>。根元素包含<AUDIT_RECORD>元素,每个元素提供有关审计事件的信息。当审计日志插件开始写入新的日志文件时,它会写入 XML 声明和打开的<AUDIT>根元素标记。当插件关闭日志文件时,它会写入关闭的</AUDIT>根元素标记。在文件打开时不存在关闭标记。

<AUDIT_RECORD>元素内的元素具有以下特征:

  • 一些元素出现在每个<AUDIT_RECORD>元素中。其他是可选的,可能会根据审计记录类型出现。

  • <AUDIT_RECORD>元素内元素的顺序不保证。

  • 元素值不是固定长度。长值可能会被截断,如后面给出的元素描述中所示。

  • <>"&字符分别编码为&lt;&gt;&quot;&amp;。NUL 字节(U+00)编码为?字符。

  • 不是 XML 字符的字符使用数字字符引用进行编码。有效的 XML 字符包括:

    #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
    

每个<AUDIT_RECORD>元素中以下元素是必需的:

  • <NAME>

    代表生成审计事件的指令类型的字符串,例如服务器从客户端接收的命令。

    示例:

    <NAME>Query</NAME>
    

    一些常见的<NAME>值:

    Audit    When auditing starts, which may be server startup time
    Connect  When a client connects, also known as logging in
    Query    An SQL statement (executed directly)
    Prepare  Preparation of an SQL statement; usually followed by Execute
    Execute  Execution of an SQL statement; usually follows Prepare
    Shutdown Server shutdown
    Quit     When a client disconnects
    NoAudit  Auditing has been turned off
    

    可能的取值为AuditBinlog DumpChange userClose stmtConnect OutConnectCreate DBDaemonDebugDelayed insertDrop DBExecuteFetchField ListInit DBKillLong DataNoAuditPingPrepareProcesslistQueryQuitRefreshRegister SlaveReset stmtSet optionShutdownSleepStatisticsTable DumpTableDeleteTableInsertTableReadTableUpdateTime

    这些值中的许多对应于my_command.h头文件中列出的COM_*xxx*命令值。例如,Create DBChange user分别对应于COM_CREATE_DBCOM_CHANGE_USER

    具有Table*XXX*<NAME>值的事件伴随着Query事件。例如,以下语句生成一个Query事件,两个TableRead事件和一个TableInsert事件:

    INSERT INTO t3 SELECT t1.* FROM t1 JOIN t2;
    

    每个Table*XXX*事件包含<TABLE><DB>元素,用于标识事件所涉及的表和包含表的数据库。

  • <RECORD_ID>

    审计记录的唯一标识符。该值由序列号和时间戳组成,格式为*SEQ_TIMESTAMP*。当审计日志插件打开审计日志文件时,它将序列号初始化为审计日志文件的大小,然后为记录的每个记录递增序列号。时间戳是*YYYY-MM-DD*T*hh:mm:ss*格式的 UTC 值,指示审计日志插件打开文件的日期和时间。

    示例:

    <RECORD_ID>12_2019-10-03T14:06:33</RECORD_ID>
    
  • <TIMESTAMP>

    代表以*YYYY-MM-DD*T*hh:mm:ss* UTC格式表示的 UTC 值的字符串,指示生成审计事件的日期和时间。例如,对于从客户端接收的 SQL 语句执行对应的事件,其<时间戳>值发生在语句完成后,而不是接收时。

    示例:

    <TIMESTAMP>2019-10-03T14:09:45 UTC</TIMESTAMP>
    

下列元素在<审计记录>元素中是可选的。其中许多元素仅在特定<名称>元素值出现时才会出现。

  • <COMMAND_CLASS>

    指示执行的操作类型的字符串。

    示例:

    <COMMAND_CLASS>drop_table</COMMAND_CLASS>
    

    这些值对应于statement/sql/*xxx*命令计数器。例如,xxx分别是drop_tableselect,用于DROP TABLESELECT语句。以下语句显示可能的名称:

    SELECT REPLACE(EVENT_NAME, 'statement/sql/', '') AS name
    FROM performance_schema.events_statements_summary_global_by_event_name
    WHERE EVENT_NAME LIKE 'statement/sql/%'
    ORDER BY name;
    
  • <连接属性>

    从 MySQL 8.0.19 开始,具有connect值的<COMMAND_CLASS>事件可能包含一个<连接属性>元素,以显示客户端在连接时传递的连接属性。 (有关这些属性的信息,这些属性也在性能模式表中公开,请参见第 29.12.9 节,“性能模式连接属性表”.)

    <连接属性>元素包含一个<属性>元素,每个元素包含<名称><值>元素,分别指示属性名称和值。

    示例:

    <CONNECTION_ATTRIBUTES>
     <ATTRIBUTE>
      <NAME>_pid</NAME>
      <VALUE>42794</VALUE>
     </ATTRIBUTE>
     <ATTRIBUTE>
      <NAME>_os</NAME>
      <VALUE>macos0.14</VALUE>
     </ATTRIBUTE>
     <ATTRIBUTE>
      <NAME>_platform</NAME>
      <VALUE>x86_64</VALUE>
     </ATTRIBUTE>
     <ATTRIBUTE>
      <NAME>_client_version</NAME>
      <VALUE>8.0.19</VALUE>
     </ATTRIBUTE>
     <ATTRIBUTE>
      <NAME>_client_name</NAME>
      <VALUE>libmysql</VALUE>
     </ATTRIBUTE>
     <ATTRIBUTE>
      <NAME>program_name</NAME>
      <VALUE>mysqladmin</VALUE>
     </ATTRIBUTE>
    </CONNECTION_ATTRIBUTES>
    

    如果事件中没有连接属性,则不记录任何属性,也不会出现<连接属性>元素。这可能发生在连接尝试失败,客户端未传递任何属性,或者连接在内部发生,例如在服务器启动期间或由插件发起时。

  • <连接标识符>

    代表客户端连接标识符的无符号整数。这与会话中由CONNECTION_ID()函数返回的值相同。

    示例:

    <CONNECTION_ID>127</CONNECTION_ID>
    
  • <连接类型>

    与服务器的连接的安全状态。允许的值为TCP/IP(未加密建立的 TCP/IP 连接),SSL/TLS(加密建立的 TCP/IP 连接),Socket(Unix 套接字文件连接),Named Pipe(Windows 命名管道连接)和Shared Memory(Windows 共享内存连接)。

    示例:

    <CONNECTION_TYPE>SSL/TLS</CONNECTION_TYPE>
    
  • <数据库>

    代表数据库名称的字符串。

    示例:

    <DB>test</DB>
    

    对于连接事件,此元素指示默认数据库;如果没有默认数据库,则该元素为空。对于表访问事件,该元素指示所访问表所属的数据库。

  • <主机>

    代表客户端主机名的字符串。

    示例:

    <HOST>localhost</HOST>
    
  • <IP>

    代表客户端 IP 地址的字符串。

    示例:

    <IP>127.0.0.1</IP>
    
  • <MYSQL 版本>

    一个表示 MySQL 服务器版本的字符串。这与VERSION()函数或version系统变量的值相同。

    示例:

    <MYSQL_VERSION>5.7.21-log</MYSQL_VERSION>
    
  • <操作系统登录>

    一个表示在认证过程中使用的外部用户名称的字符串,由用于认证客户端的插件设置。对于本机(内置)MySQL 认证,或者如果插件未设置该值,则此元素为空。该值与external_user系统变量的值相同(参见第 8.2.19 节,“代理用户”)。

    示例:

    <OS_LOGIN>jeffrey</OS_LOGIN>
    
  • <操作系统版本>

    一个表示构建或运行服务器的操作系统的字符串。

    示例:

    <OS_VERSION>x86_64-Linux</OS_VERSION>
    
  • <特权用户>

    一个表示服务器对客户端进行身份验证的用户的字符串。这是服务器用于权限检查的用户名,可能与 <用户> 值不同。

    示例:

    <PRIV_USER>jeffrey</PRIV_USER>
    
  • <代理用户>

    一个表示代理用户的字符串(参见第 8.2.19 节,“代理用户”)。如果未启用用户代理,则值为空。

    示例:

    <PROXY_USER>developer</PROXY_USER>
    
  • <服务器 ID>

    一个表示服务器 ID 的无符号整数。这与server_id系统变量的值相同。

    示例:

    <SERVER_ID>1</SERVER_ID>
    
  • <SQL 文本>

    一个表示 SQL 语句文本的字符串。该值可以为空。长值可能会被截断。该字符串与审计日志文件本身一样,使用 UTF-8 编写(每个字符最多 4 个字节),因此该值可能是转换的结果。例如,原始语句可能已从客户端作为 SJIS 字符串接收。

    示例:

    <SQLTEXT>DELETE FROM t1</SQLTEXT>
    
  • <启动选项>

    一个表示在启动 MySQL 服务器时在命令行或选项文件中给定的选项的字符串。第一个选项是服务器可执行文件的路径。

    示例:

    <STARTUP_OPTIONS>/usr/local/mysql/bin/mysqld
      --port=3306 --log_output=FILE</STARTUP_OPTIONS>
    
  • <状态>

    一个表示命令状态的无符号整数:成功为 0,发生错误为非零值。这与mysql_errno() C API 函数的值相同。有关 <状态码><状态> 之间的区别的信息,请参阅描述。

    审计日志不包含 SQLSTATE 值或错误消息。要查看错误代码、SQLSTATE 值和消息之间的关联,请参阅服务器错误消息参考。

    警告未记录。

    示例:

    <STATUS>1051</STATUS>
    
  • <状态码>

    一个表示命令状态的无符号整数:成功为 0,发生错误为 1。

    STATUS_CODE 值与 STATUS 值不同:STATUS_CODE 成功时为 0,错误时为 1,这与 Audit Vault 的 EZ_collector 消费者兼容。STATUSmysql_errno() C API 函数的值。成功时为 0,错误时为非零,因此错误不一定为 1。

    例子:

    <STATUS_CODE>0</STATUS_CODE>
    
  • <TABLE>

    代表表名的字符串。

    例子:

    <TABLE>t3</TABLE>
    
  • <USER>

    代表客户端发送的用户名的字符串。这可能与 <PRIV_USER> 值不同。

    例子:

    <USER>root[root] @ localhost [127.0.0.1]</USER>
    
  • <VERSION>

    代表审计日志文件格式版本的无符号整数。

    例子:

    <VERSION>1</VERSION>
    
旧式 XML 审计日志文件格式

这是一个以旧式 XML 格式(audit_log_format=OLD)稍作调整以提高可读性的示例日志文件:

<?xml version="1.0" encoding="utf-8"?>
<AUDIT>
  <AUDIT_RECORD
    TIMESTAMP="2019-10-03T14:25:00 UTC"
    RECORD_ID="1_2019-10-03T14:25:00"
    NAME="Audit"
    SERVER_ID="1"
    VERSION="1"
    STARTUP_OPTIONS="--port=3306"
    OS_VERSION="i686-Linux"
    MYSQL_VERSION="5.7.21-log"/>
  <AUDIT_RECORD
    TIMESTAMP="2019-10-03T14:25:24 UTC"
    RECORD_ID="2_2019-10-03T14:25:00"
    NAME="Connect"
    CONNECTION_ID="4"
    STATUS="0"
    STATUS_CODE="0"
    USER="root"
    OS_LOGIN=""
    HOST="localhost"
    IP="127.0.0.1"
    COMMAND_CLASS="connect"
    CONNECTION_TYPE="SSL/TLS"
    PRIV_USER="root"
    PROXY_USER=""
    DB="test"/>

...

  <AUDIT_RECORD
    TIMESTAMP="2019-10-03T14:25:24 UTC"
    RECORD_ID="6_2019-10-03T14:25:00"
    NAME="Query"
    CONNECTION_ID="4"
    STATUS="0"
    STATUS_CODE="0"
    USER="root[root] @ localhost [127.0.0.1]"
    OS_LOGIN=""
    HOST="localhost"
    IP="127.0.0.1"
    COMMAND_CLASS="drop_table"
    SQLTEXT="DROP TABLE IF EXISTS t"/>

...

  <AUDIT_RECORD
    TIMESTAMP="2019-10-03T14:25:24 UTC"
    RECORD_ID="8_2019-10-03T14:25:00"
    NAME="Quit"
    CONNECTION_ID="4"
    STATUS="0"
    STATUS_CODE="0"
    USER="root"
    OS_LOGIN=""
    HOST="localhost"
    IP="127.0.0.1"
    COMMAND_CLASS="connect"
    CONNECTION_TYPE="SSL/TLS"/>
  <AUDIT_RECORD
    TIMESTAMP="2019-10-03T14:25:32 UTC"
    RECORD_ID="12_2019-10-03T14:25:00"
    NAME="NoAudit"
    SERVER_ID="1"/>
</AUDIT>

审计日志文件以 XML 格式编写,使用 UTF-8(每个字符最多 4 个字节)。根元素是 <AUDIT>。根元素包含 <AUDIT_RECORD> 元素,每个元素提供有关审计事件的信息。当审计日志插件开始写入新日志文件时,它会写入 XML 声明和打开 <AUDIT> 根元素标记。当插件关闭日志文件时,它会写入关闭 </AUDIT> 根元素标记。在文件打开时不存在关闭标记。

<AUDIT_RECORD> 元素的属性具有以下特征:

  • 一些属性��现在每个 <AUDIT_RECORD> 元素中。其他属性是可选的,可能会根据审计记录类型而出现。

  • <AUDIT_RECORD> 元素内属性的顺序不保证。

  • 属性值不是固定长度。长值可能会根据稍后给出的属性描述而被截断。

  • <>"& 字符分别编码为 &lt;&gt;&quot;&amp;。NUL 字节(U+00)编码为 ? 字符。

  • 不是有效 XML 字符的字符使用数字字符引用进行编码。有效的 XML 字符包括:

    #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
    

每个 <AUDIT_RECORD> 元素中以下属性是必需的:

  • NAME

    代表生成审计事件的指令类型的字符串,例如服务器从客户端接收的命令。

    例子:NAME="Query"

    一些常见的 NAME 值:

    Audit    When auditing starts, which may be server startup time
    Connect  When a client connects, also known as logging in
    Query    An SQL statement (executed directly)
    Prepare  Preparation of an SQL statement; usually followed by Execute
    Execute  Execution of an SQL statement; usually follows Prepare
    Shutdown Server shutdown
    Quit     When a client disconnects
    NoAudit  Auditing has been turned off
    

    可能的值为 AuditBinlog DumpChange userClose stmtConnect OutConnectCreate DBDaemonDebugDelayed insertDrop DBExecuteFetchField ListInit DBKillLong DataNoAuditPingPrepareProcesslistQueryQuitRefreshRegister SlaveReset stmtSet optionShutdownSleepStatisticsTable DumpTableDeleteTableInsertTableReadTableUpdateTime

    许多这些值对应于 my_command.h 头文件中列出的 COM_*xxx* 命令值。例如,"Create DB""Change user" 分别对应于 COM_CREATE_DBCOM_CHANGE_USER

    具有NAME值为Table*XXX*的事件伴随着Query事件。例如,以下语句生成一个Query事件,两个TableRead事件和一个TableInsert事件:

    INSERT INTO t3 SELECT t1.* FROM t1 JOIN t2;
    

    每个Table*XXX*事件都有TABLEDB属性,用于标识事件所涉及的表和包含该表的数据库。

    旧式 XML 审计日志格式的Connect事件不包括连接属性。

  • RECORD_ID

    审计记录的唯一标识符。该值由序列号和时间戳组成,格式为*SEQ_TIMESTAMP*。当审计日志插件打开审计日志文件时,它将序列号初始化为审计日志文件的大小,然后为每个记录递增 1。时间戳是以*YYYY-MM-DD*T*hh:mm:ss*格式的 UTC 值,指示审计日志插件打开文件的日期和时间��

    示例: RECORD_ID="12_2019-10-03T14:25:00"

  • TIMESTAMP

    代表以*YYYY-MM-DD*T*hh:mm:ss* UTC格式的 UTC 值的字符串,指示生成审计事件的日期和时间。例如,对于从客户端接收的 SQL 语句执行对应的事件,TIMESTAMP值发生在语句完成之后,而不是接收时。

    示例: TIMESTAMP="2019-10-03T14:25:32 UTC"

<AUDIT_RECORD>元素中以下属性是可选的。其中许多属性仅在具有特定NAME属性值的元素中出现。

  • COMMAND_CLASS

    表示执行的操作类型的字符串。

    示例: COMMAND_CLASS="drop_table"

    这些值对应于statement/sql/*xxx*命令计数器。例如,xxx分别为drop_tableselect,用于DROP TABLESELECT语句。以下语句显示可能的名称:

    SELECT REPLACE(EVENT_NAME, 'statement/sql/', '') AS name
    FROM performance_schema.events_statements_summary_global_by_event_name
    WHERE EVENT_NAME LIKE 'statement/sql/%'
    ORDER BY name;
    
  • CONNECTION_ID

    代表客户端连接标识符的无符号整数。这与会话中CONNECTION_ID()函数返回的值相同。

    示例: CONNECTION_ID="127"

  • CONNECTION_TYPE

    与服务器的连接的安全状态。允许的值为TCP/IP(未加密的 TCP/IP 连接建立),SSL/TLS(已加密的 TCP/IP 连接建立),Socket(Unix 套接字文件连接),Named Pipe(Windows 命名管道连接)和Shared Memory(Windows 共享内存连接)。

    示例: CONNECTION_TYPE="SSL/TLS"

  • DB

    代表数据库名称的字符串。

    示例: DB="test"

    对于连接事件,此属性指示默认数据库;如果没有默认数据库,则该属性为空。对于表访问事件,该属性指示访问表所属的数据库。

  • HOST

    代表客户端主机名的字符串。

    示例: HOST="localhost"

  • IP

    代表客户端 IP 地址的字符串。

    示例: IP="127.0.0.1"

  • MYSQL_VERSION

    代表 MySQL 服务器版本的字符串。这与VERSION()函数或version系统变量的值相同。

    示例:MYSQL_VERSION="5.7.21-log"

  • OS_LOGIN

    代表在认证过程中使用的外部用户名称的字符串,由用于认证客户端的插件设置。对于本地(内置)MySQL 认证,或者如果插件未设置该值,则此属性为空。该值与external_user系统变量的值相同(参见第 8.2.19 节,“代理用户”)。

    示例:OS_LOGIN="jeffrey"

  • OS_VERSION

    代表构建或运行服务器的操作系统的字符串。

    示例:OS_VERSION="x86_64-Linux"

  • PRIV_USER

    代表服务器对客户端进行身份验证的用户的字符串。这是服务器用于特权检查的用户名,可能与USER值不同。

    示例:PRIV_USER="jeffrey"

  • PROXY_USER

    代表代理用户的字符串(参见第 8.2.19 节,“代理用户”)。如果未启用用户代理,则值为空。

    示例:PROXY_USER="developer"

  • SERVER_ID

    代表服务器 ID 的无符号整数。这与server_id系统变量的值相同。

    示例:SERVER_ID="1"

  • SQLTEXT

    代表 SQL 语句的文本的字符串。该值可以为空。长值可能会被截断。该字符串与审计日志文件本身一样,使用 UTF-8 编写(每个字符最多 4 个字节),因此该值可能是转换的结果。例如,原始语句可能已从客户端接收为 SJIS 字符串。

    示例:SQLTEXT="DELETE FROM t1"

  • STARTUP_OPTIONS

    代表 MySQL 服务器启动时在命令行或选项文件中给定的选项的字符串。

    示例:STARTUP_OPTIONS="--port=3306 --log_output=FILE"

  • STATUS

    代表命令状态的无符号整数:成功为 0,发生错误为非零。这与mysql_errno() C API 函数的值相同。有关其与STATUS的区别的信息,请参阅STATUS_CODE的描述。

    审计日志不包含 SQLSTATE 值或错误消息。要查看错误代码、SQLSTATE 值和消息之间的关联,请参阅服务器错误消息参考。

    警告不会被记录。

    示例:STATUS="1051"

  • STATUS_CODE

    代表命令状态的无符号整数:成功为 0,发生错误为 1。

    STATUS_CODE 值与 STATUS 值不同:STATUS_CODE 对于成功为 0,对于错误为 1,这与 Audit Vault 的 EZ_collector 消费者兼容。STATUSmysql_errno() C API 函数的值。这对于成功为 0,对于错误为非零,因此并不一定为 1 表示错误。

    例如:STATUS_CODE="0"

  • TABLE

    代表表名的字符串。

    例如:TABLE="t3"

  • USER

    代表客户端发送的用户名的字符串。这可能与 PRIV_USER 值不同。

  • VERSION

    代表审计日志文件格式版本的无符号整数。

    例如:VERSION="1"

JSON 审计日志文件格式

对于 JSON 格式的审计日志记录(audit_log_format=JSON),日志文件内容形成一个 JSON 数组,每个数组元素表示一个审计事件,作为一个 JSON 键值对的哈希。完整事件记录的示例稍后在本节中出现。以下是部分事件的摘录:

[
  {
    "timestamp": "2019-10-03 13:50:01",
    "id": 0,
    "class": "audit",
    "event": "startup",
    ...
  },
  {
    "timestamp": "2019-10-03 15:02:32",
    "id": 0,
    "class": "connection",
    "event": "connect",
    ...
  },
  ...
  {
    "timestamp": "2019-10-03 17:37:26",
    "id": 0,
    "class": "table_access",
    "event": "insert",
      ...
  }
  ...
]

审计日志文件使用 UTF-8 编写(每个字符最多 4 个字节)。当审计日志插件开始写入新的日志文件时,它会写入开头的 [ 数组标记。当插件关闭日志文件时,它会写入结尾的 ] 数组标记。在文件打开时,结尾标记不存在。

审计记录中的项目具有以下特征:

  • 一些项目出现在每个审计记录中。其他项目是可选的,可能会根据审计记录类型而出现。

  • 审计记录中项目的顺序不保证。

  • 项目值不是固定长度。长值可能会根据稍后给出的项目描述而被截断。

  • "\ 字符分别编码为 \"\\

JSON 格式是唯一支持可选查询时间和大小统计信息的审计日志文件格式,这些信息从 MySQL 8.0.30 开始可用。对于符合条件的查询,此数据在慢查询日志中可用,并且在审计日志的上下文中,类似地有助于检测活动分析的异常值。

要将查询统计信息添加到日志文件中,必须将其设置为使用 audit_log_filter_set_filter() 审计日志函数作为 JSON 过滤语法的服务元素的过滤器。有关如何执行此操作的说明,请参见为异常检测添加查询统计信息。要填充 bytes_sentbytes_received 字段,必须将系统变量 log_slow_extra 设置为 ON。

以下示例展示了不同事件类型的 JSON 对象格式(由 classevent 项目指示),稍作调整以提高可读性:

审计启动事件:

{ "timestamp": "2019-10-03 14:21:56",
  "id": 0,
  "class": "audit",
  "event": "startup",
  "connection_id": 0,
  "startup_data": { "server_id": 1,
                    "os_version": "i686-Linux",
                    "mysql_version": "5.7.21-log",
                    "args": ["/usr/local/mysql/bin/mysqld",
                             "--loose-audit-log-format=JSON",
                             "--log-error=log.err",
                             "--pid-file=mysqld.pid",
                             "--port=3306" ] } }

当由于服务器启动而启动审计日志插件(而不是在运行时启用)时,connection_id设置为 0,accountlogin不存在。

审计关闭事件:

{ "timestamp": "2019-10-03 14:28:20",
  "id": 3,
  "class": "audit",
  "event": "shutdown",
  "connection_id": 0,
  "shutdown_data": { "server_id": 1 } }

当由于服务器关闭而卸载审计日志插件(而不是在运行时禁用)时,connection_id设置为 0,accountlogin不存在。

连接或更改用户事件:

{ "timestamp": "2019-10-03 14:23:18",
  "id": 1,
  "class": "connection",
  "event": "connect",
  "connection_id": 5,
  "account": { "user": "root", "host": "localhost" },
  "login": { "user": "root", "os": "", "ip": "::1", "proxy": "" },
  "connection_data": { "connection_type": "ssl",
                       "status": 0,
                       "db": "test",
                       "connection_attributes": {
                         "_pid": "43236",
                         ...
                         "program_name": "mysqladmin"
                       } }
}

断开连接事件:

{ "timestamp": "2019-10-03 14:24:45",
  "id": 3,
  "class": "connection",
  "event": "disconnect",
  "connection_id": 5,
  "account": { "user": "root", "host": "localhost" },
  "login": { "user": "root", "os": "", "ip": "::1", "proxy": "" },
  "connection_data": { "connection_type": "ssl" } }

查询事件:

{ "timestamp": "2019-10-03 14:23:35",
  "id": 2,
  "class": "general",
  "event": "status",
  "connection_id": 5,
  "account": { "user": "root", "host": "localhost" },
  "login": { "user": "root", "os": "", "ip": "::1", "proxy": "" },
  "general_data": { "command": "Query",
                    "sql_command": "show_variables",
                    "query": "SHOW VARIABLES",
                    "status": 0 } }

具有用于异常检测的可选查询统计信息的查询事件:

{ "timestamp": "2022-01-28 13:09:30", 
  "id": 0, 
  "class": "general", 
  "event": "status", 
  "connection_id": 46, 
  "account": { "user": "user", "host": "localhost" }, 
  "login": { "user": "user", “os": "", “ip": "127.0.0.1", “proxy": "" }, 
  "general_data": { "command": "Query", 
                    "sql_command": "insert",
	            "query": "INSERT INTO audit_table VALUES(4)",
	            "status": 1146 }
  "query_statistics": { "query_time": 0.116250,
                        "bytes_sent": 18384,
                        "bytes_received": 78858,
                        "rows_sent": 3,
                        "rows_examined": 20878 } }

表访问事件(读取、删除、插入、更新):

{ "timestamp": "2019-10-03 14:23:41",
  "id": 0,
  "class": "table_access",
  "event": "insert",
  "connection_id": 5,
  "account": { "user": "root", "host": "localhost" },
  "login": { "user": "root", "os": "", "ip": "127.0.0.1", "proxy": "" },
  "table_access_data": { "db": "test",
                         "table": "t1",
                         "query": "INSERT INTO t1 (i) VALUES(1),(2),(3)",
                         "sql_command": "insert" } }

以下列表中的项目出现在 JSON 格式审计记录的顶层:每个项目的值可以是标量或JSON哈希。对于具有哈希值的项目,描述仅列出该哈希内的项目名称。有关第二级哈希项目的更完整描述,请参见本节后面的内容。

  • account

    与事件关联的 MySQL 账户。该值是一个包含这些项目的哈希,等同于CURRENT_USER()函数中的值:user, host.

    示例:

    "account": { "user": "root", "host": "localhost" }
    
  • class

    表示事件类的字符串。类定义了事件的类型,与指定事件子类的event项目一起。

    示例:

    "class": "connection"
    

    以下表格显示了classevent值的允许组合。

    表 8.34 审计日志类和事件组合

    类值 允许的事件值
    audit startup, shutdown
    connection connect, change_user, disconnect
    general status
    table_access_data read, delete, insert, update
  • connection_data

    有关客户端连接的信息。该值是一个包含这些项目的哈希:connection_type, status, db,可能还有connection_attributes。此项目仅出现在class值为connection的审计记录中。

    示例:

    "connection_data": { "connection_type": "ssl",
                         "status": 0,
                         "db": "test" }
    

    截至 MySQL 8.0.19,具有class值为connectionevent值为connect的事件可能包括一个connection_attributes项目,以显示客户端在连接时传递的连接属性。(有关这些属性的信息,也在性能模式表中公开,参见第 29.12.9 节,“性能模式连接属性表”.)

    connection_attributes值是一个哈希,通过其名称和值表示每个属性。

    示例:

    "connection_attributes": {
      "_pid": "43236",
      "_os": "macos0.14",
      "_platform": "x86_64",
      "_client_version": "8.0.19",
      "_client_name": "libmysql",
      "program_name": "mysqladmin"
    }
    

    如果事件中没有连接属性,则不记录任何属性,也不会出现connection_attributes项目。这可能发生在连接尝试失败、客户端未传递任何属性或连接在服务器启动期间内部发生时。

  • connection_id

    代表客户端连接标识符的无符号整数。这与会话中CONNECTION_ID()函数返回的值相同。

    示例:

    "connection_id": 5
    
  • event

    代表事件类别的子类的字符串。子类定义了事件的类型,当与指定事件类别的class项目一起考虑时。有关更多信息,请参阅class项目描述。

    示例:

    "event": "connect"
    
  • general_data

    执行语句或命令的信息。该值是一个包含以下项目的哈希:commandsql_commandquerystatus。此项目仅出现在class值为general的审计记录中。

    示例:

    "general_data": { "command": "Query",
                      "sql_command": "show_variables",
                      "query": "SHOW VARIABLES",
                      "status": 0 }
    
  • id

    代表事件 ID 的无符号整数。

    示例:

    "id": 2
    

    对于具有相同timestamp值的审计记录,它们的id值可以区分它们并形成一个序列。在审计日志中,timestamp/id对是唯一的。这些对是标识日志中事件位置的书签。

  • login

    指示客户端如何连接到服务器的信息。该值是一个包含以下项目的哈希:userosipproxy

    示例:

    "login": { "user": "root", "os": "", "ip": "::1", "proxy": "" }
    
  • query_statistics

    用于异常检测的可选查询统计信息。该值是一个包含以下项目的哈希:query_timerows_sentrows_examinedbytes_receivedbytes_sent。有关设置查询统计信息的说明,请参见为异常检测添加查询统计信息。

    示例:

    "query_statistics": { "query_time": 0.116250,
                          "bytes_sent": 18384,
                          "bytes_received": 78858,
                          "rows_sent": 3,
                          "rows_examined": 20878 }
    
  • shutdown_data

    与审计日志插件终止相关的信息。该值是一个包含以下项目的哈希:server_id。此项目仅出现在classevent值分别为auditshutdown的审计记录中。

    示例:

    "shutdown_data": { "server_id": 1 }
    
  • startup_data

    与审计日志插件初始化相关的信息。该值是一个包含以下项目的哈希:server_idos_versionmysql_versionargs。此项目仅出现在classevent值分别为auditstartup的审计记录中。

    示例:

    "startup_data": { "server_id": 1,
                      "os_version": "i686-Linux",
                      "mysql_version": "5.7.21-log",
                      "args": ["/usr/local/mysql/bin/mysqld",
                               "--loose-audit-log-format=JSON",
                               "--log-error=log.err",
                               "--pid-file=mysqld.pid",
                               "--port=3306" ] }
    
  • table_access_data

    访问表格的信息。该值是一个包含以下项目的哈希:dbtablequerysql_command。此项目仅出现在class值为table_access的审计记录中。

    示例:

    "table_access_data": { "db": "test",
                           "table": "t1",
                           "query": "INSERT INTO t1 (i) VALUES(1),(2),(3)",
                           "sql_command": "insert" }
    
  • time

    此字段类似于timestamp字段中的字段,但其值是一个整数,表示生成审计事件的日期和时间的 UNIX 时间戳值。

    示例:

    "time" : 1618498687
    

    只有在启用audit_log_format_unix_timestamp系统变量时,time字段才会出现在 JSON 格式的日志文件中。

  • timestamp

    代表以YYYY-MM-DD hh:mm:ss格式表示的 UTC 值,指示生成审计事件的日期和时间。例如,对应于从客户端接收的 SQL 语句执行的事件具有timestamp值,该值在语句完成后发生,而不是在接收时发生。

    示例:

    "timestamp": "2019-10-03 13:50:01"
    

    对于具有相同timestamp值的审计记录,它们的id值可以区分它们并形成一个序列。在审计日志中,timestamp/id对是唯一的。这些对是标识日志中事件位置的书签。

这些项目出现在与 JSON 格式审计记录顶级项目关联的哈希值中:

  • args

    一个数组,其中包含 MySQL 服务器启动时在命令行或选项文件中给定的选项。第一个选项是服务器可执行文件的路径。

    示例:

    "args": ["/usr/local/mysql/bin/mysqld",
             "--loose-audit-log-format=JSON",
             "--log-error=log.err",
             "--pid-file=mysqld.pid",
             "--port=3306" ]
    
  • bytes_received

    从客户端接收的字节数。此项目是可选查询统计信息的一部分。要填充此字段,必须将系统变量log_slow_extra设置为ON

    示例:

    "bytes_received": 78858
    
  • bytes_sent

    发送到客户端的字节数。此项目是可选查询统计信息的一部分。要填充此字段,必须将系统变量log_slow_extra设置为ON

    示例:

    "bytes_sent": 18384
    
  • command

    代表生成审计事件的指令类型,例如服务器从客户端接收的命令。

    示例:

    "command": "Query"
    
  • connection_type

    与服务器的连接安全状态相关。允许的值为tcp/ip(未加密的 TCP/IP 连接)、ssl(已加密的 TCP/IP 连接)、socket(Unix 套接字文件连接)、named_pipe(Windows 命名管道连接)和shared_memory(Windows 共享内存连接)。

    示例:

    "connection_type": "tcp/tcp"
    
  • db

    代表数据库名称的字符串。对于connection_data,它是默认数据库。对于table_access_data,它是表数据库。

    示例:

    "db": "test"
    
  • host

    代表客户端主机名的字符串。

    示例:

    "host": "localhost"
    
  • ip

    代表客户端 IP 地址的字符串。

    示例:

    "ip": "::1"
    
  • mysql_version

    代表 MySQL 服务器版本的字符串。这与VERSION()函数或version系统变量的值相同。

    示例:

    "mysql_version": "5.7.21-log"
    
  • os

    代表在认证过程中使用的外部用户名,由用于认证客户端的插件设置。对于本地(内置)MySQL 认证,或者如果插件未设置该值,则此属性为空。该值与external_user系统变量的值相同。参见 Section 8.2.19, “Proxy Users”。

    示例:

    "os": "jeffrey"
    
  • os_version

    代表构建或运行服务器的操作系统的字符串。

    示例:

    "os_version": "i686-Linux"
    
  • proxy

    代理用户的字符串表示(参见第 8.2.19 节,“代理用户”)。如果未启用用户代理,则该值为空。

    示例:

    "proxy": "developer"
    
  • 查询

    一个表示 SQL 语句文本的字符串。该值可以为空。长值可能会被截断。该字符串,就像审计日志文件本身一样,是使用 UTF-8(每个字符最多 4 个字节)编写的,因此该值可能是转换的结果。例如,原始语句可能已从客户端作为 SJIS 字符串接收。

    示例:

    "query": "DELETE FROM t1"
    
  • query_time

    查询执行时间(如果选择了longlong数据类型,则为微秒,如果选择了double数据类型,则为秒)。此项是可选查询统计的一部分。

    示例:

    "query_time": 0.116250
    
  • rows_examined

    查询期间访问的行数。此项是可选查询统计的一部分。

    示例:

    "rows_examined": 20878
    
  • rows_sent

    作为结果发送给客户端的行数。此项是可选查询统计的一部分。

    示例:

    "rows_sent": 3
    
  • 服务器 ID

    表示服务器 ID 的无符号整数。这与server_id系统变量的值相同。

    示例:

    "server_id": 1
    
  • sql_command

    表示 SQL 语句类型的字符串。

    示例:

    "sql_command": "insert"
    

    这些值对应于statement/sql/*xxx*命令计数器。例如,xxxdrop_tableselect分别用于DROP TABLESELECT语句。以下语句显示可能的名称:

    SELECT REPLACE(EVENT_NAME, 'statement/sql/', '') AS name
    FROM performance_schema.events_statements_summary_global_by_event_name
    WHERE EVENT_NAME LIKE 'statement/sql/%'
    ORDER BY name;
    
  • 状态

    表示命令状态的无符号整数:成功为 0,发生错误为非零。这与mysql_errno() C API 函数的值相同。

    审计日志不包含 SQLSTATE 值或错误消息。要查看错误代码、SQLSTATE 值和消息之间的关联,请参阅服务器错误消息参考。

    警告未记录。

    示例:

    "status": 1051
    
  • 表示表名的字符串。

    示例:

    "table": "t1"
    
  • 用户

    表示用户名的字符串。根据user出现的项的不同,含义也不同:

    • account项中,user是一个表示服务器对客户端进行身份验证的用户的字符串。这是服务器用于权限检查的用户名。

    • login项中,user是表示客户端发送的用户名的字符串。

    示例:

    "user": "root"
    

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

8.4.5.5 配置审计日志特性

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

  • 审计日志文件命名约定

  • 选择审计日志文件格式

  • 启用审计日志刷新任务

  • 为异常检测添加查询统计信息

  • 压缩审计日志文件

  • 加密审计日志文件

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

  • MySQL 8.0.17 之前的审计日志文件加密

  • 审计日志文件空间管理

  • 审计日志编写策略

注意

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

有关影响审计日志的函数和系统变量的额外信息,请参阅审计日志函数和审计日志选项和变量。

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

审计日志文件命名约定

要配置审计日志文件名,请在服务器启动时设置audit_log_file系统变量。默认名称是服务器数据目录中的audit.log。为了最佳安全性,将审计日志写入仅对 MySQL 服务器和有合法查看日志原因的用户可访问的目录。

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

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

  • 如果启用了加密,插件会添加一个后缀为.*pwd_id*.enc,其中pwd_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是一个以*YYYYMMDD*T*hhmmss*格式表示的 UTC 值,指示密码创建的时间。

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

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

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

为了构建用于在密钥环中存储密码的相应密钥环 ID,审计日志插件将pwd_id值的前缀添加为audit_log-。对于刚刚显示的示例密码 ID,相应的密钥环 ID 是:

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

当前由审计日志插件用于加密的密码的 ID 是具有最大pwd_timestamp值的密码。如果多个密码具有该pwd_timestamp值,则当前密码 ID 是具有最大序列号的密码。例如,在前面的密码 ID 集合中,有两个具有最大时间戳20190403T142400,因此当前密码 ID 是具有最大序列号(2)的密码。

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

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

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

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

选择审计日志文件格式

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

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

  • OLD:旧式 XML 格式。

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

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

启用审计日志刷新任务

从 MySQL 8.0.34 开始,MySQL 企业审计提供了设置刷新间隔以自动处理内存缓存的功能。使用audit_log_flush_interval_seconds系统变量配置的刷新任务默认值为零,这意味着未安排运行任务。

当任务配置为运行时(值为非零),MySQL 企业审计尝试在其初始化时调用 scheduler 组件,并配置其内存缓存的定期定期刷新:

  • 如果审计日志找不到调度程序注册服务的实现,则不会安排刷新并继续加载。

  • 审计日志实现了dynamic_loader_services_loaded_notification服务,并监听mysql_scheduler的新注册,以便审计日志可以将其计划任务注册到新加载的调度程序中。

  • 审计日志仅注册到加载的第一个调度程序实现中。

类似地,MySQL 企业审计在其去初始化时调用scheduler组件,并取消其已计划的定期刷新。它保持对调度程序注册服务的活动引用,直到计划任务被注销,确保在有活动计划任务时无法卸载scheduler组件。执行调度程序及其任务的所有结果都写入服务器错误日志。

要安排审计日志刷新任务:

  1. 确认scheduler组件已加载并启用。该组件默认启用(ON)(参见component_scheduler.enabled)。

    SELECT * FROM mysql.components;
    +--------------+--------------------+----------------------------+
    | component_id | component_group_id | component_urn              |
    +--------------+--------------------+----------------------------+
    |            1 |                  1 | file://component_scheduler |
    +--------------+--------------------+----------------------------+
    
  2. 如果尚未安装audit_log插件,请安装它(参见 Section 8.4.5.2, “Installing or Uninstalling MySQL Enterprise Audit”)。

  3. 使用audit_log_flush_interval_seconds启动服务器,并将值设置为大于 59 的数字。该值的上限因平台而异。例如,要配置刷新任务每两分钟重复一次:

    $> mysqld --audit_log_flush_interval_seconds=120
    

    更多信息,请参阅audit_log_flush_interval_seconds系统变量。

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

在 MySQL 8.0.30 及更高版本中,您可以通过可选数据字段扩展 JSON 格式的日志文件,以显示查询时间、发送和接收的字节数、返回给客户端的行数以及检查的行数。对于符合条件的查询,此数据在慢查询日志中可用,并且在审计日志的上下文中,类似地有助于检测活动分析的异常值。只有当审计日志处于 JSON 格式(audit_log_format=JSON)时,扩展数据字段才能添加,这不是默认设置。

查询统计信息通过您设置的组件服务传递到审计日志,作为审计日志过滤函数。这些服务分别命名为mysql_audit_print_service_longlong_data_sourcemysql_audit_print_service_double_data_source。您可以为每个输出项选择任一数据类型。对于查询时间,longlong以微秒输出值,而double以秒输出值。

您可以使用audit_log_filter_set_filter()审计日志函数将查询统计信息添加为 JSON 过滤语法的service元素,如下所示:

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。如果系统��量值为OFF,则这些字段的日志文件中将写入空值。

如果您想停止收集查询统计信息,请使用audit_log_filter_set_filter()审计日志函数来移除过滤器,例如:

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

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

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

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

加密审计日志文件

可以为任何日志格式启用审计日志文件加密。加密基于用户定义的密码(除了审计日志插件生成的初始密码)。要使用此功能,必须启用 MySQL 密钥环,因为审计日志使用它进行密码存储。可以使用任何密钥环组件或插件;有关说明,请参阅第 8.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,请查询性能模式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 |
    +-----------------------------+
    

有关审计日志加密函数的其他信息,请参阅审计日志函数。

当审计日志插件初始化时,如果发现日志文件加密已启用,则会检查密钥环是否包含审计日志加密密码。如果没有,则插件会自动生成一个随机初始加密密码并将其存储在密钥环中。要查找此密码,请调用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),但不同的序列号(12)。这些文件具有不同的加密密码。

要手动解压缩压缩的日志文件,请使用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 企业审计无法读取用旧密码加密的日志文件。如果你预期需要手动解密这些文件,你必须保留以前的密码记录。

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

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

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

  • 当密码清理发生时,如果插件过期任何具有audit_log-*pwd_id*格式的密钥环 ID 的密码,它也会过期具有audit_log密钥环 ID 的密码(如果存在)。此时,具有后缀.enc而不是.*pwd_id*.enc的加密日志文件变得无法被插件读取,因此可以假定你不再需要它们。

审计日志文件的空间管理

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

为管理使用的空间,采用以下方法:

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

  • 如果启用了自动轮换,则对已轮换的 JSON 格式日志文件进行修剪。修剪可以基于日志文件的年龄(自 MySQL 8.0.24 起),或组合日志文件大小(自 MySQL 8.0.26 起)进行。

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

  • 如果audit_log_rotate_on_size为 0(默认值),则禁用自动日志文件轮换。

    • 除非手动执行,否则不会发生轮换。

    • 要轮换当前文件,请使用以下方法之一:

      • 在 MySQL 8.0.31 之前,手动重命名文件,然后启用audit_log_flush来关闭它,并使用原始名称打开一个新的当前日志文件。此文件轮换方法和audit_log_flush变量在 MySQL 8.0.31 中已弃用。

        使用此文件轮换方法,不会发生对已轮换的 JSON 格式日志文件进行修剪;audit_log_max_sizeaudit_log_prune_seconds不起作用。

      • 从 MySQL 8.0.31 开始,运行SELECT audit_log_rotate();来重命名文件,并使用原始名称打开一个新的审计日志文件。

        使用此文件轮换方法,如果audit_log_max_sizeaudit_log_prune_seconds的值大于 0,则会对已轮换的 JSON 格式日志文件进行修剪。

      参见手动审计日志文件轮换(MySQL 8.0.31 之前)。

  • 如果audit_log_rotate_on_size大于 0,则启用自动审计日志文件轮换:

    • 当对当前日志文件进行写入导致其大小超过audit_log_rotate_on_size值时,以及在某些其他条件下,会自动进行轮换;参见自动审计日志文件轮换。当自动轮换发生时,审计日志插件会重命名当前日志文件,并使用原始名称打开一个新的当前日志文件。

    • 如果audit_log_max_sizeaudit_log_prune_seconds的值大于 0,则会对旋转的 JSON 格式日志文件进行修剪。

    • audit_log_flush没有效果。

注意

对于 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 开始)

  • 自动审计日志文件旋转

  • 审计日志文件修剪

手动审计日志文件旋转(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.1audit.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 格式日志记录,手动重命名审计日志文件会使它们对于日志读取功能不可用,因为审计日志插件无法再确定它们是日志文件序列的一部分(参见第 8.4.5.6 节,“读取审计日志文件”)。考虑设置audit_log_rotate_on_size大于 0 以使用基于大小的轮换。

手动审计日志文件旋转(从 MySQL 8.0.31 开始)

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

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

使用audit_log_rotate()函数需要AUDIT_ADMIN特权。

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

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

自动审计日志文件旋转

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

在以下情况下也会自动基于大小进行旋转:

  • 在插件初始化期间,如果具有审计日志文件名的文件已经存在(参见审计日志文件命名约定)。

  • 在插件终止期间。

  • 当调用audit_log_encryption_password_set()函数设置加密密码时,如果启用了加密。(如果禁用加密,则不会发生旋转。)

插件通过在基本名称后插入时间戳来重命名原始文件。例如,如果文件名为audit.log,插件将将其重命名为类似audit.20210115T140633.log的值。时间戳是*YYYYMMDD*T*hhmmss*格式的 UTC 值。对于 XML 日志记录,时间戳表示旋转时间。对于 JSON 日志记录,时间戳是写入文件的最后一个事件的时间。

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

审计日志文件修剪

如果启用了自动日志文件旋转,则审计日志插件支持对旋转的 JSON 格式审计日志文件进行修剪。要使用此功能:

  • audit_log_format设置为JSON。(此外,还考虑更改audit_log_file;请参见选择审计日志文件格式。)

  • audit_log_rotate_on_size设置为大于 0,以指定自动日志文件旋转发生的字节大小。

  • 默认情况下,不会对自动旋转的 JSON 格式日志文件进行修剪。要启用修剪,请将以下系统变量之一设置为大于 0 的值:

    • audit_log_max_size设置为大于 0,以指定旋转日志文件的组合大小上限,超过该大小的文件将被修剪。audit_log_max_size自 MySQL 8.0.26 版本起可用。

    • audit_log_prune_seconds设置为大于 0,以指定旋转日志文件在多少秒后将被修剪。audit_log_prune_seconds自 MySQL 8.0.24 版本起可用。

    非零值的audit_log_max_size优先于非零值的audit_log_prune_seconds。如果两者在插件初始化时都设置为大于 0,则会向服务器错误日志写入警告。如果客户端在运行时都设置为大于 0,则会向客户端返回警告。

    注意

    写入错误日志的警告被写入为注释,这些是信息消息。为确保这些消息出现在错误日志中并且不被丢弃,请确保错误日志的详细程度足以包含信息消息。例如,如果您正在使用基于优先级的日志过滤,如第 7.4.2.5 节,“基于优先级的错误日志过滤(log_filter_internal)”中所述,将log_error_verbosity系统变量设置为 3。

如果启用了 JSON 格式日志文件的修剪,则会按以下方式进行:

  • 当自动旋转发生时;有关发生此情况的条件,请参阅自动审计日志文件旋转。

  • 当全局audit_log_max_sizeaudit_log_prune_seconds系统变量���运行时设置时。

对于基于组合旋转日志文件大小进行修剪,如果组合大小大于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 策略的一个缺点是当缓冲区已满时会丢弃事件。对于负载较重的服务器,审计日志可能会丢失事件。

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

8.4.5.6 读取审计日志文件

审计日志插件支持提供 SQL 接口以读取 JSON 格式审计日志文件的函数。(此功能不适用于其他格式的日志文件。)

当审计日志插件初始化并配置为 JSON 记录时,它使用包含当前审计日志文件的目录作为搜索可读取审计日志文件的位置。插件从audit_log_file系统变量的值中确定文件位置、基本名称和后缀,然后查找与以下模式匹配的文件,其中[...]表示可选文件名部分:

*basename*[.*timestamp*].*suffix*[.gz][[.*pwd_id*].enc]

如果文件名以.enc结尾,则文件已加密,读取其未加密内容需要从密钥环获取解密密码。审计日志插件确定解密密码的密钥环 ID 如下:

  • 如果.enc之前是pwd_id,密钥环 ID 是audit_log-*pwd_id*

  • 如果.enc之前不是pwd_id,则文件具有在实施审计日志加密密码历史之前的旧名称。密钥环 ID 是audit_log

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

插件会忽略那些被手动重命名且不符合模式的文件,以及使用密码加密但密钥环中不再存在密码的文件。插件会打开每个剩余的候选文件,验证文件是否实际包含JSON审计事件,并使用每个文件的第一个事件的时间戳对文件进行排序。结果是一系列文件,可以通过日志读取函数进行访问:

  • audit_log_read() 从审计日志中读取事件或关闭读取过程。

  • audit_log_read_bookmark() 返回最近写入的审计日志事件的书签。此书签适合传递给audit_log_read()以指示从何处开始读取。

audit_log_read() 接受一个可选的JSON字符串参数,成功调用任一函数后返回的结果是一个JSON字符串。

要使用函数读取审计日志,请遵循以下原则:

  • 调用audit_log_read() 从给定位置或当前位置开始读取事件,或关闭读取:

    • 要初始化审核日志读取序列,请传递指示开始位置的参数。一种方法是传递由audit_log_read_bookmark()返回的书签:

      SELECT audit_log_read(audit_log_read_bookmark());
      
    • 要从序列中的当前位置继续读取,请调用audit_log_read()而不指定位置:

      SELECT audit_log_read();
      
    • 要显式关闭读取序列,请传递一个JSON null参数:

      SELECT audit_log_read('null');
      

      不需要显式关闭读取。当会话结束或通过调用带有指示开始位置参数的audit_log_read()来初始化新的读取序列时,读取会在隐式关闭。

  • 成功调用audit_log_read()读取事件将返回一个包含审核事件数组的JSON字符串:

    • 如果返回数组的最终值不是JSON null值,则在刚刚读取的事件后还有更多事件,并且可以再次调用audit_log_read()来读取更多事件。

    • 如果返回数组的最终值是JSON null值,则当前读取序列中没有更多事件可读取。

    每个非null数组元素都表示为JSON哈希。例如:

    [
      {
        "timestamp": "2020-05-18 13:39:33", "id": 0,
        "class": "connection", "event": "connect",
        ...
      },
      {
        "timestamp": "2020-05-18 13:39:33", "id": 1,
        "class": "general", "event": "status",
        ...
      },
      {
        "timestamp": "2020-05-18 13:39:33", "id": 2,
        "class": "connection", "event": "disconnect",
        ...
      },
      null
    ]
    

    有关 JSON 格式审核事件内容的更多信息,请参阅 JSON 审计日志文件格式。

  • 未指定位置的audit_log_read()调用在以下任何条件下都会产生错误:

    • 通过向audit_log_read()传递位置参数来初始化读取序列。

    • 当前读取序列中没有更多事件可读取;也就是说,audit_log_read()先前返回了以JSON null值结尾的数组。

    • 通过向audit_log_read()传递一个JSON null值,最近的读取序列已被关闭。

    要在这些条件下读取事件,需要首先通过调用带有指定位置参数的audit_log_read()来初始化读取序列。

要指定传递给audit_log_read()的位置,请包含指示从何处开始读取的参数。例如,传递一个书签,这是一个包含timestampid元素的JSON哈希,用于唯一标识特定事件。以下是通过调用audit_log_read_bookmark()函数获得的示例书签:

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

将当前书签传递给audit_log_read()会初始化从书签位置开始的事件读取:

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", ... |
+-----------------------------------------------------------------------+

传递给[audit_log_read()的参数是可选的。如果存在,则可以是JSON null值以关闭读取序列,或者是JSON哈希。

在传递给audit_log_read()的哈希参数中,项目是可选的,用于控制读取操作的方面,例如开始读取的位置或要读取的事件数量。以下项目是重要的(其他项目将被忽略):

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

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

    start项目自 MySQL 8.0.22 起允许使用。

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

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

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

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

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

audit_log_read()接受的示例参数:

  • 从给定时间戳之后或同时发生的第一个事件开始读取事件:

    audit_log_read('{ "start": { "timestamp": "2020-05-24 12:30:00" } }')
    
  • 类似于前一个示例,但最多读取 3 个事件:

    audit_log_read('{ "start": { "timestamp": "2020-05-24 12:30:00" }, "max_array_length": 3 }')
    
  • 2020-05-24 00:00:00之后或同时发生的第一个事件开始读取事件(时间戳不包含时间部分,因此假定为00:00:00):

    audit_log_read('{ "start": { "timestamp": "2020-05-24" } }')
    
  • 从具有确切时间戳和事件 ID 的事件开始读取事件:

    audit_log_read('{ "timestamp": "2020-05-24 12:30:00", "id": 0 }')
    
  • 与前一个示例类似,但最多读取 3 个事件:

    audit_log_read('{ "timestamp": "2020-05-24 12:30:00", "id": 0, "max_array_length": 3 }')
    
  • 从读取序列的当前位置读取事件:

    audit_log_read()
    
  • 从当前位置开始读取最多 5 个事件:

    audit_log_read('{ "max_array_length": 5 }')
    
  • 关闭当前读取序列:

    audit_log_read('null')
    

从任一日志读取函数返回的JSON字符串可以根据需要进行操作。假设调用以获取书签产生此值:

mysql> SET @mark := audit_log_read_bookmark();
mysql> SELECT @mark;
+-------------------------------------------------+
| @mark                                           |
+-------------------------------------------------+
| { "timestamp": "2020-05-18 16:10:28", "id": 2 } |
+-------------------------------------------------+

使用该参数调用audit_log_read()可以返回多个事件。要限制audit_log_read()最多读取 N 个事件,请向字符串添加一个具有该值的 max_array_length 项。例如,要读取单个事件,请修改字符串如下:

mysql> SET @mark := JSON_SET(@mark, '$.max_array_length', 1);
mysql> SELECT @mark;
+----------------------------------------------------------------------+
| @mark                                                                |
+----------------------------------------------------------------------+
| {"id": 2, "timestamp": "2020-05-18 16:10:28", "max_array_length": 1} |
+----------------------------------------------------------------------+

修改后的字���串,当传递给audit_log_read()时,将产生一个包含最多一个事件的结果,无论有多少事件可用。

在 MySQL 8.0.19 之前,审计日志函数返回的字符串返回值是二进制字符串。要将二进制字符串用于需要非二进制字符串的函数(例如操作JSON值的函数),请将其转换为非二进制字符串。例如,在将书签传递给JSON_SET()之前,将其转换为utf8mb4如下:

SET @mark = CONVERT(@mark USING utf8mb4);

该语句即使对于 MySQL 8.0.19 及更高版本也可以使用;对于这些版本,它基本上是一个无操作,并且是无害的。

如果从mysql客户端内调用审计日志函数,则根据--binary-as-hex的值,二进制字符串结果将以十六进制表示。有关该选项的更多信息,请参见 Section 6.5.1, “mysql — The MySQL Command-Line Client”。

要限制audit_log_read()读取的字节数量,请设置audit_log_read_buffer_size系统变量。从 MySQL 8.0.12 开始,此变量默认为 32KB,并且可以在运行时设置。每个客户端应适当设置其对audit_log_read()的使用的会话值audit_log_read_buffer_size

每次调用audit_log_read()都会返回尽可能多的可用事件,适合缓冲区大小。不适合缓冲区大小的事件将被跳过并生成警告。考虑这种行为时,应考虑以下因素来评估应用程序的适当缓冲区大小:

  • 在调用audit_log_read()和每次调用返回的事件数量之间存在权衡:

    • 使用更小的缓冲区大小,调用会返回更少的事件,因此需要更多的调用。

    • 使用更大的缓冲区大小,调用会返回更多事件,因此需要更少的调用。

  • 使用较小的缓冲区大小,例如默认大小为 32KB,事件超过缓冲区大小并因此被跳过的可能性更大。

在 MySQL 8.0.12 之前,audit_log_read_buffer_size默认为 1MB,影响所有客户端,只能在服务器启动时更改。

有关审计日志读取函数的更多信息,请参见 Audit Log Functions。

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

8.4.5.7 审计日志过滤

注意

要使此处描述的审计日志过滤工作,必须安装审计日志插件和相应的审计表和函数。如果安装了插件但没有为基于规则的过滤所需的审计表和函数,插件将以传统过滤模式运行,描述在第 8.4.5.10 节“传统模式审计日志过滤”中。传统模式(在 MySQL 8.0.34 中已弃用)是 MySQL 5.7.13 之前引入基于规则的过滤之前的过滤行为。

  • 审计日志过滤属性

  • 审计日志过滤函数的约束

  • 使用审计日志过滤函数

审计日志过滤属性

审计日志插件具有通过过滤控制记录审计事件的能力:

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

    • 用户帐户

    • 审计事件类

    • 审计事件子类

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

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

    • 审计规则定义创建了一组审计规则。根据刚才描述的特征,可以配置定义以包括或排除事件进行日志记录。

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

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

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

    审计日志过滤用于从 MySQL 8.0.30 实现组件服务。要获取该版本提供的可选查询统计信息,您可以设置它们作为一个使用服务组件的过滤器,该组件实现将统计信息写入审计日志的服务。有关设置此过滤器的说明,请参见添加查询统计信息以进行异常检测。

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

  • 可以使用基于函数调用的 SQL 接口定义和修改审计过滤器。要显示审计过滤器,请查询mysql.audit_log_filter表。

  • 审计过滤器定义存储在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_filter_set_filter(): 定义过滤器。

  • audit_log_filter_remove_filter(): 移除过滤器。

  • audit_log_filter_set_user(): 开始过滤用户账户。

  • audit_log_filter_remove_user(): 停止过滤用户账户。

  • audit_log_filter_flush(): 刷新手动更改的过滤器表以影响正在进行的过滤。

有关使用示例和有关过滤功能的完整详细信息,请参见 Using Audit Log Filtering Functions 和 Audit Log Functions。

审计日志过滤功能的约束

审计日志过滤功能受到以下约束:

  • 要使用任何过滤功能,必须启用audit_log插件,否则会出错。此外,审计表必须存在,否则会出错。要安装audit_log插件及其附带的功能和表,请参见 Section 8.4.5.2, “Installing or Uninstalling 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.'
    

    在 MySQL 8.0.34 之后不再支持的传统模式中,过滤只能基于事件账户或状态进行。详情请参阅第 8.4.5.10 节,“传统模式审计日志过滤”。

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

    在 MySQL 8.0.28 或更高版本中创建的具有SYSTEM_USER权限的账户在创建时会自动分配AUDIT_ABORT_EXEMPT权限。在进行 MySQL 8.0.28 或更高版本的升级过程时,如果没有现有账户被分配该权限,则具有SYSTEM_USER权限的现有账户也会被分配AUDIT_ABORT_EXEMPT权限。

使用审计日志过滤功能

在使用审计日志函数之前,请根据第 8.4.5.2 节,“安装或卸载 MySQL 企业审计”中提供的说明安装它们。使用任何这些函数都需要AUDIT_ADMINSUPER权限。

审计日志过滤功能通过提供一个接口来创建、修改和删除过滤定义并将过滤器分配给用户账户,实现了过滤控制。

过滤器定义是JSON值。有关在 MySQL 中使用 JSON 数据的信息,请参见第 13.5 节,“JSON 数据类型”。本节显示了一些简单的过滤器定义。有关过滤器定义的更多信息,请参见第 8.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@localhostuser2@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 系统数据库中的审计日志表(参见 Audit Log Tables)。也可以直接修改审计日志表,使用诸如 INSERTUPDATEDELETE 等语句,但这些更改不会立即影响过滤。要刷新更改并使其生效,请调用 audit_log_filter_flush()

SELECT audit_log_filter_flush();

警告

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

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

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

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

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

8.4.5.8 编写审计日志过滤器定义

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

过滤器定义采用以下形式,其中actions表示过滤如何进行:

{ "filter": *actions* }

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

  • 记录所有事件

  • 记录特定事件类

  • 记录特定事件子类

  • 包容性和排他性日志记录

  • 测试事件字段值

  • 阻止特定事件的执行

  • 逻辑运算符

  • 引用预定义变量

  • 引用预定义函数

  • 替换事件字段值

  • 替换用户过滤器

记录所有事件

要明确启用或禁用所有事件的记录,请在过滤器中使用log项:

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

log值可以是truefalse

前面的过滤器启用了所有事件的记录。这等同于:

{
  "filter": { }
}

记录行为取决于log值以及是否指定了classevent项:

  • 如果指定了log,则使用给定的值。

  • 如果未指定log,则如果未指定classevent项,则记录为true,否则为false(在这种情况下,classevent可以包括自己的log项)。

记录特定事件类

要记录特定类别的事件,请在过滤器中使用class项,其��name字段表示要记录的类别的名称:

{
  "filter": {
    "class": { "name": "connection" }
  }
}

name值可以是connectiongeneraltable_access,分别用于记录连接、一般或表访问事件。

上述过滤器启用了connection类中事件的记录。它等同于以下过滤器,其中log项目被明确指定:

{
  "filter": {
    "log": false,
    "class": { "log": true,
               "name": "connection" }
  }
}

要启用多个类别的记录,将class值定义为JSON数组元素,命名这些类别:

{
  "filter": {
    "class": [
      { "name": "connection" },
      { "name": "general" },
      { "name": "table_access" }
    ]
  }
}

注意

当在过滤器定义中同一级别出现给定项目的多个实例时,可以将项目值合并为数组值中的单个项目实例。上述定义可以写成这样:

{
  "filter": {
    "class": [
      { "name": [ "connection", "general", "table_access" ] }
    ]
  }
}
记录特定事件子类

要选择特定的事件子类,使用包含命名子类的name项目的event项目。由event项目选择的事件的默认操作是记录它们。例如,此过滤器启用了命名事件子类的记录:

{
  "filter": {
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect" },
          { "name": "disconnect" }
        ]
      },
      { "name": "general" },
      {
        "name": "table_access",
        "event": [
          { "name": "insert" },
          { "name": "delete" },
          { "name": "update" }
        ]
      }
    ]
  }
}

event项目还可以包含显式的log项目,以指示是否记录符合条件的事件。此event项目选择多个事件,并明确指示它们的记录行为:

"event": [
  { "name": "read", "log": false },
  { "name": "insert", "log": true },
  { "name": "delete", "log": true },
  { "name": "update", "log": true }
]

event项目还可以指示是否阻止符合条件的事件,如果包含abort项目。详情请参见阻止特定事件的执行。

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

表 8.35 事件类和子类组合

事件类 事件子类 描述
connection connect 连接初始化(成功或失败)
connection change_user 会话期间使用不同用户/密码重新认证
connection disconnect 连接终止
general status 一般操作信息
message internal 内部生成的消息
message user audit_api_message_emit_udf()生成的消息
table_access read 表读取语句,如SELECTINSERT INTO ... SELECT
table_access delete 表删除语句,如DELETETRUNCATE TABLE
table_access insert 表插入语句,如INSERTREPLACE
table_access update 表更新语句,如UPDATE
事件类 事件子类 描述

表 8.36,“每个事件类和子类组合的记录和中止特性”描述了每个事件子类是否可以被记录或中止。

表 8.36 每个事件类和子类组合的记录和中止特性

事件类 事件子类 可以被记录 可以被中止
connection connect
connection change_user
connection disconnect
general status
message internal
message user
table_access read
table_access delete
table_access insert
table_access update
事件类 事件子类 可以被记录 可以被中止
包容性和独占性记录

可以定义包容性或独占性模式的过滤器:

  • 包容性模式仅记录明确指定的项目。

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

要执行包容性记录,全局禁用记录并为特定类启用记录。此过滤器记录connection类中的connectdisconnect事件,以及general类中的事件:

{
  "filter": {
    "log": false,
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect", "log": true },
          { "name": "disconnect", "log": true }
        ]
      },
      { "name": "general", "log": true }
    ]
  }
}

要执行独占性记录,全局启用记录并为特定类禁用记录。此过滤器记录除general类中的事件之外的所有内容:

{
  "filter": {
    "log": true,
    "class":
      { "name": "general", "log": false }
  }
}

此过滤器记录connection类中的change_user事件,message事件和table_access事件,因为记录其他所有内容:

{
  "filter": {
    "log": true,
    "class": [
      {
        "name": "connection",
        "event": [
          { "name": "connect", "log": false },
          { "name": "disconnect", "log": false }
        ]
      },
      { "name": "general", "log": false }
    ]
  }
}
测试事件字段值

要基于特定事件字段值启用记录,请在指示字段名称及其预期值的log项内指定一个field项:

{
  "filter": {
    "class": {
    "name": "general",
      "event": {
        "name": "status",
        "log": {
          "field": { "name": "general_command.str", "value": "Query" }
        }
      }
    }
  }
}

每个事件包含特定于事件类的字段,可以从过滤器内部访问以执行自定义过滤。

connection类中的事件指示会话期间发生的与连接相关的活动,例如用户连接到服务器或从服务器断开连接。表 8.37,“连接事件字段”指示了connection事件的允许字段。

表 8.37 连接事件字段

字段名称 字段类型 描述
status 整数 事件状态:0:成功否则:失败
connection_id 无符号整数 连接 ID
user.str 字符串 在认证期间指定的用户名
user.length 无符号整数 用户名称长度
priv_user.str 字符串 已认证的用户名称(帐户用户名)
priv_user.length 无符号整数 已认证的用户名称长度
external_user.str 字符串 外部用户名称(由第三方认证插件提供)
external_user.length 无符号整数 外部用户名称长度
proxy_user.str string 代理用户名称
proxy_user.length unsigned integer 代理用户名称长度
host.str string 连接用户主机
host.length unsigned integer 连接用户主机长度
ip.str string 连接用户 IP 地址
ip.length unsigned integer 连接用户 IP 地址长度
database.str string 连接时指定的数据库名称
database.length unsigned integer 数据库名称长度
connection_type integer 连接类型:0 或 "::undefined": 未定义 1 或 "::tcp/ip": TCP/IP2 或 "::socket": Socket3 或 "::named_pipe": 命名管道 4 或 "::ssl": 带加密的 TCP/IP5 或 "::shared_memory": 共享内存
字段名称 字段类型 描述

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

general 类中的事件指示操作的状态代码及其详细信息。 表 8.38,“通用事件字段” 指示 general 事件的允许字段。

表 8.38 通用事件字段

字段名称 字段类型 描述
general_error_code integer 事件状态:0: OK 否则: 失败
general_thread_id unsigned integer 连接/线程 ID
general_user.str string 认证期间指定的用户名
general_user.length unsigned integer 用户��称长度
general_command.str string 命令名称
general_command.length unsigned integer 命令名称长度
general_query.str string SQL 语句文本
general_query.length unsigned integer SQL 语句文本长度
general_host.str string 主机名
general_host.length unsigned integer 主机名长度
general_sql_command.str string SQL 命令类型名称
general_sql_command.length unsigned integer SQL 命令类型名称长度
general_external_user.str string 外部用户名称(由第三方认证插件提供)
general_external_user.length unsigned integer 外部用户名称长度
general_ip.str string 连接用户 IP 地址
general_ip.length unsigned integer 连接用户 IP 地址长度
字段名称 字段类型 描述

general_command.str 指示命令名称:QueryExecuteQuitChange user

一个 general 事件,其中 general_command.str 字段设置为 QueryExecute,包含 general_sql_command.str 设置为指定 SQL 命令类型的值:alter_dbalter_db_upgradeadmin_commands 等。 可以在此语句显示的性能模式工具的最后组件中看到可用的 general_sql_command.str 值:

mysql> SELECT NAME FROM performance_schema.setup_instruments
       WHERE NAME LIKE 'statement/sql/%' ORDER BY NAME;
+---------------------------------------+
| NAME                                  |
+---------------------------------------+
| statement/sql/alter_db                |
| statement/sql/alter_db_upgrade        |
| statement/sql/alter_event             |
| statement/sql/alter_function          |
| statement/sql/alter_instance          |
| statement/sql/alter_procedure         |
| statement/sql/alter_server            |
...

table_access 类中的事件提供有关对表的特定类型访问的信息。Table 8.39, “Table-Access Event Fields” 指示了table_access事件的允许字段。

Table 8.39 Table-Access Event Fields

Field Name Field Type 描述
connection_id 无符号整数 事件连接 ID
sql_command_id integer SQL 命令 ID
query.str string SQL 语句文本
query.length 无符号整数 SQL 语句文本长度
table_database.str string 与事件相关联的数据库名
table_database.length 无符号整数 数据库名长度
table_name.str string 与事件相关联的表名
table_name.length 无符号整数 表名长度

以下列表显示了哪些语句产生哪些表访问事件:

  • read 事件:

    • SELECT

    • INSERT ... SELECT(用于SELECT子句中引用的表)

    • REPLACE ... SELECT(用于SELECT子句中引用的表)

    • UPDATE ... WHERE(用于WHERE子句中引用的表)

    • HANDLER ... READ

  • delete 事件:

    • DELETE

    • TRUNCATE TABLE

  • insert 事件:

    • INSERT

    • INSERT ... SELECT(用于INSERT子句中引用的表)

    • REPLACE

    • REPLACE ... SELECT(用于REPLACE子句中引用的表)

    • LOAD DATA

    • LOAD XML

  • update 事件:

    • UPDATE

    • UPDATE ... WHERE(用于UPDATE子句中引用的表)

阻止特定事件的执行

event 项可以包括一个abort项,指示是否阻止符合条件的事件执行。abort使得可以编写规则来阻止特定 SQL 语句的执行。

重要

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

在 MySQL 8.0.28 或更高版本中创建的带有SYSTEM_USER权限的帐户在创建时会自动分配AUDIT_ABORT_EXEMPT权限。在进行 MySQL 8.0.28 或更高版本的升级过程时,如果没有现有帐户被分配该权限,则现有帐户也会被分配AUDIT_ABORT_EXEMPT权限。

abort项必须出现在event项内。例如:

"event": {
  "name": *qualifying event subclass names*
  "abort": *condition*
}

对于由name项选择的事件子类,abort操作为真或假,取决于condition的评估。如果条件评估为真,则阻止事件。否则,事件继续执行。

condition规范可以简单到truefalse,也可以更复杂,以至于评估取决于事件特征。

此过滤器阻止INSERTUPDATEDELETE语句:

{
  "filter": {
    "class": {
      "name": "table_access",
      "event": {
        "name": [ "insert", "update", "delete" ],
        "abort": true
      }
    }
  }
}

这个更复杂的过滤器仅针对特定表(finances.bank_account)阻止相同的语句:

{
  "filter": {
    "class": {
      "name": "table_access",
      "event": {
        "name": [ "insert", "update", "delete" ],
        "abort": {
          "and": [
            { "field": { "name": "table_database.str", "value": "finances" } },
            { "field": { "name": "table_name.str", "value": "bank_account" } }
          ]
        }
      }
    }
  }
}

由过滤器匹配并阻止的语句会向客户端返回错误:

ERROR 1045 (28000): Statement was aborted by an audit log filter

并非所有事件都可以被阻止(参见表 8.36,“每个事件类和子类组合的日志和中止特性”)。对于无法被阻止的事件,审计日志会向错误日志写入警告,而不是阻止它。

尝试定义一个过滤器,其中abort项出现在event项之外时,会出现错误。

逻辑运算符

逻辑运算符(andornot)允许构建复杂条件,从而编写更高级的过滤配置。以下log项仅记录具有特定值和长度的general_command字段的general事件:

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "log": {
          "or": [
            {
              "and": [
                { "field": { "name": "general_command.str",    "value": "Query" } },
                { "field": { "name": "general_command.length", "value": 5 } }
              ]
            },
            {
              "and": [
                { "field": { "name": "general_command.str",    "value": "Execute" } },
                { "field": { "name": "general_command.length", "value": 7 } }
              ]
            }
          ]
        }
      }
    }
  }
}
引用预定义变量

要在log条件中引用预定义变量,请使用variable项,该项接受namevalue项并测试命名变量与给定值的相等性:

"variable": {
  "name": "*variable_name*",
  "value": *comparison_value*
}

如果variable_name具有值comparison_value,则为真,否则为假。

示例:

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "log": {
          "variable": {
            "name": "audit_log_connection_policy_value",
            "value": "::none"
          }
        }
      }
    }
  }
}

每个预定义变量对应一个系统变量。通过编写测试预定义变量的过滤器,您可以通过设置相应的系统变量来修改过滤器操作,而无需重新定义过滤器。例如,通过编写测试audit_log_connection_policy_value预定义变量值的过滤器,您可以通过更改audit_log_connection_policy系统变量的值来修改过滤器操作。

audit_log_*xxx*_policy系统变量用于废弃的传统模式审计日志(参见第 8.4.5.10 节,“传统模式审计日志过滤”)。使用基于规则的审计日志过滤时,这些变量仍然可见(例如,使用SHOW VARIABLES),但除非编写包含引用它们的结构的过滤器,否则对它们的更改不会产生任何效果。

以下列表描述了variable项的允许的预定义变量:

  • audit_log_connection_policy_value

    此变量对应于audit_log_connection_policy系统变量的值。该值是一个无符号整数。表 8.40,“audit_log_connection_policy_value Values”显示了允许的值以及相应的audit_log_connection_policy值。

    表 8.40 audit_log_connection_policy_value Values

    对应的 audit_log_connection_policy 值
    0"::none" NONE
    1"::errors" ERRORS
    2"::all" ALL

    "::*xxx*"值是象征性伪常量,可以代替文字数字值。它们必须被引用为字符串,并且区分大小写。

  • audit_log_policy_value

    此变量对应于audit_log_policy系统变量的值。该值是一个无符号整数。表 8.41,“audit_log_policy_value Values”显示了允许的值以及相应的audit_log_policy值。

    表 8.41 audit_log_policy_value Values

    对应的 audit_log_policy 值
    0"::none" NONE
    1"::logins" LOGINS
    2"::all" ALL
    3"::queries" QUERIES

    "::*xxx*"值是象征性伪常量,可以代替文字数字值。它们必须被引用为字符串,并且区分大小写。

  • audit_log_statement_policy_value

    此变量对应于audit_log_statement_policy系统变量的值。该值是一个无符号整数。表 8.42,“audit_log_statement_policy_value Values”显示了允许的值以及相应的audit_log_statement_policy值。

    表 8.42 audit_log_statement_policy_value Values

    对应的 audit_log_statement_policy 值
    0"::none" NONE
    1"::errors" ERRORS
    2"::all" ALL

    "::*xxx*"值是象征性伪常量,可以代替文字数字值。它们必须被引用为字符串,并且区分大小写。

引用预定义函数

要在 log 条件中引用预定义函数,请使用 function 项,该项接受 nameargs 项分别指定函数名称及其参数:

"function": {
  "name": "*function_name*",
  "args": *arguments*
}

name 项应仅指定函数名称,不包括括号或参数列表。

args 项必须满足以下条件:

  • 如果函数不需要参数,则不应提供 args 项。

  • 如果函数需要参数,则需要一个 args 项,并且参数必须按照函数描述中列出的顺序给出。参数可以是预定义变量、事件字段或字符串或数字常量。

如果参数数量不正确或参数类型与函数所需的正确数据类型不符,将会出现错误。

示例:

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "log": {
          "function": {
            "name": "find_in_include_list",
            "args": [ { "string": [ { "field": "user.str" },
                                    { "string": "@"},
                                    { "field": "host.str" } ] } ]
          }
        }
      }
    }
  }
}

前面的过滤器根据当前用户是否在 audit_log_include_accounts 系统变量中找到来确定是否记录 generalstatus 事件。该用户是使用事件中的字段构建的。

以下列表描述了 function 项的允许预定义函数:

  • audit_log_exclude_accounts_is_null()

    检查 audit_log_exclude_accounts 系统变量是否为 NULL。在定义与传统审计日志实现对应的过滤器时,此函数可能会有所帮助。

    参数:

    无。

  • audit_log_include_accounts_is_null()

    检查 audit_log_include_accounts 系统变量是否为 NULL。在定义与传统审计日志实现对应的过滤器时,此函数可能会有所帮助。

    参数:

    无。

  • debug_sleep(millisec)

    休眠指定的毫秒数。此函数用于性能测量。

    debug_sleep() 仅适用于调试版本。

    参数:

    • millisec:指定要休眠的毫秒数的无符号整数。
  • find_in_exclude_list(account)

    检查账户字符串是否存在于审计日志排除列表中(audit_log_exclude_accounts 系统变量的值)。

    参数:

    • account:指定用户账户名称的字符串。
  • find_in_include_list(account)

    检查账户字符串是否存在于审计日志包含列表中(audit_log_include_accounts 系统变量的值)。

    参数:

    • account:指定用户账户名称的字符串。
  • query_digest([str])

    此函数具有不同的行为,具体取决于是否给出参数:

    • 没有参数时,query_digest 返回与当前事件中语句文本对应的语句摘要值。

    • 有参数时,query_digest 返回一个布尔值,指示参数是否等于当前语句摘要。

    参数:

    • str:此参数是可选的。如果提供,则指定要与当前事件中语句的摘要进行比较的语句摘要。

    例子:

    function项不包含参数,因此query_digest将当前语句摘要作为字符串返回:

    "function": {
      "name": "query_digest"
    }
    

    function项包含一个参数,因此query_digest返回一个布尔值,指示参数是否等于当前语句摘要:

    "function": {
      "name": "query_digest",
      "args": "SELECT ?"
    }
    

    此函数是在 MySQL 8.0.26 中添加的。

  • string_find(text, substr)

    检查substr值是否包含在text值中。此搜索区分大小写。

    参数:

    • text:要搜索的文本字符串。

    • substr:要在text中搜索的子字符串。

事件字段值的替换

截至 MySQL 8.0.26,审计过滤器定义支持替换某些审计事件字段,以便记录的事件包含替换值而不是原始值。此功能使记录的审计记录可以包含语句摘要而不是文字语句,这对于可能暴露敏感值的 MySQL 部署非常有用。

审计事件中的字段替换工作原理如下:

  • 字段替换在审计过滤器定义中指定,因此必须按照第 8.4.5.7 节,“审计日志过滤”中描述的方式启用审计日志过滤。

  • 并非所有字段都可以被替换。表 8.43,“可替换事件字段”显示了哪些字段可以在哪些事件类中被替换。

    表 8.43 可替换事件字段

    事件类 字段名称
    general general_query.str
    table_access query.str
  • 替换是有条件的。过滤器定义中的每个替换规范都包括一个条件,使得可根据条件结果更改或保持替换字段不变。

  • 如果发生替换,替换规范将使用允许用于此目的的函数指示替换值。

如表 8.43,“可替换事件字段”所示,目前唯一可替换的字段是包含语句文本的字段(出现在generaltable_access类事件中)。此外,唯一允许用于指定替换值的函数是query_digest。这意味着唯一允许的替换操作是将语句文字文本替换为其对应的摘要。

因为字段替换发生在早期的审计阶段(在过滤期间),所以无论稍后写入的日志格式是 XML 还是 JSON 输出(即,审计日志插件生成的日志格式),都需要选择是写入语句文字文本还是摘要值。

字段替换可以在不同级别的事件粒度上进行:

  • 要为类中的所有事件执行字段替换,请在类级别过滤事件。

  • 要更细粒度地执行替换,可以包括额外的事件选择项。例如,您可以仅针对给定事件类的特定子类执行字段替换,或仅在具有特定特征的字段的事件中执行。

在过滤器定义中,通过包含print项来指定字段替换,其语法如下:

"print": {
  "field": {
    "name": "*field_name*",
    "print": *condition*,
    "replace": *replacement_value*
  }
}

print项中,其field项使用这三个项目来指示替换是如何发生的:

  • name:替换(可能)发生的字段。field_name必须是 Table 8.43,“可替换事件字段”中显示的字段之一。

  • print:确定是保留原始字段值还是替换它的条件:

    • 如果condition评估为true,则该字段保持不变。

    • 如果condition评估为false,则发生替换,使用replace项的值。

    要无条件替换字段,请指定条件如下:

    "print": false
    
  • replace:当print条件评估为false时要使用的替换值。使用function项指定replacement_value

例如,此过滤器定义适用于general类中的所有事件,将语句文字替换为其摘要:

{
  "filter": {
    "class": {
      "name": "general",
      "print": {
        "field": {
          "name": "general_query.str",
          "print": false,
          "replace": {
            "function": {
              "name": "query_digest"
            }
          }
        }
      }
    }
  }
}

前面的过滤器使用这个print项来无条件地通过其摘要值替换general_query.str中包含的语句文字:

"print": {
  "field": {
    "name": "general_query.str",
    "print": false,
    "replace": {
      "function": {
        "name": "query_digest"
      }
    }
  }
}

print项可以以不同的方式编写以实现不同的替换策略。刚刚显示的replace项使用这个function结构指定替换文本,以返回表示当前语句摘要的字符串:

"function": {
  "name": "query_digest"
}

query_digest函数也可以以另一种方式使用,作为返回布尔值的比较器,从而使其在print条件中可用。为此,提供一个参数,指定一个比较语句摘要:

"function": {
  "name": "query_digest",
  "args": "*digest*"
}

在这种情况下,query_digest根据当前语句摘要是否与比较摘要相同返回truefalse。以这种方式使用query_digest使得过滤器定义能够检测与特定摘要匹配的语句。以下结构中的条件仅对具有等于SELECT ?的摘要的语句为真,因此仅对不匹配摘要的语句进行替换:

"print": {
  "field": {
    "name": "general_query.str",
    "print": {
      "function": {
        "name": "query_digest",
        "args": "SELECT ?"
      }
    },
    "replace": {
      "function": {
        "name": "query_digest"
      }
    }
  }
}

仅为匹配摘要的语句执行替换,使用not来反转条件:

"print": {
  "field": {
    "name": "general_query.str",
    "print": {
      "not": {
        "function": {
          "name": "query_digest",
          "args": "SELECT ?"
        }
      }
    },
    "replace": {
      "function": {
        "name": "query_digest"
      }
    }
  }
}

假设您希望审计日志仅包含语句摘要而不是文字语句。为实现此目的,您必须对包含语句文本的所有事件执行替换;即generaltable_access类别中的事件。较早的过滤器定义显示了如何无条件地替换general事件的语句文本。要对table_access事件执行相同操作,请使用类似但将类别从general更改为table_access,字段名称从general_query.str更改为query.str的过滤器:

{
  "filter": {
    "class": {
      "name": "table_access",
      "print": {
        "field": {
          "name": "query.str",
          "print": false,
          "replace": {
            "function": {
              "name": "query_digest"
            }
          }
        }
      }
    }
  }
}

结合generaltable_access过滤器会产生一个执行所有包含语句文本事件替换的单一过滤器:

{
  "filter": {
    "class": [
      {
        "name": "general",
        "print": {
          "field": {
            "name": "general_query.str",
            "print": false,
            "replace": {
              "function": {
                "name": "query_digest"
              }
            }
          }
        }
      },
      {
        "name": "table_access",
        "print": {
          "field": {
            "name": "query.str",
            "print": false,
            "replace": {
              "function": {
                "name": "query_digest"
              }
            }
          }
        }
      }
    ]
  }
}

仅对类别中的某些事件执行替换,向过滤器添加指示更具体替换发生时间的项目。以下过滤器适用于table_access类中的事件,但仅对insertupdate事件执行替换(保持readdelete事件不变):

{
  "filter": {
    "class": {
      "name": "table_access",
      "event": {
        "name": [
          "insert",
          "update"
        ],
        "print": {
          "field": {
            "name": "query.str",
            "print": false,
            "replace": {
              "function": {
                "name": "query_digest"
              }
            }
          }
        }
      }
    }
  }
}

该过滤器对应于列出的账户管理语句的general类事件执行替换(效果是隐藏语句中的凭据和数据值):

{
  "filter": {
    "class": {
      "name": "general",
      "event": {
        "name": "status",
        "print": {
          "field": {
            "name": "general_query.str",
            "print": false,
            "replace": {
              "function": {
                "name": "query_digest"
              }
            }
          }
        },
        "log": {
          "or": [
            {
              "field": {
                "name": "general_sql_command.str",
                "value": "alter_user"
              }
            },
            {
              "field": {
                "name": "general_sql_command.str",
                "value": "alter_user_default_role"
              }
            },
            {
              "field": {
                "name": "general_sql_command.str",
                "value": "create_role"
              }
            },
            {
              "field": {
                "name": "general_sql_command.str",
                "value": "create_user"
              }
            }
          ]
        }
      }
    }
  }
}

有关可能的general_sql_command.str值的信息,请参阅测试事件字段值。

替换用户过滤器

在某些情况下,过滤器定义可以动态更改。为此,在现有的filter中定义一个filter配置。例如:

{
  "filter": {
    "id": "main",
    "class": {
      "name": "table_access",
      "event": {
        "name": [ "update", "delete" ],
        "log": false,
        "filter": {
          "class": {
            "name": "general",
            "event" : { "name": "status",
                        "filter": { "ref": "main" } }
          },
          "activate": {
            "or": [
              { "field": { "name": "table_name.str", "value": "temp_1" } },
              { "field": { "name": "table_name.str", "value": "temp_2" } }
            ]
          }
        }
      }
    }
  }
}

当子过滤器中的activate项评估为true时,将激活新的过滤器。在顶层filter中使用activate是不允许的。

通过在子过滤器中使用ref项引用原始过滤器id,可以将新过滤器替换为原始过滤器。

所示的过滤器的操作方式如下:

  • main过滤器等待table_access事件,无论是update还是delete

  • 如果在temp_1temp_2表上发生updatedelete table_access事件,则将过滤器替换为内部过滤器(没有id,因为没有必要显式引用它)。

  • 如果命令结束被标记(general / status事件),则会向审计日志文件写入条目,并将过滤器替换为main过滤器。

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

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

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

注意

在定义中使用的任何id值仅与该定义相关。它们与audit_log_filter_id系统变量的值无关。

posted @ 2024-06-23 16:26  绝不原创的飞龙  阅读(2)  评论(0编辑  收藏  举报