Hashicorp Vault 密钥库

本教程演示如何设置一个使用 Vault 的 K/V 引擎 作为持久且安全的密钥存储的 KES 服务器。

K E S C l i e n t K E S S e r v e r V a u l t

先决条件

要启动开发服务器或使用 Vault CLI 与 Vault 进行交互,请下载 Vault 二进制文件

Vault 服务器

KES 需要 Vault K/V 引擎 v1v2 以及 AppRole 或 Kubernetes 身份验证方法的凭据。

如果您没有可用的现有 Vault 集群,请执行以下操作之一

  1. 按照 Hashicorp Vault 安装指南 创建一个新的集群。
  2. 创建一个 单节点开发实例

以下文档讨论了使用 AppRole 身份验证方法为开发目的设置单节点开发实例。

单节点开发 Vault 实例

以下命令以开发模式启动 Vault 服务器。

这将在开发模式下启动一个单节点 Vault 服务器,侦听 127.0.0.1:8200。开发服务器是短暂的,**不**适合在生产环境中运行。

将 Vault 连接到 Vault CLI

  1. 设置 VAULT_ADDR 端点

    Vault CLI 需要知道 Vault 端点

    export VAULT_ADDR='https://127.0.0.1:8200'
    
  2. 设置 VAULT_TOKEN

    Vault CLI 需要一个身份验证令牌来执行操作。

    export VAULT_TOKEN=hvs.O6QNQB33ksXtMxtlRKlRZL0R
    

    将令牌值替换为您自己的 Vault 访问令牌,例如 vault server -dev 命令输出中提供的 Root token

  3. 启用 K/V 后端

    KES 将密钥存储在 Vault K/V 后端。Vault 提供了两个 K/V 引擎v1v2

    MinIO 建议使用 K/V v1 引擎。

    KES 的 Vault 策略取决于所选的 K/V 引擎版本。为 K/V v1 设计的策略不适用于 K/V v2 引擎。同样,为 K/V v2 设计的策略不适用于 K/V v1 引擎。

    有关从 v1 迁移到 v2 的更多信息,请参阅 有关从 v1 升级的 HashiCorp 文档

设置 KES 对 Vault 的访问权限

  1. 创建 Vault 策略

    Vault 策略定义了 KES 服务器可以访问的 API 路径。创建一个名为 kes-policy.hcl 的文本文件。

    策略的内容因使用的 K/V 引擎而异。

  2. 将策略写入 Vault

    以下命令在 Vault 中创建策略

    vault policy write kes-policy kes-policy.hcl
    
  3. 启用身份验证

    此步骤允许 KES 服务器对 Vault 进行身份验证。在本教程中,我们使用 AppRole 身份验证方法。

    vault auth enable approle
    
  4. 创建 KES 角色

    以下命令在 Vault 中添加一个名为 kes-server 的新角色

    vault write auth/approle/role/kes-server token_num_uses=0  secret_id_num_uses=0  period=5m
    
  5. 将策略绑定到角色

    以下命令将 kes-server 角色绑定到 kes-policy

    vault write auth/approle/role/kes-server policies=kes-policy
    
  6. 生成 AppRole ID

    为 KES 服务器请求 AppRole ID

    vault read auth/approle/role/kes-server/role-id 
    
  7. 生成 AppRole 密钥

    为 KES 服务器请求 AppRole 密钥

    vault write -f auth/approle/role/kes-server/secret-id 
    

    AppRole 密钥打印为 secret_id。您可以忽略 secret_id_accessor

KES 服务器设置

  1. 生成 KES 服务器私钥和证书

    以下命令为 IP 127.0.0.1 和 DNS 名称 localhost(作为 SAN)生成新的 TLS 私钥 server.key 和自签名 X.509 证书 server.cert。如果您想使用其他 IP 或 DNS 名称(例如 10.1.2.3https://kes.example.net)引用您的 KES 服务器,请相应地调整 --ip 和/或 --dns 参数。

    kes identity new --key server.key --cert server.cert --ip "127.0.0.1" --dns localhost
    

    上述命令生成自签名证书。如果您已经有办法为您的服务器颁发证书,则可以使用这些证书。

    其他 X.509 证书生成工具也有效。例如,您可以使用 openssl

    openssl ecparam -genkey -name prime256v1 | openssl ec -out server.key
    
    openssl req -new -x509 -days 30 -key server.key -out server.cert \
        -subj "/C=/ST=/L=/O=/CN=localhost" -addext "subjectAltName = IP:127.0.0.1"
    
  2. 生成 API 密钥

    以下命令生成新的 KES API 密钥。

    kes identity new
    

    输出类似于以下内容

    Your API key:
    
       kes:v1:ABfa1xsnIV0lltXQC8tHXic8lte7J6hT7EoGv6+s5QCW
    
    This is the only time it is shown. Keep it secret and secure!
    
    Your Identity:
    
       cf6c535e738c1dd47a1d746366fde7f0309d1e0a8471b9f6e909833906afbbfa
    
    The identity is not a secret. It can be shared. Any peer
    needs this identity in order to verify your API key.
    
    The identity can be computed again via:
    
        kes identity of kes:v1:ABfa1xsnIV0lltXQC8tHXic8lte7J6hT7EoGv6+s5QCW   
    

    生成的 identity **不是**密钥,可以公开共享。它稍后将在 KES 配置文件中用作管理员身份或分配给策略。

    API 密钥 本身**是**密钥,不应共享。您可以随时重新计算 API 密钥的身份。

  3. 配置 KES 服务器

    创建 KES 服务器配置文件:config.yml

    确保策略部分中的身份与 client.crt 身份匹配。添加之前获得的 approle role_idsecret_id

    admin:
      # Use the identity generated above by 'kes identity new'.
      identity: "" # For example: cf6c535e738c1dd47a1d746366fde7f0309d1e0a8471b9f6e909833906afbbfa
    
    tls:
      key: private.key    # The KES server TLS private key
      cert: public.crt    # The KES server TLS certificate
    
    keystore:
       vault:
         endpoint: https://127.0.0.1:8200
         version:  v1 # The K/V engine version - either "v1" or "v2".
         engine:   kv # The engine path of the K/V engine. The default is "kv".
         approle:
           id:     "" # Your AppRole ID
           secret: "" # Your AppRole Secret
    
  4. 启动 KES 服务器

KES CLI 访问

  1. 设置 KES_SERVER 端点

    以下环境变量指定 KES CLI 应该与之通信的 KES 服务器

    export KES_SERVER=https://127.0.0.1:7373
    
  2. 定义 CLI 访问凭据

    以下环境变量设置客户端用于与 KES 服务器通信的密钥

    export KES_API_KEY=kes:v1:ABfa1xsnIV0lltXQC8tHXic8lte7J6hT7EoGv6+s5QCW
    

    将值替换为服务器的 API 密钥。启动服务器时,服务器的 API 密钥会显示在输出中。

  3. 测试配置

    例如,检查服务器的状态

    kes status -k
    

    使用密钥生成新的数据加密密钥

    kes key dek my-key-1 -k
    

    命令输出类似于以下内容

    {
      plaintext : UGgcVBgyQYwxKzve7UJNV5x8aTiPJFoR+s828reNjh0=
      ciphertext: eyJhZWFkIjoiQUVTLTI1Ni1HQ00tSE1BQy1TSEEtMjU2IiwiaWQiOiIxMTc1ZjJjNDMyMjNjNjNmNjY1MDk5ZDExNmU3Yzc4NCIsIml2IjoiVHBtbHpWTDh5a2t4VVREV1RSTU5Tdz09Iiwibm9uY2UiOiJkeGl0R3A3bFB6S21rTE5HIiwiYnl0ZXMiOiJaaWdobEZrTUFuVVBWSG0wZDhSYUNBY3pnRWRsQzJqWFhCK1YxaWl2MXdnYjhBRytuTWx0Y3BGK0RtV1VoNkZaIn0=
    }
    

将 KES 与 MinIO 服务器一起使用

MinIO 服务器需要 KES 才能启用服务器端数据加密。

请参阅 KES for MinIO 指南,了解将新的 KES 服务器与 MinIO 服务器一起使用所需的额外步骤。

配置参考

以下部分描述了密钥加密服务 (KES) 配置设置,以使用 HashiCorp Vault 密钥存储作为根 KMS 来存储外部密钥,例如用于 MinIO 服务器上的服务器端加密的密钥。

MinIO 服务器需要扩展的权限
MinIO 服务器 RELEASE.2023-02-17T17-52-43Z 开始,MinIO 需要扩展的 KES 权限才能正常工作。本节中的示例配置包含所有必需的权限。

高级配置

这些其他配置步骤可以解决特定问题。

使用 K/V 前缀的多租户

Vault 可以作为多个隔离的 KES 租户的后端。每个 KES 租户可以由N个副本组成。可以有M个 KES 租户连接到同一个 Vault 服务器/集群。

这意味着N × M个 KES 服务器实例可以连接到单个 Vault。

在这些配置中,每个 KES 租户在 K/V 密钥引擎中都有一个单独的前缀。对于每个 KES 租户,必须有一个对应的 Vault 策略。

  • 对于 K/V v1

    path "kv/<tenant-name>/*" {
       capabilities = [ "create", "read", "delete" ]
    }
    
  • 对于 K/V v2

    path "kv/data/<tenant-name>/*" {
      capabilities = [ "create", "read" ]
    }
    path "kv/metadata/<tenant-name>/*" {
      capabilities = [ "list", "delete" ]       
    }
    

为每个 KES 租户创建一个不同的配置文件。该文件包含租户要使用的 Vault K/V 前缀。

keystore:
   vault:
     endpoint: https://127.0.0.1:8200
     prefix: <tenant-name>
     approle:
       id:     "" # Your AppRole ID
       secret: "" # Your AppRole Secret
       retry:  15s
     status:
       ping: 10s
     tls:
       ca: vault.crt # Manually trust the vault certificate since we use self-signed certificates

使用 Vault 命名空间的多租户

Vault 可以作为多个隔离的 KES 租户的后端。每个 KES 租户可以由N个副本组成。可以有M个 KES 租户连接到同一个 Vault 服务器/集群。

这意味着N × M个 KES 服务器实例可以连接到单个 Vault。

因此,每个 KES 租户在 K/V 密钥引擎中都有一个单独的前缀。对于每个 KES 租户,必须有一个对应的 Vault 策略。

  • 对于 K/V v1

    path "kv/<tenant-name>/*" {
       capabilities = [ "create", "read", "delete" ]
    }
    
  • 对于 K/V v2

    path "kv/data/<tenant-name>/*" {
       capabilities = [ "create", "read" ]
    }
    path "kv/metadata/<tenant-name>/*" {
       capabilities = [ "list", "delete" ]       
    }
    

为每个 KES 租户使用不同的配置文件。该文件包含 KES 租户应使用的 Vault 命名空间。

keystore:
   vault:
     endpoint: https://127.0.0.1:8200
     namespace: <vault-namespace>
     approle:
       id:     "" # Your AppRole ID
       secret: "" # Your AppRole Secret
       retry:  15s
     status:
       ping: 10s
     tls:
       ca: vault.crt # Manually trust the vault certificate since we use self-signed certificates

加密 Vault 存储的密钥

HashiCorp 的Transit 功能提供了一种加密和解密存储在 Vault 中的密钥的方法。这提供了一层额外的加密,在某些特定情况下可能很有用。

启用后,HashiCorp 会在 Vault 中存储一个密钥来加密或解密存储在 Vault 中的其他密钥。然后,KES 使用 Vault 管理的密钥来存储或检索 Vault 中的密钥。

潜在数据丢失
如果指定的传输密钥不正确、已禁用、已删除或无法访问,则 KES 无法检索任何 Vault 密钥,也无法执行依赖于这些密钥的任何加密/解密操作。

要配置 Transit,请将以下部分添加到 KES 配置 YAML 的keystore.vault部分

keystore:
  vault:
    transit:      # Optionally encrypt keys stored on the K/V engine with a Vault-managed key.
      engine: ""  # The path of the transit engine - e.g. "my-transit". If empty, defaults to: transit (Vault default)
      key: ""     # The key name that should be used to encrypt entries stored on the K/V engine.

参考