28.2.4.12 编写密钥环插件

MySQL Server 支持密钥环服务,该服务使内部服务器组件和插件能够安全地存储敏感信息,以便以后检索。本节介绍如何编写服务器端密钥环插件,服务功能可以使用该插件来执行密钥 Management 操作。有关常规密钥环的信息,请参见第 6.4.4 节“ MySQL 密钥环”

此处的说明基于 MySQL 源代码发行版本plugin/keyring目录中的源代码。该目录中的源文件实现了名为keyring_file的插件,该插件使用服务器主机本地的文件进行数据存储。

要编写密钥环插件,请在插件源文件中包含以下头文件。根据插件的功能和要求,可能还需要其他 MySQL 或常规头文件。

#include <mysql/plugin_keyring.h>

plugin_keyring.h包含plugin.h,因此您无需显式包括后者。 plugin.h定义MYSQL_KEYRING_PLUGIN服务器插件类型和声明插件所需的数据结构。 plugin_keyring.h定义特定于密钥环插件的数据结构。

像任何 MySQL 服务器插件一样,密钥环插件具有通用的插件 Descriptors(请参见第 28.2.4.2.1 节,“服务器插件库和插件 Descriptors”)。在keyring.cc中,keyring_file的一般 Descriptors 如下所示:

mysql_declare_plugin(keyring_file)
{
  MYSQL_KEYRING_PLUGIN,     /* type                                     */
  &keyring_descriptor,      /* descriptor                               */
  "keyring_file",           /* name                                     */
  "Oracle Corporation",     /* author                                   */
  "store/fetch authentication data to/from a flat file", /* description */
  PLUGIN_LICENSE_GPL,
  keyring_init,             /* init function (when loaded)              */
  keyring_deinit,           /* deinit function (when unloaded)          */
  0x0100,                   /* version                                  */
  NULL,                     /* status variables                         */
  keyring_system_variables, /* system variables                         */
  NULL,
  0,
}
mysql_declare_plugin_end;

name成员(keyring_file)table 示插件名称。这是INFORMATION_SCHEMA.PLUGINSSHOW PLUGINS显示的名称。

通用 Descriptors 也指向keyring_system_variables,该结构向SHOW VARIABLES语句公开系统变量:

static struct st_mysql_sys_var *keyring_system_variables[]= {
  MYSQL_SYSVAR(data),
  NULL
};

keyring_init初始化函数创建数据文件(如果它不存在),然后读取它并初始化密钥库。 keyring_deinit函数释放与文件关联的数据结构。

常规 Descriptors 中的keyring_descriptor值指向特定于类型的 Descriptors。对于密钥环插件,此 Descriptors 具有以下结构:

struct st_mysql_keyring
{
  int interface_version;
  my_bool (*mysql_key_store)(const char *key_id, const char *key_type,
                             const char* user_id, const void *key, size_t key_len);
  my_bool (*mysql_key_fetch)(const char *key_id, char **key_type,
                             const char *user_id, void **key, size_t *key_len);
  my_bool (*mysql_key_remove)(const char *key_id, const char *user_id);
  my_bool (*mysql_key_generate)(const char *key_id, const char *key_type,
                                const char *user_id, size_t key_len);
};

特定于类型的 Descriptors 具有以下成员:

  • interface_version:按照惯例,类型特定的插件 Descriptors 以给定插件类型的接口版本开头。服务器在加载插件时会检查interface_version,以查看插件是否与其兼容。对于密钥环插件,interface_version成员的值为MYSQL_KEYRING_INTERFACE_VERSION(在plugin_keyring.h中定义)。

  • mysql_key_store:混淆密钥并将其存储在密钥环中的功能。

  • mysql_key_fetch:对密钥进行模糊处理并从密钥环中检索密钥的功能。

  • mysql_key_remove:从钥匙圈中删除钥匙的功能。

  • mysql_key_generate:生成新的随机密钥并将其存储在密钥环中的函数。

对于keyring_file插件,特定于类型的 Descriptors 如下所示:

static struct st_mysql_keyring keyring_descriptor=
{
  MYSQL_KEYRING_INTERFACE_VERSION,
  mysql_key_store,
  mysql_key_fetch,
  mysql_key_remove,
  mysql_key_generate
};

密钥环插件实现的mysql_key_xxx函数类似于密钥环服务 API 公开的my_key_xxx函数。例如,mysql_key_store插件功能类似于my_key_store密钥环服务功能。有关密钥环服务功能的参数及其用法的信息,请参阅第 28.3.2 节“密钥环服务”

要编译和安装插件库文件,请使用第 28.2.4.3 节“编译和安装插件库”中的说明。要使该库文件可供使用,请将其安装在插件目录(由plugin_dir系统变量命名的目录)中。对于keyring_file插件,当您从源代码构建 MySQL 时会对其进行编译和安装。它也包含在二进制发行版中。构建过程将生成一个共享对象库,其名称为keyring_file.so(后缀.so可能因平台而异)。

密钥环插件通常在服务器启动过程的早期加载,以便内置插件和可能依赖于它们的存储引擎可以使用它们。对于keyring_file,请使用服务器my.cnf文件中的这些行,并根据需要调整平台的.so后缀:

[mysqld]
early-plugin-load=keyring_file.so

有关插件加载的其他信息,请参见第 5.5.1 节“安装和卸载插件”

要验证插件安装,请检查INFORMATION_SCHEMA.PLUGINStable 或使用SHOW PLUGINS语句(请参见第 5.5.2 节“获取服务器插件信息”)。例如:

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

安装keyring_file插件后,它将公开一个系统变量,该变量指示用于安全信息存储的数据文件的位置:

mysql> SHOW VARIABLES LIKE 'keyring_file%';
+-------------------+----------------------------------+
| Variable_name     | Value                            |
+-------------------+----------------------------------+
| keyring_file_data | /usr/local/mysql/keyring/keyring |
+-------------------+----------------------------------+

有关keyring_file_data变量的说明,请参见第 5.1.7 节“服务器系统变量”

要在测试插件后禁用它,请在不使用命名插件的--early-plugin-load选项的情况下重新启动服务器。