本文档介绍了如何为 Pub/Sub 配置客户管理的加密密钥 (CMEK)。
默认情况下,Pub/Sub 使用 Google 拥有且由 Google 管理的密钥加密消息。无需进行额外设置即可使用 Google 管理的加密密钥。
CMEK 简介
CMEK 是您拥有的加密密钥,在 Cloud Key Management Service (Cloud KMS) 中进行管理和存储。如果您需要更好地控制用于保护 Pub/Sub 数据的加密密钥,则可以使用 CMEK。有些组织还强制要求使用 CMK。
借助 CMEK,您可以完全控制加密密钥,从而管理其生命周期、轮替和访问权限政策。使用 CMEK 配置 Pub/Sub 后,该服务会自动使用指定的密钥加密所有数据。使用 CMEK 的 Cloud KMS 用量可能会产生额外费用,具体取决于您的使用模式。
系统会为每条消息在以下状态和层级加密:
在应用层,Pub/Sub 会在收到消息后立即对每条消息进行单独加密。此实现增加了以下功能:
- 在数据中心内部链接上加密消息
- 启用客户管理的加密密钥 (CMEK)
适用于 Pub/Sub 的 CMEK
Pub/Sub 通过 CMEK 使用信封加密模式。在此方法中,Cloud KMS 不会对消息进行加密。Cloud KMS 用于对 Pub/Sub 为每个主题创建的 DEK(数据加密密钥)进行加密。这些 DEK 仅由 Pub/Sub 以加密(封装)形式存储。存储 DEK 之前,服务会将 DEK 发送到 Cloud KMS,以便使用在主题上指定的 KEK(密钥加密密钥)对 DEK 进行加密。系统大约每六个小时就会为每个主题生成一个新的 DEK。
Pub/Sub 向订阅发布消息之前,会使用系统为相应主题生成的最新 DEK 对消息进行加密。在消息即将传送给订阅者之前,Pub/Sub 会对消息进行解密。
准备工作
您可以使用 Google Cloud 控制台或 Google Cloud CLI 为 Pub/Sub 配置 CMEK。
完成以下任务:
启用 Cloud KMS API。
在 Cloud KMS 中创建密钥环和密钥。您无法删除密钥和密钥环。
如需了解如何完成这些任务,请参阅 Cloud KMS 快速入门指南。
由于 Pub/Sub 资源是全球性的,因此我们强烈建议您使用全局 Cloud KMS 密钥配置启用了 CMEK 的主题。根据主题发布者和订阅者的位置,使用区域性 Cloud KMS 密钥可能会产生对跨区域网络链接的依赖,而这种依赖其实是不必要的。
配置 CMEK 所需的角色和权限
Pub/Sub 使用 Google Cloud 服务代理访问 Cloud KMS。Pub/Sub 会在内部为每个项目保存该服务代理,该服务代理默认不会显示在 Google Cloud 控制台中的服务账号页面上。
Pub/Sub 服务代理的格式为 service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com
。
Pub/Sub 需要特定权限才能使用 CMEK 加密和解密数据。
请完成以下步骤以设置所需的访问权限:
向 Pub/Sub 服务代理授予 Cloud KMS Crypto Key Encrypter/Decrypter (
roles/cloudkms.cryptoKeyEncrypterDecrypter
) 角色。gcloud kms keys add-iam-policy-binding CLOUD_KMS_KEY_NAME \ --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
替换以下内容:
CLOUD_KMS_KEY_NAME:Cloud KMS 密钥的名称。
密钥的格式为
projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/CRYPTO_KEY
。示例见
projects/test-project/locations/us-central1/keyRings/test-keyring/cryptoKeys/test-key
。PROJECT_NUMBER:Pub/Sub 项目的项目编号。
如需详细了解如何授予 IAM 角色,请参阅向资源授予角色。
使用 CMEK 配置主题
您可以使用 Google Cloud 控制台或 gcloud CLI 为主题配置 CMEK。
控制台
如需使用 CMEK 创建主题,请按以下步骤操作:
gcloud
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
-
如需使用 CMEK 创建主题,请运行
gcloud pubsub topics create
命令:gcloud pubsub topics create TOPIC_ID --topic-encryption-key=ENCRYPTION_KEY
替换以下内容:
-
TOPIC_ID:主题的 ID 或名称。
如需详细了解如何命名主题,请参阅 主题、订阅、架构或快照命名指南。
-
ENCRYPTION_KEY:要为主题使用的 CMEK 的 ID。
格式为
projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/CRYPTO_KEY
。
-
更新主题的 CMEK
您可以灵活更改与 Pub/Sub 主题关联的 CMEK。您可以使用 gcloud CLI 更新 CMEK。不过,此项变更不会溯及既往。
在密钥更改之前发布到主题的消息仍使用原始密钥进行加密。如果主题是在未使用 CMEK 的情况下创建的,您可以稍后添加 CMEK。现有邮件仍会继续使用 Google 管理的默认加密方式进行保护。更改主题的 CMEK 不会重新加密之前发布的消息。这些邮件会继续使用其最初加密时所用的密钥进行保护。
Pub/Sub 针对密钥提供了一个缓存机制,该机制的有效期约为 5 分钟。Pub/Sub 最多可能需要此时长才能识别并开始使用新密钥版本。
审核日志
启用密钥、停用密钥或 Pub/Sub 使用密钥对消息进行加密和解密时,Cloud KMS 会生成审核日志。这在排查发布或传送问题时很有用。
Cloud KMS 密钥会附加到 Pub/Sub 主题资源的审核日志中。Pub/Sub 不包含与 Cloud KMS 相关的任何其他信息。
价格和费用
对于以下 Pub/Sub 请求,使用 CMEK 会产生基于 Pub/Sub 价格的 Cloud KMS 服务使用费:
对于使用 CMEK 的每个主题,系统每六个小时会对新的 DEK 进行加密和存储。
系统每六分钟会使用该密钥对 DEK 进行解密。解密操作会执行三次(运行 Pub/Sub 服务的区域中的每个地区执行一次)。
例如,假设有一个主题,该主题具备以下条件:
至少有一个订阅
发布者和订阅者客户端位于同一区域
Cloud KMS 加密操作的次数可以按以下公式估算:
1 key access for ENCRYPT * (30 days / month * 24 hours / day) / 6 hours + 3 key accesses for DECRYPT * (30 days / month * 24 hours / day * 60 minutes / hour ) / 6 minutes = 21,720 Cloud KMS key access events
实际上,提取密钥的频率可能会更高或更低,具体取决于访问模式。请仅将这些数字用作估算值。
监控和问题排查
密钥访问问题可能会产生以下影响:
消息传送延迟
发布出错
您可以使用以下指标监控发布和拉取请求错误(按 response_class
和 response_code
分组):
topic/send_request_count
subscription/pull_request_count
subscription/streaming_pull_response_count
StreamingPull 响应的错误率为 100%。这表示流已结束,而不表示请求失败。如需监控 StreamingPull,请查找 FAILED_PRECONDITION
响应代码。
发布和消息传送可能会因多个原因而失败并显示 FAILED_PRECONDITION
错误。
您可以停用 Cloud KMS 密钥。如需了解详情,请参阅本页上的停用和重新启用密钥。
如果您通过 Cloud EKM 使用外部管理的密钥,请参阅 Cloud EKM 错误参考。
对于推送订阅,无法直接检测特定于 CMEK 的传送问题。请改用以下方法:
使用
subscription/num_unacked_messages
监控推送订阅积压输入量的大小和存在时长。监控
subscription/oldest_unacked_message_age
是否存在异常峰值。使用发布错误和 CMEK 审核日志来发现问题。
停用和重新启用密钥
您可以通过以下两种方法阻止 Pub/Sub 对消息数据进行解密:
推荐:停用通过 Pub/Sub 与主题相关联的 Cloud KMS 密钥。此方法仅影响与该特定密钥相关联的 Pub/Sub 主题和订阅。
使用 IAM 撤消 Pub/Sub 服务账号 (
service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com
) 的 Pub/Sub CryptoKey Encrypter/Decrypter 角色。此方法会影响项目的所有 Pub/Sub 主题以及包含使用 CMEK 加密的消息的订阅。
虽然这两项操作均不能确认即时撤消访问权限,但 IAM 更改通常会传播得更快。如需了解详情,请参阅 Cloud KMS 资源一致性和访问权限更改传播。
如果 Pub/Sub 无法访问 Cloud KMS 密钥,则使用 StreamingPull 或拉取方法发布和传送消息的操作将失败,并显示 FAILED_PRECONDITION
错误。向推送端点传送消息的操作将停止。要恢复传送和发布,请恢复对 Cloud KMS 密钥的访问。
一旦 Pub/Sub 可以访问 Cloud KMS 密钥,系统就会在 12 小时内继续发布消息,并且在 2 小时内继续传送消息。
虽然 Cloud KMS 间歇性中断(少于 1 分钟)不太可能严重中断发布和传送,但 Cloud KMS 不可用时间延长则相当于撤消密钥。