AWS跨账户访问S3存储桶的6种方式
下面介绍的几种跨账户访问S3存储桶的方式中,只有前面三种:Assume Role
, S3桶ACL 及 S3桶策略是真正意义上的通过配置权限的方式进行实现的,后面的三种都不是通过配置跨账户的权限方式实现的。
Assume Role
我们假设分别有A账户和B账户,需求是B账户能够访问A账户中的S3存储桶
- 先从账户A中创建Role,Trust Relationship - 选择所信任的实体
Trust Relationship
如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::B-account-id:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Permissions
- 角色可以访问的S3桶的权限(桶权限 & 对象权限)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws-cn:s3:::bucket-name",
"arn:aws-cn:s3:::bucket-name/*"
]
}
]
}
- 在B账户中创建Role并配置Trust Relationship & Permission
Permission
- 拥有AssumeRole
的权限
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"*"
]
}
]
}
- 测试B账户下能否访问到A账户的S3存储桶
测试过程:将B账户的角色作为lambda的执行角色,通过调用python的boto3包
import json
import boto3
def lambda_handler(event, context):
sts_connection = boto3.client('sts')
accountA = sts_connection.assume_role(
RoleArn = "arn:aws-cn:iam::A-account-id:role/role-name",
RoleSessionName = "cross_acct_lambda"
)
access_key = accountA['Credentials']['AccessKeyId']
secret_key = accountA['Credentials']['SecretAccessKey']
session_token = accountA['Credentials']['SessionToken']
# print("=============access_key", access_key)
# print("=============secret_key", secret_key)
# print("=============session_token", session_token)
targetAccountSession = boto3.Session(
aws_access_key_id = access_key,
aws_secret_access_key = secret_key,
aws_session_token = session_token
)
s3 = targetAccountSession.client("s3", region_name='region-code')
# 指定存储桶名称
bucket_name = 'bucket-name'
# 列出存储桶内的所有对象
response = s3.list_objects_v2(Bucket=bucket_name)
print("============response", response)
能够访问此存储桶的内容
============response {
'ResponseMetadata':
{
..........
}
S3桶ACL
- 创建S3存储桶并开启桶ACL
- 添加
Grantee
如何查找Grantee
:
点击控制台的右上角
- 测试:是否可以访问S3存储桶
$ aws s3 ls s3://bucket-name
2023-08-23 05:15:09 84xxxxx83 xxxxxx.png
S3桶策略
给特定的User添加访问权限
- 配置桶策略 - 以允许B账户的访问
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::B-account-id:user/user_name"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws-cn:s3:::bucket-name",
"arn:aws-cn:s3:::bucket-name/*"
]
}
]
}
- 测试 - 查看是否能够访问S3
$ aws s3 ls s3://bucket-name
给特定的Role添加访问权限
- 配置桶策略 - 以允许角色的访问
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws-cn:iam::B-account-id:role/role-name"
]
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws-cn:s3:::bucket-name",
"arn:aws-cn:s3:::bucket-name/*"
]
}
]
}
- 测试:可以通过Role访问S3存储桶
B账号的lambda通过调用boto3的方式访问S3存储桶
import boto3
def lambda_handler(event, context):
s3 = boto3.client('s3', region_name='region')
bucket_name = 'bucket-name'
object_key = 'xxxxxxx.png'
# get_object
# response = s3.get_object(Bucket = bucket_name, Key=object_key)
# list_bucket
response = s3.list_objects(Bucket=bucket_name)
print("=========response", response)
前提:需要本账户的Role也具有访问S3的权限
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws-cn:s3:::bucket-name",
"arn:aws-cn:s3:::bucket-name/*"
]
}
]
}
对象访问权
分别对桶内的每个对象都放开对象的访问权限,以实现放开桶访问权限的功能
- 开启对象的
ACL
- 添加对象的访问权限
S3桶预签名
A账户生成预签名,B账户使用A账户生成的url对S3桶内的对象进行访问;预签名 URL 使用的凭证是生成该 URL 的 Amazon 用户的凭证
使用如下aws cli进行预签名的操作,身份凭证会集成到生成的URL中,B账户通过url中集成的身份凭证去访问s3存储桶
aws s3 presign s3://bucket-name/object-name --expires-in 3600
B账户可以通过生成的url去访问S3存储桶
S3存储桶公开访问 - 不推荐使用有安全风险
- S3存储桶关闭阻止公开访问
- 编辑桶策略
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws-cn:s3:::bucket-name/*",
"arn:aws-cn:s3:::bucket-name"
]
}
]
}