MySQL 服务器支持一个密钥环服务,使内部服务器组件和插件能够安全地存储敏感信息以供以后检索。本节介绍如何编写一个服务器端密钥环插件,该插件可供服务函数用于执行密钥管理操作。有关密钥环的一般信息,请参见 MySQL 密钥环.
MySQL 8.4 删除了已弃用的密钥环插件,转而使用密钥环组件。例如,使用 component_keyring_file
而不是 keyring_file
。有关相关信息,请参见 密钥环组件与密钥环插件.
此处的说明基于 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 服务器插件一样,都有一个通用插件描述符(参见 第 4.4.2.1 节,“服务器插件库和插件描述符”)。在 keyring.cc
中,keyring_file
的通用描述符如下所示
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
) 指示插件名称。这是 INFORMATION_SCHEMA.PLUGINS
或 SHOW PLUGINS
显示的名称。
通用描述符还引用了 keyring_system_variables
,这是一个结构,它向 SHOW VARIABLES
语句公开一个系统变量
static struct st_mysql_sys_var *keyring_system_variables[]= {
MYSQL_SYSVAR(data),
NULL
};
keyring_init
初始化函数在数据文件不存在的情况下创建它,然后读取它并初始化密钥存储。 keyring_deinit
函数释放与文件关联的数据结构。
keyring_descriptor
值在通用描述符中指向特定于类型的描述符。对于密钥环插件,此描述符具有以下结构
struct st_mysql_keyring
{
int interface_version;
bool (*mysql_key_store)(const char *key_id, const char *key_type,
const char* user_id, const void *key, size_t key_len);
bool (*mysql_key_fetch)(const char *key_id, char **key_type,
const char *user_id, void **key, size_t *key_len);
bool (*mysql_key_remove)(const char *key_id, const char *user_id);
bool (*mysql_key_generate)(const char *key_id, const char *key_type,
const char *user_id, size_t key_len);
};
特定于类型的描述符具有以下成员
interface_version
:按照惯例,特定于类型的插件描述符以给定插件类型的接口版本开头。服务器在加载插件时检查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
插件,特定于类型的描述符如下所示
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_
函数类似于密钥环服务 API 公开的 xxx
my_key_
函数。例如, xxx
mysql_key_store
插件函数类似于 my_key_store
密钥环服务函数。有关密钥环服务函数的参数及其使用方法的信息,请参见 密钥环服务.
要编译和安装插件库文件,请使用 第 4.4.3 节,“编译和安装插件库” 中的说明。要使库文件可用,请将其安装到插件目录(由 plugin_dir
系统变量指定的目录)中。对于 keyring_file
插件,在您从源代码构建 MySQL 时,它将被编译和安装。它也包含在二进制发行版中。构建过程会生成一个名为 keyring_file.so
的共享对象库(.so
后缀可能因平台而异)。
密钥环插件通常在服务器启动过程的早期加载,以便它们可供可能依赖它们的内置插件和存储引擎使用。对于 keyring_file
,在服务器 my.cnf
文件中使用以下行,根据需要调整平台的 .so
后缀
[mysqld]
early-plugin-load=keyring_file.so
有关插件加载的更多信息,请参见 安装和卸载插件.
要验证插件安装,请检查 INFORMATION_SCHEMA.PLUGINS
表或使用 SHOW PLUGINS
语句(参见 获取服务器插件信息)。例如
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 |
+-------------------+----------------------------------+
要禁用插件(在测试后),请在没有 --early-plugin-load
选项(该选项指定插件名称)的情况下重新启动服务器。