Rgw bucket policy权限设置
一. bucket policy 的应用需求
在上一篇中关于tenant,可以知道 tenant 用作用户的隔离,在实际的应用场景中,情况可能会复杂一些,关于bucket,默认的权限是只有创建者有权限访问,和使用。现在来考虑一下其他应用场景。
- 同一个租户内的用户创建的bucket如何给其他用户访问权限
- 不同租户下用户的创建的bucket 如何访问
二. bucket policy 说明
从官网中的BUCKET POLICIES文档中可以看到,bucket policy 是从L版开始才增加的特性,并且相比AWS的policy,ceph支持的特性是AWS policy 的子集。
bucket policy 的存储形式是bucket meta rados 对象的一个xattr 属性,属性名是user.rgw.iam-policy,policy的文本结构如下
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": ["arn:aws:iam::usfolks:user/fred"]},
"Action": "s3:PutObjectAcl",
"Resource": [
"arn:aws:s3:::happybucket/*"
]
}]
}
- Version : policy版本,目前测试只能设定为”2012-10-17”
Effect : 允许或者禁止 > 可选值 1. Allow 2. Deny
Principal: 指定规则生效的对象 > 格式为 “Principal”:{“AWS”:“arn:aws:iam::[tenant]:user/[username]“}
Action : 操作, 目前可以设定的操作可以看官方文档,比较长
Resource : 限定的资源,一般就是指bucket
三. bucket policy实践
1.用1个默认tenant的用户和1个显示指定tenant的用户去测试应用场景
tenant ID | user ID | bucket ID |
---|---|---|
默认 | df_user1 | df_bucket1 |
tenant_1 | user1 | bucket3 |
# radosgw-admin bucket list
[
"df_bucket1",
"tenant_1/bucket3",
]
# radosgw-admin user list
[
"df_user1",
"tenant_1$user1",
]
- 因为boto3 不支持ceph的tenant,所以这里对bucket的操作全部使用boto
所有的bucket都已经上传了, 名为”testfile.txt”的文件
2.授予所有用户 df_bucket1 的ListBucket 权限
a. policy.json
{ "Version": "2012-10-17", "Statement": [ { "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::df_bucket1", "arn:aws:s3:::df_bucket1/*" ], "Effect": "Allow", "Principal": { "AWS": "*" } } ] }
注意这个Version 是不能改的,ceph会对这个版本进行检查,如果对应不上,会报参数错误
b. 设置policy的的boto代码
import sys import boto import boto.s3.connection from boto.s3.key import Key if __name__ == "__main__": # df_user1 access_key = "CCIMF23H3Z3OY7RTZESM" secret_key = "BP7oioaBdqHxlFgQlMNA2rAci4e7CNe6lkIRM0tf" bucket = ":df_bucket1" conn = boto.connect_s3(aws_access_key_id=access_key, aws_secret_access_key=secret_key, host='172.26.2.52', port=7480, is_secure=False, calling_format = boto.s3.connection.OrdinaryCallingFormat()) bk = conn.get_bucket(bucket) policy = """ { "Version": "2012-10-17", "Statement": [ { "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::df_bucket1", "arn:aws:s3:::df_bucket1/*" ], "Effect": "Allow", "Principal": { "AWS": "*" } } ] } """ bk.set_policy(policy)
- 还有一个比较暴力的方法就是,直接用rados 给这个对象setxattr 同样可以设置policy
c. 验证一下policy 在rados对象中的存储
// 1. 查看bucket 元数据对象的属性 # rados listxattr .bucket.meta.df_bucket1:ea8654d1-f637-4d51-b269-7c443f58d8d7.1154355.9 -p tupu-zone1.rgw.meta --namespace root ceph.objclass.version user.rgw.acl user.rgw.iam-policy // 这个就是刚刚对bucket设置的policy // 2. 查看user.rgw.iam-policy 属性的值 # rados getxattr .bucket.meta.df_bucket1:ea8654d1-f637-4d51-b269-7c443f58d8d7.1154355.9 user.rgw.iam-policy -p tupu-zone1.rgw.meta --namespace root { "Version": "2012-10-17", "Statement": [ { "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::df_bucket1", "arn:aws:s3:::df_bucket1/*" ], "Effect": "Allow", "Principal": { "AWS": ["arn:aws:iam::tenant_1:user/user1"] } } ] }
确实是设置成功的 ( 对namespace 有疑问的可以看看,本站关于namespace的文档 )
d. 尝试用用户tenant_1 的user1 访问 df_bucket1
import sys import boto import boto.s3.connection from boto.s3.key import Key # tenant$user1 access_key = "ZXG1FADOHRNMAM9YSN3D" secret_key = "2ApioxknYXcCXEY1B0Pu7RS3lhzxhRB5FHhb5StP" bucket = ":df_bucket1" conn = boto.connect_s3(aws_access_key_id=access_key, aws_secret_access_key=secret_key, host='172.26.2.52', port=7480, is_secure=False, calling_format = boto.s3.connection.OrdinaryCallingFormat()) bk = conn.get_bucket(bucket) print(bk.get_all_keys())
# python rgw_bucket.py [<Key: df_bucket1,testfile.txt>]
测试结果,user1是可以ListBucket的,可以获取object吗?
bk = conn.get_bucket(bucket) k = Key(bk) k.key = 'testfile.txt' filename = './testfile.txt.1' k.get_contents_to_filename(filename)
结果为 “boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden”, 因为没有getobject的权限。
设置GetObject 权限
{ "Version": "2012-10-17", "Statement": [ { "Action": ["s3:ListBucket", "s3:GetObject"], "Resource": [ "arn:aws:s3:::df_bucket1", "arn:aws:s3:::df_bucket1/*" ], "Effect": "Allow", "Principal": { "AWS": ["arn:aws:iam::tenant_1:user/user1"] } } ] }
再次尝试,就可以下载文件了