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 存储桶是不是是公共的并将它们设为私有的主要内容,如果未能解决你的问题,请参考以下文章
从AWS Lambda python函数将多个JSON文件合并到S3中的单个JSON文件
我如何使用 aws lambda 将文件写入 s3 (python)?