延伸 MySQL 9.0  /  ...  /  編寫金鑰環外掛程式

4.4.12 編寫金鑰環外掛程式

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.PLUGINSSHOW 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_xxx 函式與金鑰環服務 API 公開的 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 選項。