8.4.4.8 使用 HashiCorp Vault 密钥环插件
MySQL Enterprise Edition 商业产品中包含了keyring_hashicorp
插件。要了解更多关于商业产品的信息,请访问https://www.mysql.com/products/。
keyring_hashicorp
密钥环插件使用 HashiCorp Vault 作为后端存储。插件支持 HashiCorp Vault AppRole 认证。MySQL 服务器本地存储中不永久存储任何密钥信息(可选的内存密钥缓存可能用作中间存储)。MySQL 服务器侧执行随机密钥生成,随后将密钥存储到 HashiCorp Vault 中。
keyring_hashicorp
插件支持标准 MySQL 密钥环服务接口中的所有函数。这些函数的密钥操作可以在两个级别上访问:
-
SQL 接口:在 SQL 语句中,调用
keyring_functions
描述在第8.4.4.12节,“通用密钥环密钥管理函数”中。 -
C 接口:在 C 语言代码中,调用
keyring_service
描述在第7.6.9.2节,“密钥环服务”中。
示例(使用 SQL 接口):
SELECT keyring_key_generate('MyKey', 'AES', 32);
SELECT keyring_key_remove('MyKey');
关于keyring_hashicorp
插件允许的密钥值特征,请访问第8.4.4.10节,“支持的密钥环密钥类型和长度”。
要安装keyring_hashicorp
,请按照第8.4.4.3节,“Keyring Plugin Installation”中的一般指令,并将特定的keyring_hashicorp
配置信息应用于这里。插件专门的配置包括为连接到HashiCorp Vault准备证书和密钥文件,以及配置HashiCorp Vault本身。以下部分提供了必要的指令。
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 平台,可能需要对其他平台进行调整。
这些指令生成的证书是自签名的,这可能不是非常安全。在您使用这些文件后,可以考虑从注册证书权威机构获取证书/密钥材料。
-
准备公司和 HashiCorp Vault 服务器密钥。
使用以下命令生成密钥文件:
openssl genrsa -aes256 -out company.key 4096 openssl genrsa -aes256 -out vault.key 2048
这些命令产生了持有公司私钥(
company.key
)和 Vault 服务器私钥(vault.key
)的文件。这些密钥是随机生成的 RSA 密钥,分别为 4096 和 2048 位。每个命令都需要输入密码。在测试环境中,可以忽略密码。要禁用密码,请省略
-aes256
参数。密钥文件包含敏感信息,应该存储在安全的位置。密码(也敏感)将在后续需要,因此请记下并存储在安全的位置。
(可选)要检查密钥文件内容和有效性,请使用以下命令:
openssl rsa -in company.key -check openssl rsa -in vault.key -check
-
创建公司 CA 证书。
使用以下命令创建一个名为
company.crt
的公司 CA 证书文件,该证书有效期为 365 天(请在单行输入命令):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 []:
使用适当的值回答提示。
-
创建证书签名请求。
要创建HashiCorp Vault服务器证书,需要为新创建的服务器密钥准备证书签名请求。创建一个名为
request.conf
的配置文件,包含以下行。如果HashiCorp Vault服务器不在本地主机上, substitute适当的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
)是一个中间文件,用于创建服务器证书的输入文件。 -
创建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 设置,以便测试keyring_hashicorp
插件的步骤。
测试设置类似于生产设置,但生产使用 HashiCorp Vault 需要考虑更多安全因素,例如使用非自签名证书和将公司证书存储在系统信任存储器中。您需要实现满足操作需求的任何额外安全步骤。
这些步骤假设已经创建了在证书和密钥准备中提到的证书和密钥文件。如果您没有这些文件,请查看该部分。
-
获取 HashiCorp Vault 二进制文件。
从https://www.vaultproject.io/downloads.html下载适合您的平台的 HashiCorp Vault 二进制文件。
解压缩归档以生成可执行的vault命令,该命令用于执行 HashiCorp Vault 操作。如果必要,请将安装命令的目录添加到系统路径中。
(Optional) HashiCorp Vault 支持自动完成选项,易于使用。更多信息请见https://learn.hashicorp.com/vault/getting-started/install#command-completion。
-
创建 HashiCorp Vault 服务器配置文件。
准备一个名为
config.hcl
的配置文件,内容如下。对于tls_cert_file
、tls_key_file
和path
值,请将路径名称更改为适用于您的系统。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
-
启动HashiCorp Vault服务器。
要启动Vault服务器,请使用以下命令,其中
-config
选项指定刚创建的配置文件路径:vault server -config=config.hcl
在这个步骤中,您可能会被提示为Vault服务器私钥存储在
vault.key
文件中的密码。服务器应该启动,显示一些控制台信息(IP、端口等)。
为了继续输入剩余命令,请将vault server命令置于背景或在另一个终端中打开。
-
初始化HashiCorp Vault服务器。
Note本步骤中的操作仅在首次启动Vault时需要,以获取未封锁密钥和根令牌。随后的Vault实例重启只需使用未封锁密钥来解封锁。
执行以下命令(假设Bourne shell语法):
export VAULT_SKIP_VERIFY=1 vault operator init -n 1 -t 1
第一个命令使vault命令临时忽略系统信任存储中没有添加公司证书的事实。它补偿了我们的自签名CA未被添加到该存储的 facto。 (对于生产用途,应该将该证书添加到该存储中。)
第二个命令创建一个单一的解密密钥,要求在解密时输入单一的解密密钥。 (在生产环境中,一台实例将有多个解密密钥,每个密钥都需要输入以解密它。这些密钥应该交付给公司内的密钥管理员。使用单个密钥可能被认为是一个安全问题,因为这允许vault被单个密钥管理员解密。)
Vault 应该回复关于解密密钥和根令牌的信息,plus一些额外的文本(实际的解密密钥和根令牌值与这里显示的不同):
... Unseal Key 1: I2xwcFQc892O0Nt2pBiRNlnkHzTUrWS+JybL39BjcOE= Initial Root Token: s.vTvXeo3tPEYehfcd9WH7oUKz ...
将解密密钥和根令牌存储在安全位置。
-
解密 HashiCorp Vault 服务器。
使用以下命令解密 Vault 服务器:
vault operator unseal
当被提示输入解密密钥时,使用之前在 Vault 初始化期间获得的密钥。
Vault 应该生成输出,指示设置完成且vault已解密。
-
登录到 HashiCorp Vault 服务器并验证其状态。
准备用于以 root 身份登录的环境变量:
vault login s.vTvXeo3tPEYehfcd9WH7oUKz
在该命令中,将 token 值替换为之前在 Vault 初始化期间获得的根令牌内容。
验证 Vault 服务器状态:
vault status
输出应该包含这些行(其他行):
... Initialized true Sealed false ...
-
设置 HashiCorp Vault 认证和存储。
Note本步骤中描述的操作只需要在 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
-
添加 AppRole 安全策略。
Note本步骤中描述的操作仅在 Vault 实例首次运行时需要。后续不需要重复执行。
准备一个策略,以允许之前创建的角色访问适当的秘密。创建一个名为
mysql.hcl
的新文件,内容如下:path "kv/mysql/*" { capabilities = ["create", "read", "update", "delete", "list"] }
Notekv/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 认证的更多信息,请访问https://www.vaultproject.io/docs/auth/approle.html。
插件库文件包含keyring_hashicorp
插件和可加载函数keyring_hashicorp_update_config()
。当插件初始化和终止时,它将自动加载和卸载函数,不需要手动加载和卸载。
keyring_hashicorp
插件支持以下配置参数表所示的参数。要指定这些参数,分配对应系统变量的值。
Configuration Parameter | System Variable | Mandatory |
---|---|---|
HashiCorp Server URL | keyring_hashicorp_server_url |
否 |
AppRole role ID | keyring_hashicorp_role_id |
是 |
AppRole secret ID | keyring_hashicorp_secret_id |
是 |
Store path | keyring_hashicorp_store_path |
是 |
Authorization Path | keyring_hashicorp_auth_path |
否 |
CA certificate file path | keyring_hashicorp_ca_path |
否 |
Cache control | keyring_hashicorp_caching |
否 |
在服务器启动过程中可用,keyring_hashicorp
必须使用--early-plugin-load
选项加载。正如前表所示,多个插件相关的系统变量是必需的,并且必须设置。例如,在服务器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路由都以协议版本前缀(在前面的示例中可以看到在keyring_hashicorp_store_path
和keyring_hashicorp_auth_path
值中显示为/v1/
)开头。如果HashiCorp开发了新的协议版本,可能需要在配置中将/v1/
更改为其他内容。
MySQL 服务器使用 AppRole 认证对 HashiCorp Vault 进行身份验证。认证成功需要在 Vault 提供两个秘密,角色 ID 和秘密 ID,这些值类似于用户名和密码。要指定这两个 ID,分配它们的相应值给 keyring_hashicorp_role_id
和 keyring_hashicorp_secret_id
系统变量。setup 程序还将生成一个存储路径为 /v1/kv/mysql
,该值应分配给 keyring_hashicorp_commit_store_path
。
在插件初始化时,keyring_ hashicorp
尝试使用配置值连接到 HashiCorp Vault 服务器。如果连接成功,插件将存储对应的系统变量值,其中包含_commit_
。例如,在连接成功后,插件将存储keyring_hashicorp_role_id
和keyring_hashicorp_store_path
的值在keyring_hashicorp_commit_role_id
和keyring_hashicorp_commit_store_path
中。
在运行时可以使用keyring_hashicorp_update_config()
函数进行重新配置:
-
使用
SET
语句将所需的新值分配给前面表格中显示的配置系统变量。这些赋值本身对插件的继续操作没有影响。 -
调用
keyring_hashicorp_update_config()
以使插件重新配置并使用新变量值连接到 HashiCorp Vault 服务器。 -
如果连接成功,插件将更新的配置值存储在对应的系统变量中,这些变量名中包含
_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_
变量反映了用于该连接的值。
如果您没有在服务器启动时设置必需的系统变量,或者其他插件初始化错误发生,初始化失败。在这种情况下,您可以使用 runtime 重新配置过程来初始化插件而不需要重启服务器。
关于keyring_hashicorp
插件特定的系统变量和函数的详细信息,请见第8.4.4.16节,“Keyring System Variables”,和第8.4.4.13节,“Plugin-Specific Keyring Key-Management Functions”。