一、背景
S3提供Access Point用于数据分享、访问授权,可用于对外隐藏真实的存储桶名称的同时实施权限控制。S3 Access Point有两种类型:从Internet互联网访问类型,以及仅能从特定VPC访问的类型。此外S3 Access Point也支持跨账户访问。
下面分别进行两种配置。
二、创建可从Internet直接访问的S3 Access Point
1、创建S3 Access Point
相比于从AWS控制台网页界面创建Access Point,命令行AWSCLI的操作更加快捷,只需一条命令即可。
执行如下命令:
aws s3control create-access-point --name mys3ap01 --account-id 420029960748 --bucket s3accesspoint01
请替换mys3ap01
为要使用的Access Point的名字(友好名称),替换s3accesspoint01
为要分享的Bucket名字。
成功的话返回如下结果。
{
"AccessPointArn": "arn:aws-cn:s3:cn-north-1:420029960748:accesspoint/mys3ap01"
}
(END)
2、测试从AWSCLI访问
创建完毕后,在AWS控制台图形界面内,进入存储桶,然后找到“访问点”标签页内,可以看到访问点的名称,接下来使用这个名称作为存储桶名来访问S3。如下截图。
从以上界面上,复制下来Access Point alias,也就是类似mys3ap01-h5dzfgteuw8so9j1rdhwdqj9p3puncnn1a-s3alias
格式的这一段。
从互联网上的客户端,配置AKSK后,用AWSCLI发起验证是否正常:
aws s3 ls s3://mys3ap01-h5dzfgteuw8so9j1rdhwdqj9p3puncnn1a-s3alias/
由此可看到访问正常。这个别名,也被AWSCLI以外的别的应用程序正确解析出来,可完全视为一个独立的存储痛的名字获得正常访问。
3、存储桶内的文件公开在互联网上接受外部访问
如果希望设置S3公开权限,允许从互联网访问,那么可以进入S3的Access Point界面,找到存储桶内的文件,如下截图。
点击文件后,即可看到这个文件被设置为公开访问后的完整域名。这个域名是本S3 Access Point的友好显示名称+账号ID组成的。由此可以看到,原始S3存储桶的名字和地址被保护了起来。如下截图。
至此配置一个从互联网访问的S3 Access Point访问完成。
三、创建仅在VPC内访问的S3 Access Point
在某些场景下,不希望S3存储桶的文件被从互联网访问,而是仅允许从特定VPC内访问。由此可以配置VPC专用S3 Access Point。
1、在VPC网络服务中创建类型为Gateway Endpoint的S3 VPC Endpoint
使用仅限VPC的S3 Access Point的场景需要将本VPC内访问S3的流量通过VPC路由到S3服务。因此这意味着,所有通过互联网访问S3的客户端都将不能访问这个S3 Access Point。后续的测试都将在VPC内的EC2上进行。
不过在默认状态下,即便是在一个部署了NAT Gateway的私有子网去访问S3,包括AWSCLI和SDK调用的默认的行为依然还是通过互联网访问S3。为了能强制位于VPC内的客户端使用VPC内网访问S3服务,就需要为VPC配置S3 VPC Endpoint。方法如下。
进入VPC服务界面,从左侧菜单中选择终端服务Endpoint
,点击右上角的创建按钮。如下截图。
在服务类型中选择类型是左侧第一项AWS服务,在服务搜索框中,输入关键字s3
搜索服务名。如下截图。
在搜索结果中,会出现两条S3的Endpoint,右侧的类型分别是Interface
和Gateway
两种类型。此时需要选中Gateway
类型。然后在下方的VPC中选择要授权访问的VPC,在路由表中,选择本VPC内的要访问S3的客户端所在的路由表,例如EC2/EKS所在的子网对应的路由表。接下来继续向下滚动页面。如下截图。
在Policy界面,选择默认的Full access
,然后将页面滚动到最下方,点击创建
。创建完成。如下截图。
2、验证上一步配置的S3 VPC Endpoint工作是否正常
在创建完毕后,接下来要验证下VPC Endpoint的路由表创建成功,以此确保流量被从VPC内送达S3。验证方法如下。
点击VPC Endpoint的名称,检查标签页路由表,查看是否能显示出来关联的路由表ID。如下截图。
点击上图的路由表ID,跳转到路由表条目的页面,查看下方路由表。如果存在形式为pl-xxxxx
这种目的地址条目,且目标路由的下一跳是vpce-xxxxxxxx
这种形式的地址,则表示配置S3 VPC Endpoint配置生效。
在本VPC内,使用AWSCLI验证存储桶访问是否正常。此时调用的S3是存储桶原始的名字,而不是S3 Access Point。本步骤是用来验证VPC内的S3流量完全通过VPC传输,而不是在互联网传输。
aws s3 ls s3://s3accesspoint01/
如果正常列出存储桶内的文件,这表示配置正常。
3、创建S3 Access Point
请替换如下命令中的endpiont名字、账户ID、S3桶名、要授权访问的VPC ID、AWS区域的名字,然后执行如下命令:
aws s3control create-access-point --name mys3ap02 --account-id 420029960748 --bucket s3accesspoint01 --vpc-configuration VpcId=vpc-36cf9352 --region cn-north-1
配置成功显示如下信息:
{
"AccessPointArn": "arn:aws-cn:s3:cn-north-1:420029960748:accesspoint/mys3ap02"
}
创建S3 Access Point完毕。
4、验证S3 Access Point访问正常
创建完毕后,在AWS控制台图形界面内,进入存储桶,然后找到“访问点”标签页内,可以看到这个VPC专用的访问点的名称,接下来使用这个名称作为存储桶名来访问S3。注意名称需要唯一,和前文的S3 Access Point区别开来。如下截图。
执行如下命令:
aws s3 ls s3://mys3ap02-sipdycqfuj3gkiqs9tr9szumkr68gcnn1a-s3alias/
可看到访问正常,成功列出了这个存储桶内的对象。
为了验证S3 Access Point是在特定VPC才能访问,此时可以在位于非本VPC的其他位置对存储桶的S3 Access Point发起访问测试。在VPC外通过Internet访问时候本S3 Access Point会报错:
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
这表示本S3 Access Point是完全针对特定VPC的授权的,由此配置成功。
四、通过S3 Access Point控制访问权限
前文实验中,创建S3 Access Point时候使用的默认授权,这意味着使用S3 Access Point的用户对S3存储桶有完全访问权限。这种完全开放所有权限的场景可能不是最佳安全实践。如果只希望本AWS账户内的某用户通过S3 Access Point对存储桶进行特定的操作(如GetObject只读),那么可按照如下方式配置。
1、创建独立的IAM用户(生成AKSK)并绑定IAM策略
创建一个新的IAM用户,并为这个用户创建AKSK。接下来将要授权这个用户能访问S3 Access Point。
在创建用户完毕后,创建一个IAM Policy,请替换其中的账户ID和S3 Access Point名称为实际环境:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws-cn:s3:cn-north-1:420029960748:accesspoint/mys3ap02/object/*"
}
]
}
以上这段策略由此表示本IAM用户(以及AKSK)可以调用S3 Access Point。然后把这段IAM Policy挂载到刚才创建的用户上。
2、配置S3存储桶策略
进入S3存储桶界面,进入策略界面,找到策略位置,点击编辑。如下截图。
填写配置如下策略。
{
"Version": "2012-10-17",
"Statement" : [
{
"Effect": "Allow",
"Principal" : { "AWS": "*" },
"Action" : "S3:GetObject",
"Resource" : [ "arn:aws-cn:s3:::s3accesspoint01", "arn:aws-cn:s3:::s3accesspoint01/*" ],
"Condition": {
"StringEquals" : { "s3:DataAccessPointAccount" : "420029960748" }
}
}]
}
请替换以上策略中的存储桶ARN为实际的桶的名字,并替换最后一个桶Owner的账户ID为桶的所有人的AWS账户。然后保存存储桶策略。如下截图。
这段策略的作用是,允许S3 Access Point进来的流量执行GetObject访问本存储桶。
3、清空S3 Access Point策略
在S3存储桶配置了对应策略的场景下,S3 Access Point的策略无需配置,留空即可。如果之前配置过,需要将其清空。
清空现有S3 Access Point的方法是,进入S3 Access Point界面,点击策略。接下来向下滚动页面。如下截图。
在S3 Access Point位置可看到当前策略为空,如果不为空,点击删除按钮可清空。
4、验证S3 Access Policy工作正常
首先验证被授权的GetObject行为。执行如下命令,从存储桶内向线下本机复制一个文件,可看到复制成功。
aws s3 cp s3://mys3ap02-sipdycqfuj3gkiqs9tr9szumkr68gcnn1a-s3alias/AWS.png AWS3.png
接下来验证策略中没有授权的PutObject行为。从线下本机向线上存储桶内复制一个文件,可看到没有权限被拒绝。
aws s3 cp AWS.png s3://mys3ap02-sipdycqfuj3gkiqs9tr9szumkr68gcnn1a-s3alias/AWS10.png
返回的拒绝的错误消息是:
upload failed: .\AWS.png to s3://mys3ap02-sipdycqfuj3gkiqs9tr9szumkr68gcnn1a-s3alias/AWS10.png An error occurred (AccessDenied) when calling the CreateMultipartUpload operation: Access Denied
由此,就配置好了一个S3 Access Point,并且只允许被特定IAM用户(以及AKSK)读取对象操作。
五、跨账号访问S3 Access Point获取数据
在某些场景下,还需要提供S3跨账号访问服务,那么可在上一步的基础上,为S3存储桶策略和S3 Access Point策略分别增加跨账号授权。
注意:
- 跨账号定义是同在AWS国内,或者同在AWS全球海外。由于AWS国内和海外两套体系,因此国内和海外账号之间不可跨账号访问;
- 跨账号访问的时候,创建基于互联网访问的S3 Access Point比较方便。如果要求是仅限VPC内部的S3 Access Point,那么步骤还会更多一些,因为上一步实验已经创建好的仅限特定VPC的S3 Access Point一经创建是无法修改的,所以跨账号场景下,还需要使用另一个被授权账号的VPC ID来重新创建新的仅限特定VPC的S3 Access Point,且还需要在被授权的账号内应用程序所在的VPC上创建VPC Endpoint,来确保最终用户访问S3的网络流量是仅来自特定VPC的。
本文仅描述使用互联网访问的S3 Access Point的跨账号场景。实现架构如下:
1、配置S3存储桶权限授权跨账号访问
在上一步的配置S3存储桶策略的基础上进行轻微修改,调整其中存储桶所有人账号、和被授权的AWS账号、S3 Access Point名称。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::被授权的AWS账号12位数字:root"
},
"Action": "S3:GetObject",
"Resource": [
"arn:aws-cn:s3:::s3accesspoint01",
"arn:aws-cn:s3:::s3accesspoint01/*"
],
"Condition": {
"StringEquals": {
"s3:DataAccessPointArn": "arn:aws-cn:s3:cn-north-1:存储桶Owner的AWS账号12位数字:accesspoint/mys3ap01"
}
}
}
]
}
以上策略表示,授权另一个AWS账号能通过本账号所属的Access Point访问进入。
2、配置S3 Access Point策略
对S3 Access Point配置如下policy,调整其中存储桶所有人账号、和被授权的AWS账号、S3 Access Point名称。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::被授权的AWS账号12位数字:user/zhangsan01"
},
"Action": "S3:GetObject",
"Resource": "arn:aws-cn:s3:cn-north-1:存储桶Owner的AWS账号12位数字:accesspoint/mys3ap01/object/*"
}
]
}
注意,如果S3存储桶策略和S3 Access Point策略有差别,以存储桶策略为准。例如在存储桶策略上设置GetObject授权,但是在S3 Access Point的策略上授权所有访问动作,那么最终用户依然只能GetObject不能获得其他权限。
3、在另一个AWS账号验证账号访问
在被授权的账号内,分别通过AWSCLI执行cp操作,从S3存储桶向本地cp(即GetObject),并测试从本地向存储桶内复制(PutObject),来验证以上授权是否正确。
经过测试,可发现跨账号下载文件(GetObject)成功,且跨账号上传文件(PutObject)被拒绝(和Policy没有授权写入权限的行为是一致的)。
六、参考资料
https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points-policies.html