Python lambda 函数来检查我的 S3 存储桶是不是是公共的并将它们设为私有

Posted

技术标签:

【中文标题】Python lambda 函数来检查我的 S3 存储桶是不是是公共的并将它们设为私有【英文标题】:Python lambda function to check If my S3 Buckets are Public & Make Them PrivatePython lambda 函数来检查我的 S3 存储桶是否是公共的并将它们设为私有 【发布时间】:2020-01-01 03:58:04 【问题描述】:

我写了一个Python lambda 函数来检查我的S3 存储桶是否公开并在我的帐户中将它们设为私有。但我不断收到错误:

( "errorMessage": "'S3' 对象没有属性 'put_bucket_access_block'", "errorType": "AttributeError", “堆栈跟踪”: [ " File \"/var/task/lambda_function.py\",第 66 行,在 lambda_handler\n validate_instance(event)\n", " File \"/var/task/lambda_function.py\",第 32 行,在 validate_instance\n addacl = s3_client.put_bucket_access_block(Bucket = s3_bucketName,\n", " File \"/var/runtime/botocore/client.py\",第 563 行,在 getattr\n self.class.name , 项)\n" ] )

下面是用 Python Boto3 编写的 Lambda 函数:

import boto3
from botocore.exceptions import ClientError
import json
import logging
import sys
log = logging.getLogger()
log.setLevel(logging.DEBUG)

log = logging.getLogger()
log.setLevel(logging.DEBUG)
print('Loading function')
sts_client = boto3.client('sts')
def validate_instance(rec_event):
    sns_msg = json.loads(rec_event['Records'][0]['Sns']['Message'])
    account_id = sns_msg['account']
    event_region = sns_msg['region']
    assumedRoleObject = sts_client.assume_role(
        RoleArn="arn:aws:iam:::role/".format(account_id, 'VSC-Admin-Account-Lambda-Execution-Role'),
        RoleSessionName="AssumeRoleSession1"
    )
    credentials = assumedRoleObject['Credentials']
    print(credentials)
    s3_client = boto3.client('s3', event_region, aws_access_key_id=credentials['AccessKeyId'],
                              aws_secret_access_key=credentials['SecretAccessKey'],
                              aws_session_token=credentials['SessionToken'],
                              )
    s3_bucketName = sns_msg['detail']['requestParameters']['bucketName']

    public_block = s3_client.put_public_access_block(Bucket = s3_bucketName,
            PublicAccessBlockConfiguration=
                'BlockPublicAcls': true,
                'IgnorePublicAcls':false,
                'BlockPublicPolicy':true,
                'RestrictPublicBuckets':true
                )        
    enableacl = s3_client.put_bucket_acl(Bucket = s3_bucketName,
                 ACL='private'
                 )


    put_public_access_block
    try:
        checkencryption=s3_client.get_bucket_encryption(Bucket=s3_bucketName)
        print("checking the encrytption")
        rules = checkencryption['ServerSideEncryptionConfiguration']['Rules']
        print('Bucket: %s, Encryption: %s' % (s3_bucketName, rules))
    except ClientError as e:
        if e.response['Error']['Code'] == 'ServerSideEncryptionConfigurationNotFoundError':
            response = s3_client.put_bucket_encryption(Bucket = s3_bucketName,
            ServerSideEncryptionConfiguration=
                'Rules': [
                    
                        'ApplyServerSideEncryptionByDefault':
                            'SSEAlgorithm': 'AES256'
                        
                    ,]
            )

        else:
            print("Bucket: %s, unexpected error: %s" % (s3_bucketName, e))


def lambda_handler(event, context):
    log.info("Here is the Received Event")
    log.info(json.dumps(event))
    validate_instance(event)

【问题讨论】:

与您发布的问题无关,您在 Lambda 函数中提供凭证的方式并不是执行此操作的最佳方式。通常,您的 Lambda 函数将使用给定的 IAM 角色进行配置,并且您永远不必显式地向 boto3 提供任何凭证。另外,请注意,您在 Lambda 环境中可用的 boto3 版本不一定是最新可用的公共版本——有关更多详细信息,请参阅docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html 您的错误信息与您提供的代码示例不再匹配。 【参考方案1】:

您无需编写代码,只需激活Amazon S3 Block Public Access – Another Layer of Protection for Your Accounts and Buckets | AWS News Blog。

这使您可以简单地阻止对存储桶的公开访问,即使存在将其公开的设置或存储桶策略。如果您愿意,它甚至可以覆盖对象级权限。

【讨论】:

【参考方案2】:

问题是与 Lambda Python 运行环境捆绑的 boto3 版本还没有包含此功能,因此 put_public_access_block 不是 S3 客户端上的方法。

一种解决方法是部署您自己的 Lambda 层,其中包含更高版本的 boto3(确实支持put_public_access_block)。有关在 Lambda 层中包含 boto3 的选项,请参阅 related answer。

【讨论】:

【参考方案3】:

您的方法名称错误。将put_bucket_access_block 更改为put_public_access_block

【讨论】:

确保您安装了最新版本的 boto3 和 botocore(该方法由 boto3 调用的 botocore 加载)。 您能否在问题中将整个 lambda 函数显示为代码块?

以上是关于Python lambda 函数来检查我的 S3 存储桶是不是是公共的并将它们设为私有的主要内容,如果未能解决你的问题,请参考以下文章

在python中自动测试aws lambda函数

从AWS Lambda python函数将多个JSON文件合并到S3中的单个JSON文件

我如何使用 aws lambda 将文件写入 s3 (python)?

如何使用 lambda 将 s3 中的最新代码部署到 lambda 函数

在单个 S3 对象上传事件上触发多个 lambda

python 将小文件写入s3存储桶的lambda处理函数