Python lambda函数检查我的S3存储桶是否为Public&;保密

Python lambda函数检查我的S3存储桶是否为Public&;保密,python,amazon-web-services,amazon-s3,aws-lambda,boto3,Python,Amazon Web Services,Amazon S3,Aws Lambda,Boto3,我编写了一个Python lambda函数来检查我的S3存储桶是否是公共的,并在我的帐户中将它们设置为私有的。但我不断地得到一个错误: ({ “errorMessage:“'S3'对象没有属性'put\u bucket\u access\u block'”, “errorType”:“AttributeError”, “stackTrace”:[ “文件\“/var/task/lambda_function.py\”,第66行,在lambda_处理程序中\n验证_实例(事件)\n”, “File

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

({ “errorMessage:“'S3'对象没有属性'put\u bucket\u access\u block'”, “errorType”:“AttributeError”, “stackTrace”:[ “文件\“/var/task/lambda_function.py\”,第66行,在lambda_处理程序中\n验证_实例(事件)\n”, “File\”/var/task/lambda\u function.py\”,第32行,在validate\u instance\n addacl=s3\u client.put\u bucket\u access\u块(bucket=s3\u bucketName,\n“, “文件\“/var/runtime/botocore/client.py\”,第563行,在getattr\n self.名称,项)\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)

您有错误的方法名称。将
put\u bucket\u access\u block
更改为
put\u public\u access\u block

无需编写代码,只需激活即可


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

问题是,与Lambda Python运行时环境捆绑的boto3版本尚未包含此功能,因此,
put\u public\u access\u block
不是S3客户机上的方法


一种解决方法是部署您自己的Lambda层,其中包括一个更高版本的bot3(它支持
put\u public\u access\u block
)。有关在Lambda层中包含boto3的选项,请参阅。

确保已安装boto3和botocore的最新版本(该方法由botocore加载,boto3调用)。能否在问题中将整个Lambda函数显示为代码块?与您发布的问题无关,在Lambda函数中提供凭据的方式不是最好的方法。通常,您的Lambda函数将使用给定的IAM角色进行配置,并且您永远不必显式地向bot3提供任何凭据。另外,请注意,Lambda环境中提供给您的boto3版本不一定是最新的可用公共版本——有关更多详细信息,请参阅错误消息与您提供的代码示例不再匹配。