为啥 gsutil 从使用 KMS 加密的存储桶中恢复文件(使用没有 DECRYPT 权限的服务帐户)?

Posted

技术标签:

【中文标题】为啥 gsutil 从使用 KMS 加密的存储桶中恢复文件(使用没有 DECRYPT 权限的服务帐户)?【英文标题】:Why gsutil restore a file from a bucket encrypted with KMS (using a service account without DECRYPT permission)?为什么 gsutil 从使用 KMS 加密的存储桶中恢复文件(使用没有 DECRYPT 权限的服务帐户)? 【发布时间】:2019-08-15 09:43:23 【问题描述】:

我正在使用 GCP KMS,当我将文件发送到 GCP 存储桶(使用 gustil cp)时,它似乎是加密的。

但是,我有一个与使用不同服务帐户从同一存储桶恢复该文件的权限有关的问题。我的意思是,我用来从存储桶中恢复文件的服务帐户没有解密权限,即使如此,gustil cp 也可以工作。

我的问题是这是正常行为,还是我遗漏了什么?

让我描述一下我的问题:

    首先,我确认bucket的默认加密是我之前设置的KEY:

    $ kms encryption gs://my-bucket
    
    Default encryption key for gs://my-bucket:
    projects/my-kms-project/locations/my-location/keyRings/my-keyring/cryptoKeys/MY-KEY
    

    接下来,通过 gcloud config,我设置了一个具有“Storage Object Creator”和“Cloud KMS CryptoKey Encrypter”权限的服务帐户:

    $ gcloud config set account my-service-account-with-Encrypter-and-object-creator-permissions
    Updated property [core/account].
    

    我将本地文件发送到存储桶:

    $ gsutil cp my-file gs://my-bucket
    
    Copying file://my-file [Content-Type=application/vnd.openxmlformats-officedocument.presentationml.presentation]...
    | [1 files][602.5 KiB/602.5 KiB]
    Operation completed over 1 objects/602.5 KiB.
    

    将文件发送到存储桶后,我确认文件是使用我之前创建的 KMS 密钥加密的:

    $ gsutil ls -L gs://my-bucket
    
    gs://my-bucket/my-file:
        Creation time:          Mon, 25 Mar 2019 06:41:02 GMT
        Update time:            Mon, 25 Mar 2019 06:41:02 GMT
        Storage class:          REGIONAL
        KMS key:                projects/my-kms-project/locations/my-location/keyRings/my-keyring/cryptoKeys/MY-KEY/cryptoKeyVersions/1
        Content-Language:       en
        Content-Length:         616959
        Content-Type:           application/vnd.openxmlformats-officedocument.presentationml.presentation
        Hash (crc32c):          8VXRTU==
        Hash (md5):             fhfhfhfhfhfhfhf==
        ETag:                   xvxvxvxvxvxvxvxvx=
        Generation:             876868686868686
        Metageneration:         1
        ACL:                    []
    

    接下来,我设置了另一个服务帐户,但这次没有解密权限和对象查看器权限(以便它能够从存储桶中读取文件):

    $ gcloud config set account my-service-account-WITHOUT-DECRYPT-and-with-object-viewer-permissions
    
    Updated property [core/account].
    

    设置新的服务账户后(没有解密权限),从bucket中恢复文件的gustil工作顺利......

    gsutil cp gs://my-bucket/my-file .
    
    Copying gs://my-bucket/my-file...
    \ [1 files][602.5 KiB/602.5 KiB]                                                
    Operation completed over 1 objects/602.5 KiB.        
    

我的问题是这是否是正常行为?或者,由于新的服务帐户没有解密权限,恢复文件的gustil cp 应该不起作用?我的意思是,并不是说使用 KMS 加密,第二个gustil cp 命令应该失败并出现“403 权限被拒绝”错误消息或其他东西......

如果我从第二个服务帐户撤消“存储对象查看器”权限(从存储桶中恢复文件),在这种情况下,gustil 失败,但这是因为它没有读取文件的权限:

$ gsutil cp gs://my-bucket/my-file . 
AccessDeniedException: 403 my-service-account-WITHOUT-DECRYPT-and-with-object-viewer-permissions does not have storage.objects.list access to my-bucket.

如果其他人可以帮助我并澄清问题,我将不胜感激......特别是我不确定命令 gsutil cp gs://my-bucket/my-file . 是否应该工作。

我认为它不应该工作(因为服务帐户没有解密权限),还是应该工作?

【问题讨论】:

【参考方案1】:

这工作正常。当您将 Cloud KMS 与 Cloud Storage 一起使用时,数据的加密和解密是在 Cloud Storage 服务的权限下进行的,而不是在请求访问对象的实体的权限下进行的。这就是为什么您必须将 Cloud Storage 服务帐户添加到您的密钥的 ACL 才能使 CMEK 工作。

当一个加密的 GCS 对象被访问时,访问者的 KMS 解密权限永远不会被使用并且它的存在是不相关的。

如果您不希望第二个服务帐户能够访问该文件,请移除其读取权限。

【讨论】:

谢谢蒂姆。从您的回复中,我想我需要阅读更多有关云存储服务帐户的内容。乍一看,我似乎只完成了 50% 的任务来完成 KMS 设置......(根据我的用例)。剩下的任务大概和云存储服务器账号和ACL的权限有关。我认为这个问题可以结束了。如果我在不久的将来有任何其他的,我会开一个新的问题。非常感谢! 听起来不错。如果您有任何其他问题,请随时 ping。 我同意 José 的观点,这与预期的不同。但是感谢@TimDierks 的澄清。在 CSEK 的情况下,可以使用不同的密钥对存储桶中的每个对象进行不同的加密,但是必须在存储桶级别设置 ACL 的意义何在。 ACL 和加密密钥都有不同的作用,但在这种情况下不是。 需要明确的是,每个对象都使用不同的密钥(或多个密钥)进行加密; KMS 密钥是管理所有这些特定于对象的密钥的密钥。见cloud.google.com/security/encryption-at-rest/default-encryption【参考方案2】:

默认情况下,Cloud Storage 使用 Google 管理的加密密钥加密所有对象数据。您可以改为提供自己的密钥。有两种类型:

    您必须提供的 CSEK 您也提供了 CMEK,但这次由 Google KMS 服务管理(这是您正在使用的服务)。

当您使用gsutil cp 时,您已经在使用幕后的加密方法。因此,正如Using Encryption Keys 的文档所述:

解密 CSEK 加密对象时,需要提供 CSEK 在其中一个 decryption_key 属性中,这对于 解密 CMEK 加密的对象,因为 CMEK 的名称用于 加密对象存储在对象的元数据中。

如您所见,密钥不是必需的,因为它已包含在 gsutil 正在使用的对象的元数据中。

如果未提供 encryption_key,gsutil 会确保它的所有数据 写入或复制改为使用目标存储桶的默认值 加密类型 - 如果存储桶具有默认 KMS 密钥集,则该 CMEK 用于加密;如果不是,则使用 Google 管理的加密。

【讨论】:

谢谢纳韦尔。感谢您的意见。

以上是关于为啥 gsutil 从使用 KMS 加密的存储桶中恢复文件(使用没有 DECRYPT 权限的服务帐户)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 gsutil 从 GCE 上的容器中复制存储桶中的文件

gsutil / gcloud 存储文件列表排序日期降序?

如何使用 gsutil 命令列出 gcs 存储桶中的所有文件(包含所有文件夹)以匹配文件内容中的特定字符串

优化文件夹子集的 gsutil 下载

如何使用 gsutil 从文件名中删除 .jpg 已在存储桶中超过 20000 个文件

gsutil - 如何从谷歌私有云复制/下载所有文件?