使用boto3通过aws Lambda拒绝访问

Hel*_*lad 11 amazon-s3 amazon-web-services amazon-iam boto3 aws-lambda

我使用构建的数据处理管道

S3 + SNS + Lambda

因为S3无法从其存储区域发送通知,所以我利用SNS向其他地区的Lambda发送S3通知.

用函数编码的lambda函数

from __future__ import print_function
import boto3


def lambda_handler (event, context):
    input_file_bucket = event["Records"][0]["s3"]["bucket"]["name"]
    input_file_key = event["Records"][0]["s3"]["object"]["key"]

    input_file_name = input_file_bucket+"/"+input_file_key

    s3=boto3.resource("s3")
    obj = s3.Object(bucket_name=input_file_bucket, key=input_file_key)
    response = obj.get()

    return event #echo first key valuesdf
Run Code Online (Sandbox Code Playgroud)

当我运行保存和测试时,我收到以下错误

    {
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      20,
      "lambda_handler",
      "response = obj.get()"
    ],
    [
      "/var/runtime/boto3/resources/factory.py",
      394,
      "do_action",
      "response = action(self, *args, **kwargs)"
    ],
    [
      "/var/runtime/boto3/resources/action.py",
      77,
      "__call__",
      "response = getattr(parent.meta.client, operation_name)(**params)"
    ],
    [
      "/var/runtime/botocore/client.py",
      310,
      "_api_call",
      "return self._make_api_call(operation_name, kwargs)"
    ],
    [
      "/var/runtime/botocore/client.py",
      395,
      "_make_api_call",
      "raise ClientError(parsed_response, operation_name)"
    ]
  ],
  "errorType": "ClientError",
  "errorMessage": "An error occurred (AccessDenied) when calling the GetObject operation: Access Denied"
}
Run Code Online (Sandbox Code Playgroud)

我配置了lambda Role

full S3 access
Run Code Online (Sandbox Code Playgroud)

并在我的目标存储桶上设置存储桶策略

everyone can do anything(list, delete, etc.)
Run Code Online (Sandbox Code Playgroud)

似乎我没有很好地制定政策.

Amr*_*mri 13

我有类似的问题,我通过将适当的策略附加到我的用户来解决它.

IAM - >用户 - >用户名 - >权限 - >附加策略.

还要确保添加正确的访问密钥和秘密访问密钥,您可以使用AmazonCLI执行此操作.


omu*_*thu 8

您正在寻找的特定 S3 对象的权限可能有限

  1. S3 对象级读取权限被拒绝
  2. 附加到 lambda 的角色无权获取/读取 S3 对象
  3. 如果使用 S3 存储桶策略授予访问权限,请验证提供了读取权限

  • 这很模糊。您能否指出如何解决这个问题? (5认同)
  • 两种可能 1. S3 对象级别的读取权限被拒绝 2. 附加到 lambda 的角色没有获取/读取 S3 对象的权限 (2认同)

Tal*_*ffe 6

添加到 Amri 的答案中,如果您的存储桶是私有的并且您拥有访问它的凭据,则可以使用 boto3.client:

import boto3
s3 = boto3.client('s3',aws_access_key_id='ACCESS_KEY',aws_secret_access_key='SECRET_KEY')
response = s3.get_object(Bucket='BUCKET', Key='KEY')
Run Code Online (Sandbox Code Playgroud)

*对于此文件:s3://bucket/a/b/c/some.text,Bucket 为“bucket”,Key 为“a/b/c/some.text”

- -编辑 - -

例如,您可以轻松更改脚本以接受密钥作为环境变量,这样它们就不会被硬编码。为了简单起见,我就这样离开了

  • 这在 Lambda 函数中是个坏主意。没有理由对密钥进行硬编码。 (2认同)

Rob*_*ose 6

Omuthu的回答实际上正确地确定了我的问题,但是它没有提供解决方案,所以我认为我会这样做。

当您在IAM中设置权限时,您可能会执行以下操作:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这是不正确的。您需要将对象权限应用于存储桶中的对象。因此它必须看起来像这样:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::test/*"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

请注意第二个ARN /*,其末尾带有。


Mia*_*Kim 6

我遇到了类似的问题,不同之处在于存储桶是用 KMS 密钥加密的。

修复方法:IAM -> 加密密钥 -> YOUR_AWS_KMS_KEY -> 您的策略或账户