AWS Lambda S3 访问被拒绝

Posted

技术标签:

【中文标题】AWS Lambda S3 访问被拒绝【英文标题】:AWS Lambda S3 Access Denied 【发布时间】:2020-09-30 11:43:31 【问题描述】:

我有一个 lambda 函数,它使用具有以下政策摘录的角色


            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::ipwl-lambda-config/*",
                "arn:aws:s3:::ipwl-lambda-config"
            ]
        

我的存储桶策略如下所示


    "Version": "2012-10-17",
    "Statement": [
        
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": 
                "AWS": "*"
            ,
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::ipwl-lambda-config/*",
            "Condition": 
                "StringNotEquals": 
                    "s3:x-amz-server-side-encryption": "aws:kms"
                
            
        ,
        
            "Sid": "AllowLambda",
            "Effect": "Allow",
            "Principal": 
                "AWS": "arn:aws:iam::accountid:role/iam_for_lambda"
            ,
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::ipwl-lambda-config/*",
                "arn:aws:s3:::ipwl-lambda-config"
            ]
        
    ]

我在角色和存储桶策略上都允许 GetObject 和 ListBucket。但是当我的函数运行时

s3_obj = s3_res.Object(s3_bucket, s3_object)

我明白了

[ERROR] ClientError: 调用时发生错误 (AccessDenied) GetObject 操作:拒绝访问

我还需要添加哪些权限?对象就在那里,当我使用管理员角色在本地运行代码时,我可以得到它。

更新

我已多次检查以确保存储桶和对象名称正确无误。根据堆栈跟踪,异常实际上来自这里的第二行

s3_res = boto3.resource('s3')
s3_obj = s3_res.Object(s3_bucket, s3_object)
data = s3_obj.get()['Body'].read()

KMS 应该只是 PutObject 的一个因素。我们有一个支持帐户,因此我可以与他们核实并更新他们的发现。

【问题讨论】:

我觉得不错。您能否仔细检查 lambda 函数使用的存储桶名称和 iam 角色是否正确? 这能回答你的问题吗? aws lambda function getting access denied when getObject from s3 如果您在 lambda 中已经拥有 s3 权限,则不需要带有 lambda 的 bucket 语句。它是多余的,除非不同的帐户。您的 s3 内联策略在 lambda 角色中是正确的。你确定s3_res.Object 会抛出错误吗?也许您还有其他 s3 操作?我也很好奇 kms 是如何融入其中的。 【参考方案1】:

要从 S3 下载 KMS 加密的对象,您不仅需要能够获取该对象。您还需要能够解密 AWS KMS 密钥。

以下是您的 Lambda 函数应具有的 IAM 策略示例:


  "Version": "2012-10-17",
  "Statement": [
    
      "Sid": "s3get",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::ipwl-lambda-config/*"
    ,
    
      "Sid": "kmsdecrypt",
      "Effect": "Allow",
      "Action": "kms:Decrypt",
      "Resource": "arn:aws:kms:example-region-1:123456789012:key/example-key-id"
    
  ]

密钥策略还需要允许 IAM 角色解密密钥,如下所示:


  "Sid": "kmsdecrypt",
  "Effect": "Allow",
  "Principal": 
    "AWS": "arn:aws:iam::123456789012:role/xyz"
  ,
  "Action": "kms:Decrypt",
  "Resource": "*"

【讨论】:

以上是关于AWS Lambda S3 访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

terraform/aws lambda 函数访问在 s3 上被拒绝

在不同账户的 Lambda 中从 AWS Athena 查询 S3 文件时访问被拒绝

AWS Lambda - 访问被拒绝错误 - GetObject

为啥我的 lambda 函数在尝试访问 S3 存储桶时会被拒绝访问?

如何在使用 lambda@edge 调整图像大小时修复访问被拒绝错误

nodeJS的AWS S3 403访问被拒绝问题