Python lambda 函数检查我的 S3 存储桶是否公开并将它们设为私有(private)

标签 python amazon-web-services amazon-s3 aws-lambda boto3

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

({ "errorMessage": "'S3' object has no attribute 'put_bucket_access_block'", "errorType": "AttributeError", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 66, in lambda_handler\n validate_instance(event)\n", " File \"/var/task/lambda_function.py\", line 32, in validate_instance\n addacl = s3_client.put_bucket_access_block(Bucket = s3_bucketName,\n", " File \"/var/runtime/botocore/client.py\", line 563, in getattr\n self.class.name, item)\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 Python 运行时环境捆绑在一起的 boto3 版本还不包含此功能,因此 put_public_access_block 不是 S3 客户端上的方法。

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

关于Python lambda 函数检查我的 S3 存储桶是否公开并将它们设为私有(private),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57683662/

相关文章:

python - 如何使用 Python 在 Lambda 中为 CloudFront 生成 SignedUrl?

amazon-web-services - 配置AWS API Gateway的日志记录

amazon-web-services - 我应该将 Cognito 删除用户逻辑放在前端还是后端?

amazon-s3 - 如何从包含大量文件的 S3 存储桶下载最新文件

javascript - 如何在 JavaScript 中加密一些在客户端不可见的字符串?

python - 使用 Python、OpenCV 和卡尔曼滤波进行二维运动估计

python - 如何在 Django 模板中获取我网站的域名?

python - Debian 音频问题,包括 Alsa、PulseAudio 和 QJackCtl

python - 如何导入和猴子修补与测试位于不同包中的 Python 模块?

amazon-web-services - S3 存储桶访问被拒绝 [悬而未决]