keithyau 2019-06-29
要对S3的访问权限做控制,既可以使用基于身份的策略(IAM用户策略),也可以使用基于资源的策略(ACL和存储桶策略)。
访问一个存储桶的权限控制流程如图所示:
访问存储桶中的对象的权限控制流程如图所示:
当 Amazon S3 收到对象操作请求时,它会将基于资源的所有相关权限(对象访问控制列表 (ACL)、存储桶策略、存储桶 ACL)和IAM用户策略转换为将在运行时进行评估的策略集。然后它会通过一系列步骤评估生成的策略集。在每个步骤中,它会在三个特定上下文 (用户上下文、存储桶上下文和对象上下文) 中评估一个策略子集。
简单来说就是先判断用户权限,然后判断存储桶权限,最后判断对象权限。
目前我们都是通过同一个AWS账户下的多个IAM用户去访问S3的,因此可以只使用IAM用户策略去做访问权限控制,这也基本能满足绝大部分常规的权限控制需求,如果无法满足的情况再考虑使用存储桶处理和ACL。
Harp
)登录AWS管理控制台,选择IAM服务进入,创建一个名为Administrators
的组,并向其附加AdministratorAccess
权限;Harp-Admin
),并将其添加到Administrators
组;Harp-Admin
,点击安全凭证;Harp-Admin
已经开启了MFA验证,使用该用户登录控制台时,需要在验证密码之后,再验证MFA(即输入Authy中的实时CODE);Harp-Admin
来处理的;s3_common_policy
;{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::derek-public*" ] }, { "Sid": "AllowRootLevelListingOfTheBucket", "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::derek-bucket3" ], "Condition": { "StringEquals": { "s3:prefix": [ "" ], "s3:delimiter": [ "/" ] } } }, { "Sid": "AllowListBucketOfASpecificUserPrefix", "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::derek-bucket3" ], "Condition": { "StringLike": { "s3:prefix": [ "public/*" ] } } }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::derek-public1/*", "arn:aws:s3:::derek-bucket3/public/*" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::derek-public2/*" } ] }
解释一下各条statements:
statement1: 对所有的S3资源赋予s3:ListAllMyBuckets和s3:GetBucketLocation,这两个权限是给控制台使用的,通过控制台访问S3时,需要这两个权限来正常列出所有存储桶,如果通过CLI访问则不需要;
statement2: 赋予所有derek-public开头的存储桶列出存储桶对象的权限(s3:ListBucket);
statement3: 允许列出derek-bucket3第一层路径下的对象,这个写法可以在S3的官方文档中找到;
statement4: 允许列出derek-bucket3/public下的所有对象;
statement5: 允许对derek-public1和derek-bucket3/public中的对象读写、复制操作;
statement6: 允许对derek-public2中的对象读取操作;
s3_common_group
,并将所有用户添加到其中,将s3_common_policy
附加到这个组;derek-public1
、derek-public2
和derek-bucket3/public
,其中derek-public2
只有可读权限,如果用户尝试写入,例如创建一个文件夹,会显示“无法使用名称XXX创建文件夹”;derek-bucket1
或derek-bucket3/user1
,会显示“Access Denied”;user1_policy
;{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::derek-bucket1", "arn:aws:s3:::derek-bucket2" ] }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::derek-bucket1/*", "arn:aws:s3:::derek-bucket3/user1/*" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::derek-bucket2" }, { "Sid": "AllowListBucketOfASpecificUserPrefix", "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::derek-bucket3" ], "Condition": { "StringLike": { "s3:prefix": [ "user1/*" ] } } } ] }
解释一下各条statements:
statement1: 允许列出derek-bucket1和derek-bucket2中的所有对象;
statement2: 允许对derek-bucket1和derek-bucket3/user1中的对象读写、复制操作;
statement3: 允许对derek-bucket2中的对象读取操作;
statement4: 允许列出derek-bucket3/user1下的所有对象;
user1_policy
,审核,添加权限;user2_policy
;{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::derek-bucket2" ] }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::derek-bucket2/*", "arn:aws:s3:::derek-bucket3/user2/*" ] }, { "Sid": "AllowListBucketOfASpecificUserPrefix", "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::derek-bucket3" ], "Condition": { "StringLike": { "s3:prefix": [ "user2/*" ] } } } ] }
解释一下各条statements:
statement1: 允许列出derek-bucket2
中的所有对象;
statement2: 允许对derek-bucket2
和derek-bucket3/user2
中的对象读写、复制操作;
statement3: 允许列出derek-bucket3/user2
下的所有对象;
user3_policy
;{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::derek-bucket3" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::derek-bucket3" } ] }
Harp-Admin
为user4创建虚拟MFA;user4_policy
;{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::derek-bucket4" ] }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::derek-bucket4/*" ] }, { "Effect": "Deny", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::derek-bucket4/mfa/*" ], "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": false } } }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::derek-bucket4/mfa/*" ] } ] }
解释一下各条statements:
statement1: 允许列出derek-bucket4中的所有对象;
statement2: 允许对derek-bucket4中的对象读写、复制操作;
statement3: 未通过MFA验证时禁止写derek-bucket4/mfa下的所有对象;
statement4: 允许读取derek-bucket4/mfa下的所有对象;
MFA ARN
和MFA当前的6位token,会返回一个json格式的临时凭证,该凭证默认有效期12h,更多关于CLI和MFA的内容可参考 如何使用 MFA 令牌对通过 AWS CLI 进行的 AWS 资源访问执行身份验证?:mfa-user
,将上一步的结果复制到这里;mfa-user
复制文件到mfa文件夹,提示复制成功;在使用user1时,在derek-bucket1
中建立文件夹没有问题,但是上传文件却失败,提示OptionsRequestDenied
,经谷歌查询猜测可能和浏览器的AdBlock相关插件有关,于是换火狐浏览器、或者使用CLI上传,都没有问题。