排查 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" }'

要解决此错误,请为 组织或文件夹的 ID 以匹配 组织或文件夹的 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 的日志桶,请选择 PROJECT 资源。

    项目

    gcloud logging settings describe --project=PROJECT_ID
    

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

    文件夹

    gcloud logging settings describe --folder=FOLDER_ID
    

    在运行此命令之前,请将 FOLDER_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 的日志桶,请选择 PROJECT 资源。

    项目

    gcloud logging settings describe --project=PROJECT_ID
    

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

    文件夹

    gcloud logging settings describe --folder=FOLDER_ID
    

    在运行此命令之前,请将 FOLDER_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 字段的值包括存储 密钥。

  2. 如果您为组织或 文件夹,然后执行以下操作:

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

    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 密钥的 Google Cloud 项目。 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/projects/PROJECT_ID/settings?updateMask=kmsServiceAccountId
      

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

      • PROJECT_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'
      

      确保 serviceAccountIdloggingServiceAccountId 匹配 。

  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 替换为 文件夹

单位

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 字段的值包括存储 密钥。

验证密钥的可用性

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

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 角色的服务账号。