文档

使用 AWS Secrets Manager 根 KMS 的服务器端对象加密

MinIO 服务器端加密 (SSE) 在写入操作期间保护对象,允许客户端利用服务器处理能力在存储层 (加密在静止状态下) 保护对象。SSE 还为围绕安全锁定和擦除的监管和合规性要求提供了关键功能。

MinIO SSE 使用 密钥加密服务 (KES) 和外部根密钥管理服务 (KMS) 来执行大规模的安全加密操作。根 KMS 提供对外部密钥 (EK) 的有状态和安全存储,而 KES 是无状态的,并从根管理的 EK 派生额外的加密密钥。

此过程假设一台运行 MinIO 和 KES 容器的单台主机,以 AWS Secrets Manager 作为外部根 KMS。作为此过程的一部分,您将

  1. 部署一个配置为使用 AWS Secrets Manager 作为根 KMSKES 容器。

  2. 在 Vault 上创建一个新的 EK,用于与 SSE 一起使用。

  3. 单节点单驱动器模式 中部署一个 MinIO 服务器容器,该容器配置为使用 KES 容器来支持 SSE

  4. 配置自动存储桶默认 SSE-KMS

对于生产编排环境,使用 MinIO Kubernetes 运算符来部署启用 SSE 的租户,并配置为与 AWS Key Management Service 一起使用。

对于生产裸金属环境,请参阅 Linux 上的 MinIO 文档,了解使用 KES 和 AWS Key Management Service 配置 MinIO 的教程。

重要

在 MinIO 部署上启用 SSE 会自动使用默认加密密钥加密该部署的后端数据。

MinIO *需要* 访问 KES *和* 根 KMS 才能解密后端并正常启动。您不能在以后禁用 KES 或“撤消” SSE 配置。

先决条件

确保可以访问 AWS Secrets Manager 和密钥管理服务

此过程假设可以访问并熟悉 AWS Secrets ManagerAWS Key Management Service

MinIO 特别需要以下 AWS 设置或配置

  • 一个新的 AWS 编程访问 用户,以及相应的访问密钥和秘密密钥。

  • 一个策略,允许创建的用户访问 AWS Secrets Manager 和 AWS 密钥管理服务。以下策略授予了必要的最小权限。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "minioSecretsManagerAccess",
          "Action": [
            "secretsmanager:CreateSecret",
            "secretsmanager:DeleteSecret",
            "secretsmanager:GetSecretValue",
            "secretsmanager:ListSecrets"
          ],
          "Effect": "Allow",
          "Resource": "*"
        },
        {
          "Sid": "minioKmsAccess",
          "Action": [
            "kms:Decrypt",
            "kms:DescribeKey",
            "kms:Encrypt"
          ],
          "Effect": "Allow",
          "Resource": "*"
        }
      ]
    }
    

    AWS 提供了 SecretsManagerReadWriteAWSKeyManagementServicePowerUser 预置角色,这些角色满足并超过了所需的最低权限。

安装 Podman 或类似的容器管理界面

此过程假设您有一个可工作的 Podman 安装,配置为在“Rootfull”模式下运行。

“Rootless”模式可能无法提供足够的权限来运行 KES,并使用必要的安全设置。有关更多信息,请参见相关的 “rootless” 文档

(Podman) 使用 AWS Secrets Manager 部署 MinIO 和 KES,并进行服务器端加密

在开始这些步骤之前,请创建以下文件夹。

mkdir -P ~/minio-kes-aws/certs
mkdir -P ~/minio-kes-aws/config
mkdir -P ~/minio-kes-aws/minio

对于 Windows 主机,请将路径替换为 Windows 风格的路径,例如 C:\minio-kes-vault\

1) 为 KES 和 MinIO 生成 TLS 证书

以下命令创建两个 TLS 证书,这些证书在创建后 30 天内到期。

  • 一个用于 KES 的 TLS 证书,用于保护它与 AWS Secrets Manager 服务之间的通信。

  • 一个用于 MinIO 的 TLS 证书,用于对 KES 执行 mTLS 身份验证。

在生产环境中谨慎使用

不要将作为此过程的一部分生成的 TLS 证书用于任何长期开发或生产环境。

遵循组织/行业关于 TLS 证书生成和管理的最佳实践。本过程不包括有关创建有效证书(例如,格式良好、最新且受信任)的完整指南。

# These commands output keys to ~/minio-kes-aws/certs and ~/minio-kes-aws/certs on the host operating system

podman run --rm  \
  -v ~/minio-kes-aws/certs:/certs  \
  quay.io/minio/kes:2024-01-11T13-09-29Z identity new  kes_server \
    --key  /certs/kes-server.key  \
    --cert /certs/kes-server.cert  \
    kes-server

podman run --rm  \
  -v ~/minio-kes-aws/certs:/certs  \
  quay.io/minio/kes:2024-01-11T13-09-29Z identity new minio_server \
    --key  /certs/minio-kes.key  \
    --cert /certs/minio-kes.cert  \
    minio-server

根据您的 Vault 配置,您可能需要将 kes-server.cert 作为受信任的证书颁发机构传递。有关更多信息,请参见 Hashicorp Vault 配置文档。有关信任第三方 CA 的说明,请参见客户端文档。

2) 创建 KES 和 MinIO 配置

  1. 创建 KES 配置文件

    使用您喜欢的文本编辑器创建配置文件。以下示例使用 nano

    nano ~/minio-kes-aws/config/kes-config.yaml
    

    KES 使用 YAML 格式的配置文件。以下示例 YAML 指定了使用 AWS Secrets Manager 启用 SSE 所需的最小字段。

    address: 0.0.0.0:7373
    
    # Disable the root identity, as we do not need that level of access for
    # supporting SSE operations.
    root: disabled
    
    # Specify the TLS keys generated in the previous step here
    # For production environments, use keys signed by a known and trusted
    # Certificate Authority (CA).
    tls:
      key:  /certs/kes-server.key
      cert: /certs/kes-server.cert
    
    # Create a policy named 'minio' that grants access to the
    # /create, /generate, and /decrypt KES APIs for any key name
    # KES uses mTLS to grant access to this policy, where only the client
    # whose TLS certificate hash matches one of the "identities" can
    # use this policy. Specify the hash of the MinIO server TLS certificate
    # hash here.
    policy:
      minio:
        allow:
        - /v1/key/create/*   # You can replace these wildcard '*' with a string prefix to restrict key names
        - /v1/key/generate/* # e.g. '/minio-'
        - /v1/key/decrypt/*
        - /v1/key/bulk/decrypt
        - /v1/key/list/*
        - /v1/status
        - /v1/metrics
        - /v1/log/audit
        - /v1/log/error
        identities:
        - ${MINIO_IDENTITY_HASH} # Replace with the output of 'kes identity of minio-kes.cert'
    
                                 # In production environments, each client connecting to KES must
                                 # Have their TLS hash listed under at least one `policy`.
    
    # Specify the connection information for the KMS and Secrets Manager endpoint.
    # The endpoint should be resolvable from the host.
    # This example assumes that the associated AWS account has the necessary
    # access key and secret key
    keystore:
      aws:
        secretsmanager:
          endpoint: secretsmanager.REGION.amazonaws.com # use the Secrets Manager endpoint for your region
          region: REGION # e.g. us-east-1
          kmskey: "" # Optional. The root AWS KMS key to use for cryptographic operations. Formerly described as the "Customer Master Key".
          credentials:
            accesskey: "AWSACCESSKEY" # AWS Access Key
            secretkey: "AWSSECRETKEY" # AWS Secret Key
    
    • MINIO_IDENTITY_HASH 设置为 MinIO mTLS 证书的身份哈希。

      以下命令计算所需的哈希值。

      podman run --rm                                             \
         -v ~/minio-kes-aws/certs/certs:/certs                                \
         kes:2024-01-11T13-09-29Z tool identity of /certs/minio-kes.cert
      
    • MINIO_IDENTITY_HASH 设置为 MinIO mTLS 证书的身份哈希。

      以下命令计算所需的哈希值。

      podman run --rm                                             \
         -v ~/minio-kes-aws/certs/certs:/certs                                \
         kes:2024-01-11T13-09-29Z tool identity of /certs/minio-kes.cert
      
    • REGION 替换为 AWS Secrets Manager 的相应区域。该值必须与 endpointregion 的值匹配。

    • AWSACCESSKEYAWSSECRETKEY 设置为相应的 AWS 凭据

  2. 创建 MinIO 环境文件

    使用您喜欢的文本编辑器创建环境文件。以下示例使用 nano

    nano ~/minio-kes-aws/config/minio
    

    此命令假定 minio-kes.certminio-kes.keykes-server.cert 证书可在指定位置访问。

    MINIO_ROOT_USER=myminioadmin
    MINIO_ROOT_PASSWORD=minio-secret-key-change-me
    MINIO_VOLUMES="/mnt/data"
    
    # KES Configurations
    
    MINIO_KMS_KES_ENDPOINT=https://127.0.0.1:7373
    MINIO_KMS_KES_CERT_FILE=/certs/minio-kes.cert
    MINIO_KMS_KES_KEY_FILE=/certs/minio-kes.key
    MINIO_KMS_KES_CAPATH=/certs/server.cert
    MINIO_KMS_KES_KEY_NAME=minio-backend-default-key
    MINIO_KMS_KES_ENCLAVE=<name>
    

    MinIO 使用 MINIO_KMS_KES_KEY_NAME 密钥进行以下加密操作。

    • 加密 MinIO 后端(IAM、配置等)。

    • 使用 SSE-KMS 加密对象(如果请求不包含特定的 EK)。

    • 使用 SSE-S3 加密对象。

    MinIO 使用 MINIO_KMS_KES_ENCLAVE 密钥来定义要使用的 KES enclave 的名称。

    • <name> 替换为要使用的 enclave 的名称。

    • 如果未定义,MinIO 不会发送任何 enclave 信息。这可能会导致使用有状态 KES 服务器的默认 enclave。

      KES enclave 将其关联的密钥与有状态 KES 服务器上的其他 enclave 隔离。

    minio-kes 证书仅允许 MinIO 部署与 KES 服务器之间的 mTLS 通信。它们不会为其他客户端连接到 MinIO 启用 TLS。

    如果密钥在根 KMS 上不存在,KES 会自动创建该密钥。

3) 创建 Pod 和容器

本节中的命令创建以下资源。

sudo podman pod create  \
  -p 9000:9000 -p 9001:9001 -p 7373:7373  \
  -v ~/minio-kes-aws/certs:/certs  \
  -v ~/minio-kes-aws/minio:/mnt/minio  \
  -v ~/minio-kes-aws/config:/etc/default/  \
  -n minio-kes-aws

sudo podman run -dt  \
  --cap-add IPC_LOCK  \
  --name kes-server  \
  --pod "minio-kes-aws"  \
  -e KES_SERVER=https://127.0.0.1:7373  \
  -e KES_CLIENT_KEY=/certs/kes-server.key  \
  -e KES_CLIENT_CERT=/certs/kes-server.cert  \
  quay.io/minio/kes:2024-01-11T13-09-29Z server  \
    --auth  \
    --config=/etc/default/kes-config.yaml  \

sudo podman run -dt  \
  --name minio-server  \
  --pod "minio-kes-aws"  \
  -e "MINIO_CONFIG_ENV_FILE=/etc/default/minio"  \
  quay.io/minio/minio:RELEASE.2024-02-17T01-15-57Z server  \
    --console-address ":9001"

您可以使用以下命令验证容器的状态。

# Should show three pods - one for the Pod, one for KES, and one for MinIO
sudo podman container ls

如果所有 Pod 都在运行,您可以通过在浏览器中打开 http://127.0.0.1:9000 并使用 MinIO 环境文件中指定的根凭据登录来连接到 MinIO 部署。

4) 生成新的加密密钥

在创建密钥之前解封 Vault

您必须在创建新的加密密钥之前解封支持的 Vault 实例。有关更多信息,请参见 Vault 文档中的 Seal/Unseal 部分。

MinIO 要求 EK 执行使用该密钥的 SSE 操作之前存在于根 KMS 上。使用 kes key create mc admin kms key create 创建一个新的 EK,用于与 SSE 一起使用。

以下命令使用 kes key create 命令在根 KMS 服务器上添加一个新的外部密钥 (EK),用于加密 MinIO 后端。

sudo podman run --rm  \
  -v ~/minio-kes-aws/certs:/certs  \
  -e KES_SERVER=https://127.0.0.1:7373  \
  -e KES_CLIENT_KEY=/certs/minio-kes.key  \
  -e KES_CLIENT_CERT=/certs/minio-kes.cert  \
  kes:2024-01-11T13-09-29Z key create -k my-new-encryption-key

您可以根据您的用例指定任何密钥名称,例如特定于桶的密钥 minio-mydata-key

5) 为桶启用 SSE-KMS

您可以使用 MinIO 控制台或 MinIO mc CLI 为桶启用默认的 SSE-KMS,并使用生成的密钥。

通过在您喜欢的浏览器中导航到 http://127.0.0.1:9001 并使用指定给 MinIO 容器的根凭据登录来打开 MinIO 控制台。

登录后,创建一个新桶并根据您的偏好命名它。选择齿轮图标以打开管理视图。

选择铅笔图标,它位于 加密 字段旁边,以打开用于配置桶默认 SSE 方案的模态。

选择 SSE-KMS,然后输入在上一步骤中创建的密钥的名称。

保存更改后,尝试将文件上传到桶中。在对象浏览器中查看该文件时,请注意,在侧边栏中,元数据包括 SSE 加密方案以及用于加密该对象密钥的信息。这表明该对象已成功加密。

以下命令

  • 为 MinIO 部署创建新的 别名

  • 创建一个用于存储加密数据的桶

  • 在该桶上启用 SSE-KMS 加密

mc alias set local http://127.0.0.1:9000 ROOTUSER ROOTPASSWORD

mc mb local/encryptedbucket
mc encrypt set SSE-KMS encrypted-bucket-key ALIAS/encryptedbucket

使用 mc cp 或任何具有 PutObject 函数的与 S3 兼容的 SDK 将文件写入桶。然后,您可以对文件运行 mc stat 以确认关联的加密元数据。

AWS 根 KMS 的配置参考

以下部分描述了每个 密钥加密服务 (KES) 配置设置,这些设置使用 AWS Secrets Manager 和 AWS Key Management System 作为 SSE 的根 KMS

重要

https://github.com/minio/minio/releases/tag/RELEASE.2023-02-17T17-52-43Z 开始,MinIO 需要扩展的 KES 权限才能正常工作。本节中的示例配置包含所有必需的权限。

具有 ${<STRING>} 的字段使用与 <STRING> 值匹配的环境变量。您可以使用此功能设置凭据,而无需将它们写入配置文件。

YAML 假设 MinIO 部署访问 KES 的权限集最小。作为替代方案,您可以省略 policy.minio-server 部分,而是将 ${MINIO_IDENTITY} 哈希设置为 ${ROOT_IDENTITY}

address: 0.0.0.0:7373
root: ${ROOT_IDENTITY}

tls:
  key: kes-server.key
  cert: kes-server.cert

policy:
  minio-server:
    allow:
    - /v1/key/create/*
    - /v1/key/generate/*
    - /v1/key/decrypt/*
    - /v1/key/bulk/decrypt
    - /v1/key/list/*
    - /v1/status
    - /v1/metrics
    - /v1/log/audit
    - /v1/log/error
    identities:
    - ${MINIO_IDENTITY}

keys:
  - name: "minio-encryption-key-alpha"
  - name: "minio-encryption-key-baker"
  - name: "minio-encryption-key-charlie"

keystore:
  secretsmanager:
    endpoint: secretsmanager.REGION.amazonaws
    region: REGION
    kmskey: ""
    credentials:
      accesskey: "${AWS_ACCESS_KEY}"
      secretkey: "${AWS_SECRET_KEY}"

描述

address

KES 服务器在启动时监听的网络地址和端口。默认为所有主机网络接口上的端口 7373

root

KES 超级用户 (root) 身份标识。使用其哈希值 (kes identity of client.cert) 与该值匹配的 TLS 证书连接的客户端可以访问所有 KES API 操作。

指定 disabled 以移除根身份,并仅依赖于 policy 配置来控制 KES 的身份和访问管理。

tls

KES 用于建立 TLS 安全通信的 TLS 私钥和证书。分别为 keycert 字段指定私钥 .key 和公钥 .cert 的完整路径。

policy

指定一个或多个 策略 来控制对 KES 服务器的访问。

MinIO SSE 需要访问以下 KES 加密 API

  • /v1/key/create/*

  • /v1/key/generate/*

  • /v1/key/decrypt/*

指定其他密钥不会扩展 MinIO SSE 功能,并且可能会违反围绕为客户端提供不必要的加密密钥操作访问权限的安全最佳实践。

可以通过在 * 之前指定前缀来限制 MinIO 在执行 SSE 时可以创建的密钥名称范围。例如,minio-sse-* 仅授予使用 minio-sse- 前缀创建、生成或解密密钥的访问权限。

KES 使用 mTLS 通过将 TLS 证书的哈希值与每个配置策略的 identities 进行比较来授权连接的客户端。使用 kes identity of 命令计算 MinIO mTLS 证书的身份,并将其添加到 policy.<NAME>.identities 数组中,以将 MinIO 与 <NAME> 策略关联。

keys

指定一个密钥数组,这些密钥必须存在于根 KMS 上,KES 才能成功启动。如果密钥不存在,KES 会尝试创建密钥,如果创建失败,则会退出并显示错误。在完成对所有指定密钥的验证之前,KES 不会接受任何客户端请求。

keystore.aws.secretsmanager

AWS Secrets Manager 和 AWS KMS 的配置。

  • endpoint - Secrets Manager 服务的端点,包括区域。

  • approle - 用于其他 AWS 服务的 AWS 区域。

  • kmskey - 用于加密操作的根 KMS 密钥。以前称为客户主密钥。

  • credentials - 用于对 Secrets Manager 和 KMS 执行身份验证操作的 AWS 凭据。

    指定的凭据必须具有适当的 权限