排查 CMEK 和默认设置错误

本文档介绍了如何查找和减少常见的 CMEK 配置错误,以及如何识别设置默认资源位置时发生的错误。

排查设置默认资源位置时遇到的问题

您尝试更新组织或文件夹的默认存储位置,但该命令失败,并显示类似如下的错误:

ERROR: (gcloud.logging.settings.update) INVALID_ARGUMENT: The KMS key location must match the storage location. Received KMS key location: us-central1, storage location: us-west1
- '@type': type.googleapis.com/google.rpc.DebugInfo
  detail: '[ORIGINAL ERROR] generic::invalid_argument: The KMS key location must match
    the storage location. Received KMS key location: us-central1, storage location:
    us-west1 [google.rpc.error_details_ext] { message: "The KMS key location must
    match the storage location. Received KMS key location: us-central1, storage location:
    us-west1" }'

如需解决此错误,请为组织或文件夹设置默认存储位置,以匹配组织或文件夹的 Cloud Key Management Service 密钥位置。

排查 VPC Service Controls 和网域限定共享问题

您已将 CMEK 配置为您的组织或文件夹的默认资源设置,或者您创建了启用了 CMEK 的日志存储桶。然后配置 VPC Service Controls。配置 VPC Service Controls 后,您可以在 VPC Service Controls 中限制对 Cloud Key Management Service 的访问权限,或启用网域限定共享

至少会发生以下情况之一:

  • 您收到了 Cloud Logging 发送的关于 CMEK 访问问题的通知。

  • 您在组织或文件夹中创建新的 Google Cloud 项目时,注意到没有为 _Default_Required 日志存储分区启用 CMEK。

  • 从启用了 CMEK 的日志存储分区读取数据时,收到错误。您看到的错误与以下错误类似:

    ERROR: (gcloud.logging.read) FAILED_PRECONDITION: service account `cmek-PROJECT_IDgcp-sa-logging.iam.gserviceaccount.com` must have both encrypt and decrypt access to the CMEK KMS key `projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY`
    
  • 在启用 CMEK 的情况下创建或更新日志存储分区时,会收到错误。您看到的错误与以下错误类似:

    ERROR: (gcloud.logging.buckets.create) service account `cmek-PROJECT_ID@gcp-sa-logging.iam.gserviceaccount.com` must have both encrypt and decrypt access to the CMEK KMS key `projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY`
    - '@type': type.googleapis.com/google.rpc.DebugInfo
      detail: '[ORIGINAL ERROR] generic::permission_denied: Request is prohibited by
      organization's policy. vpcServiceControlsUniqueIdentifier: <var>ERRORID</var>;'
    

如需确定这些问题是否由 VPC Service Controls 配置所致,请执行以下操作:

  1. 确定包含 CMEK 配置的资源的 Cloud Logging 设置。资源可以是项目、文件夹或组织。如果您创建了启用了 CMEK 的日志存储分区,请选择“项目”资源。

    项目

    gcloud logging settings describe --project=PROJECT_ID
    

    在运行该命令之前,请将 PROJECT_ID 替换为包含日志存储桶的项目 ID。

    文件夹

    gcloud logging settings describe --folder=FOLDER_ID
    

    在运行该命令之前,请将 FOLDER_ID 替换为文件夹的 ID。

    单位

    gcloud logging settings describe --organization=ORGANIZATION_ID
    

    在运行该命令之前,请将 ORGANIZATION_ID 替换为组织的 ID。

    上一条命令会返回类似于以下内容的信息:

    kmsServiceAccountId: KMS_SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
    loggingServiceAccountId: SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
    

    对于组织和文件夹,还会返回以下字段:

    kmsKeyName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY
    

    kmsKeyName 字段的值包含存储密钥的 Google Cloud 项目。

  2. 确定您是否需要迁移服务帐号:

    • 如果 kmsServiceAccountId 字段的值具有 service- 前缀,则无需迁移服务帐号。如需了解 CMEK 配置错误,请参阅本文档的排查 CMEK 问题部分。

    • 如果 kmsServiceAccountId 的值具有前缀 cmek-,请继续执行下一步。

  3. 确认您必须通过停用网域限定共享或从 VPC Service Controls 受限服务列表中移除 Cloud Key Management Service 来迁移服务帐号。

    如果错误已解决,那么为了解决故障,您必须将受影响的资源迁移到新的服务帐号。如需了解这些步骤,请参阅下一部分。

迁移 CMEK 服务账号

以下过程介绍了如何更改 Cloud Logging 用于访问已配置的 Cloud Key Management Service 密钥的服务帐号。更改服务帐号解决了 VPC Service Controls 和网域限定共享方面的已知问题。

  1. 确定资源的 loggingServiceAccountId。资源可以是项目、文件夹或组织。如果您创建了启用了 CMEK 的日志存储分区,请选择“项目”资源。

    项目

    gcloud logging settings describe --project=PROJECT_ID
    

    在运行该命令之前,请将 PROJECT_ID 替换为包含日志存储桶的项目 ID。

    文件夹

    gcloud logging settings describe --folder=FOLDER_ID
    

    在运行该命令之前,请将 FOLDER_ID 替换为文件夹的 ID。

    单位

    gcloud logging settings describe --organization=ORGANIZATION_ID
    

    在运行该命令之前,请将 ORGANIZATION_ID 替换为组织的 ID。

    上一条命令会返回类似于以下内容的信息:

    kmsServiceAccountId: KMS_SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
    loggingServiceAccountId: SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
    

    对于组织和文件夹,还会返回以下字段:

    kmsKeyName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY
    

    kmsKeyName 字段的值包含存储密钥的 Google Cloud 项目。

  2. 如果您为组织或文件夹配置了默认资源设置,请执行以下操作:

    1. KMS_PROJECT_ID 中,将 Cloud Key Management Service CryptoKey Encrypter/Decrypter 角色授予 loggingServiceAccountId 字段标识的服务帐号。

    2. 运行以下 curl 命令,该命令会更改资源使用的 Cloud Key Management Service 服务帐号。

      项目

      不适用。

      文件夹

      curl -X PATCH -H "Authorization: Bearer \"$(gcloud auth print-access-token)\"" -H "Content-Type: application/json; charset=utf-8" -d '{"kmsServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com"}' https://logging.googleapis.com/v2/folders/FOLDER_ID/settings?updateMask=kmsServiceAccountId
      

      在运行该命令之前,请执行以下操作:

      • FOLDER_ID 替换为文件夹的 ID。
      • SERVICE_ACCT_NAME 替换为之前找到的 loggingServiceAccountId

      单位

      curl -X PATCH -H "Authorization: Bearer \"$(gcloud auth print-access-token)\"" -H "Content-Type: application/json; charset=utf-8" -d '{"kmsServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com"}' https://logging.googleapis.com/v2/organizations/ORGANIZATION_ID/settings?updateMask=kmsServiceAccountId
      

      在运行该命令之前,请执行以下操作:

      • ORGANIZATION_ID 替换为组织的 ID。
      • SERVICE_ACCT_NAME 替换为之前找到的 loggingServiceAccountId

      上一条命令的结果类似于以下内容:

      {
        "name": ".../settings",
        "kmsKeyName": "projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY",
        "kmsServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com",
        "storageLocation": "...",
        "loggingServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com"
      }
      
  3. 对于每个包含已启用 CMEK 的现有日志存储分区的 Google Cloud 项目或文件夹,请执行以下操作:

    1. 在项目或文件夹中,对于每个启用了 CMEK 的日志存储桶,执行以下操作:

      1. 确定存储 Cloud Key Management Service 密钥的 Google Cloud 项目:

        项目

        gcloud logging buckets describe BUCKET_ID --location=LOCATION --project=PROJECT_ID
        

        在运行该命令之前,请执行以下操作:

        • PROJECT_ID 替换为包含日志存储桶的项目 ID。
        • LOCATION 替换为日志存储桶的位置。

        文件夹

        gcloud logging buckets describe BUCKET_ID --location=LOCATION --folder=FOLDER_ID
        

        在运行该命令之前,请执行以下操作:

        • FOLDER_ID 替换为文件夹的 ID。
        • LOCATION 替换为日志存储桶的位置。

        上一条命令的结果类似于以下内容:

        cmekSettings:
          kmsKeyName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY
          kmsKeyVersionName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY/cryptoKeyVersions/1
          serviceAccountId: KMS_SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
        createTime: '2022-10-31T12:00:00.0000000Z'
        lifecycleState: ACTIVE
        name: projects/PROJECT_ID/locations/LOCATION/buckets/BUCKET_ID
        retentionDays: 30
        createTime: '2022-10-31T13:00:00.0000000Z'
        
      2. 转到拥有 Cloud Key Management Service 密钥 KMS_PROJECT_ID 的 Google Cloud 项目,然后将 Cloud Key Management Service CryptoKey Encrypter/Decrypter 角色授予 loggingServiceAccountId 字段标识的服务帐号。

    2. 对于项目,运行以下 curl 命令,该命令会更改 Cloud Key Management Service 服务帐号:

      项目

      curl -X PATCH -H "Authorization: Bearer \"$(gcloud auth print-access-token)\"" -H "Content-Type: application/json; charset=utf-8" -d '{"kmsServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com"}' https://logging.googleapis.com/v2/projects/PROJECT_ID/settings?updateMask=kmsServiceAccountId
      

      在运行该命令之前,请执行以下操作:

      • PROJECT_ID 替换为包含日志存储桶的项目 ID。
      • SERVICE_ACCT_NAME 替换为之前找到的 loggingServiceAccountId

      文件夹

      您无需采取任何行动,因为您在上一步中更改了文件夹使用的 Cloud Key Management Service 服务帐号。

      上一条命令的结果类似于以下内容:

      {
        "name": ".../settings",
        "kmsServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com",
        "loggingServiceAccountId": "SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com"
      }
      
  4. 对于每个启用了 CMEK 的日志存储桶,请执行以下操作:

    1. 轮替 Cloud KMS 密钥

    2. 确认迁移。日志存储桶的父资源决定了要运行的 Google Cloud CLI 命令。父级可以是项目、文件夹或组织。

      项目

      gcloud logging buckets describe BUCKET_ID --location=LOCATION --project=PROJECT_ID
      

      在运行该命令之前,请执行以下操作:

      • PROJECT_ID 替换为包含日志存储桶的项目 ID。
      • LOCATION 替换为日志存储桶的位置。

      文件夹

      gcloud logging buckets describe BUCKET_ID --location=LOCATION --folder=FOLDER_ID
      

      在运行该命令之前,请执行以下操作:

      • FOLDER_ID 替换为文件夹的 ID。
      • LOCATION 替换为日志存储桶的位置。

      对于项目,上一条命令的结果类似于以下内容:

      cmekSettings:
        kmsKeyName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY
        kmsKeyVersionName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY/cryptoKeyVersions/1
        serviceAccountId: SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
      createTime: '2022-10-31T12:00:00.0000000Z'
      lifecycleState: ACTIVE
      name: projects/PROJECT_ID/locations/LOCATION/buckets/BUCKET_ID
      retentionDays: 30
      createTime: '2022-10-31T13:00:00.0000000Z'
      

      确保 serviceAccountId 与前面找到的 loggingServiceAccountId 匹配。

  5. 在撤消上一个服务帐号的权限之前,请等待至少 30 分钟。如果您在撤消旧服务帐号的权限后遇到任何问题,请恢复权限并联系 Cloud 支持团队。

排查 CMEK 问题

配置 CMEK 时,包含 Cloud KMS 密钥的 Google Cloud 项目会收到相关问题的通知。例如,当 KMS_KEY_NAME 无效、关联的服务帐号没有所需的 Cloud Key Management Service CryptoKey Encrypter/Decrypter 角色时,或者对密钥的访问权限被停用时,更新失败。

配置 CMEK 后,至少会发生以下情况:

  • 您收到了 Cloud Logging 发送的关于 CMEK 访问问题的通知。

  • 您在组织或文件夹中创建新的 Google Cloud 项目时,注意到没有为 _Default_Required 日志存储分区启用 CMEK。

  • 从启用了 CMEK 的日志存储分区读取数据,或尝试创建或更新日志存储分区时,会收到错误。

通知会提供有关失败情况的信息,并包含您可以采取的缓解措施:

错误 建议
加密密钥权限被拒

与您的 Google Cloud 项目关联的 Logging 服务帐号没有足够的 IAM 权限,无法对指定的 Cloud KMS 密钥执行操作。请按照错误中的说明操作或参阅以下文档:

加密密钥已停用 指定的 Cloud KMS 密钥已停用。按照错误中的说明重新启用密钥。
加密密钥已销毁

指定的 Cloud KMS 密钥已销毁。请按照说明操作,或参阅以下文档:

识别包含 Cloud KMS 密钥的项目

如需识别包含日志存储桶、文件夹或组织使用的加密密钥的 Google Cloud 项目的 ID,请执行以下操作:

项目

gcloud logging settings describe --project=PROJECT_ID

在运行该命令之前,请将 PROJECT_ID 替换为包含日志存储桶的项目 ID。

文件夹

gcloud logging settings describe --folder=FOLDER_ID

在运行该命令之前,请将 FOLDER_ID 替换为文件夹的 ID。

单位

gcloud logging settings describe --organization=ORGANIZATION_ID

在运行该命令之前,请将 ORGANIZATION_ID 替换为组织的 ID。

上一条命令会返回类似于以下内容的信息:

kmsServiceAccountId: KMS_SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com
loggingServiceAccountId: SERVICE_ACCT_NAME@gcp-sa-logging.iam.gserviceaccount.com

对于组织和文件夹,还会返回以下字段:

kmsKeyName: projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KMS_KEY_RING/cryptoKeys/KEY

kmsKeyName 字段的值包含存储密钥的 Google Cloud 项目。

验证密钥的可用性

如需验证密钥的可用性,请运行以下命令以列出所有密钥:

gcloud kms keys list \
--location=KMS_KEY_LOCATION \
--keyring=KMS_KEY_RING

此命令以表格格式返回每个密钥的相关信息。输出的第一行是列名称列表:

NAME PURPOSE ...

验证 Cloud KMS 密钥在命令的输出中是否被列为 ENABLED,以及密钥的用途是否为对称加密:PURPOSE 列必须包含 ENCRYPT_DECRYPT,且 PRIMARY_STATE 列必须包含 ENABLED

如有必要,请创建新密钥

验证权限配置

与组织的 CMEK 设置关联的服务账号必须拥有已配置密钥的 Cloud KMS CryptoKey Encrypter/Decrypter 角色。

如需列出密钥的 IAM 政策,请运行以下命令:

gcloud kms keys get-iam-policy KMS_KEY_NAME

如有必要,请向密钥添加包含 Cloud KMS CryptoKey Encrypter/Decrypter 角色的服务账号。