配置用于复制加密对象的源 KMS 密钥

Posted

技术标签:

【中文标题】配置用于复制加密对象的源 KMS 密钥【英文标题】:Configuring source KMS keys for replicating encrypted objects 【发布时间】:2018-08-31 17:19:02 【问题描述】:

我正在尝试将加密对象复制到不同区域的 S3 存储桶。执行此操作时,我需要指定一个或多个 KMS 密钥用于解密 source 对象。

我正在使用以下 Terraform 脚本:

replication_configuration 
  role = "$aws_iam_role.replication.arn"

  rules 
    id     = "$var.service"
    prefix = "$var.replication_bucket_prefix"
    status = "Enabled"

    destination 
      bucket        = "$aws_s3_bucket.replication_bucket.arn"
      storage_class = "STANDARD"
      replica_kms_key_id = "xxxxx"
    

    source_selection_criteria 
      sse_kms_encrypted_objects 
        enabled = true
      
    
  

此脚本有效(适用),但在 AWS 控制台中检查时,没有为源对象选择任何 KMS 密钥。

查看配置,我看不到任何地方指定这些键。 replica_kms_key_id 用于指定用于加密 destination 存储桶中的对象的 KMS 密钥。

【问题讨论】:

【参考方案1】:

我在尝试使用 terraform 实现 KMS 加密跨区域、跨账户复制时遇到了同样的问题。

在某些时候,我注意到配置中缺少源 KMS 密钥(就像您所做的那样)并通过 S3 Web 界面添加了它。这样做之后,AWS 创建了另一个策略(没有在任何地方提及它;我在一天后在做其他事情时发现它)称为 crr-$SOURCE_BUCKET_NAME-to-$TARGET_BUCKET_NAME 之类的东西,并将其附加到复制角色。在检查了该规则后,我意识到这是拼图中缺失的部分。

这是政策的重要部分:


        "Action": [
            "kms:Decrypt"
        ],
        "Effect": "Allow",
        "Condition": 
            "StringLike": 
                "kms:ViaService": "s3.$var.source_bucket_region.amazonaws.com",
                "kms:EncryptionContext:aws:s3:arn": [
                    "arn:aws:s3:::$var.source_bucket_name/*"
                ]
            
        ,
        "Resource": [
            "$var.source_kms_key_arn"
        ]
    ,

$var.source_kms_key_arn 是您的源 KMS 密钥 arn。

PS:这个问题把我逼疯了! (╯°□°)╯︵┻━┻

【讨论】:

【参考方案2】:

当您在控制台中设置复制时,它会创建一个新策略并将其附加到您的复制角色。如果您使用 Terraform 创建此策略,它将反映在控制台中并且复制将起作用。

下面的代码假设您在 terraform 中创建所有存储桶和密钥,资源名称为 aws_s3_bucket.sourceaws_s3_bucket.replica,密钥资源为 aws_kms_key.sourceaws_kms_key.replica

这绝对应该在 Terraform 网站上的 s3 存储桶资源文档中进行描述,因为没有它就无法工作,但事实并非如此。

resource "aws_iam_policy" "replication" 
  name = "tf-iam-role-policy-replication-12345"

  policy = <<POLICY

  "Version": "2012-10-17",
  "Statement": [
    
      "Action": [
        "s3:ListBucket",
        "s3:GetReplicationConfiguration",
        "s3:GetObjectVersionForReplication",
        "s3:GetObjectVersionAcl",
        "s3:GetObjectVersionTagging",
        "s3:GetObjectRetention",
        "s3:GetObjectLegalHold"
      ],
      "Effect": "Allow",
      "Resource": [
        "$aws_s3_bucket.source.arn",
        "$aws_s3_bucket.source.arn/*"
      ]
    ,
    
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags",
        "s3:GetObjectVersionTagging"
      ],
      "Effect": "Allow",
      "Resource": [
        "$aws_s3_bucket.replica.arn/*"
      ]
    ,
    
      "Action": [
        "kms:Decrypt"
      ],
      "Effect": "Allow",
        "Condition": 
          "StringLike": 
            "kms:ViaService": "s3.$aws_s3_bucket.source.region.amazonaws.com",
            "kms:EncryptionContext:aws:s3:arn": [
              "$aws_s3_bucket.source.arn/*"
            ]
          
        ,
        "Resource": [
          "$aws_kms_key.source.arn"
        ]
    ,
    
      "Action":[
        "kms:Encrypt"
      ],
      "Effect":"Allow",
      "Condition": 
        "StringLike": 
          "kms:ViaService": "s3.$aws_s3_bucket.replica.region.amazonaws.com",
          "kms:EncryptionContext:aws:s3:arn": [
            "$aws_s3_bucket.replica.arn/*"
          ]
        
      ,
      "Resource":[
        "$aws_kms_key.replica.arn"
      ]
    
  ]

POLICY

更多细节可以在 terraform-provider-aws repo 上的issue #6046 中找到

【讨论】:

【参考方案3】:

遇到了同样的问题。我从 Matt 和 malte 的早期 cmets 中的政策文档开始,但只使用了这个:


    "Version": "2012-10-17",
    "Statement": [
        
            "Action": [
                "s3:ListBucket",
                "s3:GetReplicationConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetObjectVersion",
                "s3:GetObjectVersionAcl",
                "s3:GetObjectVersionTagging",
                "s3:GetObjectRetention",
                "s3:GetObjectLegalHold"
            ],
            "Effect": "Allow",
            "Resource": [
                "$aws_s3_bucket.source.arn",
                "$aws_s3_bucket.source.arn/*"
            ]
        ,
        
            "Action": [
                "s3:ReplicateObject",
                "s3:ReplicateDelete",
                "s3:ReplicateTags",
                "s3:GetObjectVersionTagging"
            ],
            "Effect": "Allow",
            "Condition": 
                "StringLikeIfExists": 
                    "s3:x-amz-server-side-encryption": [
                        "aws:kms",
                        "AES256"
                    ],
                    "s3:x-amz-server-side-encryption-aws-kms-key-id": [
                        "$aws_kms_key.replica.arn"
                    ]
                
            ,
            "Resource": [
                "$aws_s3_bucket.replica.arn/*"
            ]
        ,
        
            "Action": [
                "kms:Decrypt"
            ],
            "Effect": "Allow",
            "Condition": 
                "StringLike": 
                    "kms:ViaService": "s3.$aws_s3_bucket.source.region.amazonaws.com",
                    "kms:EncryptionContext:aws:s3:arn": [
                        "$aws_s3_bucket.source.arn/*"
                    ]
                
            ,
            "Resource": [
                "$aws_kms_key.source.arn"
            ]
        ,
        
            "Action": [
                "kms:Encrypt"
            ],
            "Effect": "Allow",
            "Condition": 
                "StringLike": 
                    "kms:ViaService": "s3.$aws_s3_bucket.replica.region.amazonaws.com",
                    "kms:EncryptionContext:aws:s3:arn": [
                        "$aws_s3_bucket.replica.arn/*"
                    ]
                
            ,
            "Resource": [
                        "$aws_kms_key.replica.arn"
            ]
        
    ]

注意更改,可能来自 CRR 策略的 V3(从控制台选择时,AWS 创建 s3crr_kms_v3_*):

"Condition": 
                "StringLikeIfExists": 
                    "s3:x-amz-server-side-encryption": [
                        "aws:kms",
                        "AES256"
                    ],
                    "s3:x-amz-server-side-encryption-aws-kms-key-id": [
                        "$aws_kms_key.replica.arn"
                    ]
                
            

使用 KMS 的 S3 CRR 的 Terraform 文档仍然非常有限。

【讨论】:

以上是关于配置用于复制加密对象的源 KMS 密钥的主要内容,如果未能解决你的问题,请参考以下文章

AWS:无法使用流从 SSE-KMS 加密存储桶下载文件

获取解密密文时使用的 Google KMS 密钥的版本

Amazon S3 加密

[S3使用Terraform进行跨区域复制

要求在 S3 存储桶策略中使用特定密钥 ID 进行 KMS 加密

使用默认 aws/S3 KMS 密钥对解密对象进行跨账户访问