对象存储 COS 的权限管理分析

作者介绍:

杨冠军:腾讯云 COS 首席解决方案架构师,现负责腾讯云对象存储 COS 华东区域客户的解决方案架构工作。

随着互联网和公有云的发展,越来越多的企业把数据放到公有云上,COS(Cloud Object Storage)作为腾讯云的对象存储产品,提供了高容量、高可靠、低成本的存储解决方案,也使得客户把越来越多的业务数据放到了 COS 上。

在数字化时代,数据逐渐成为了公司的核心资产,存储到对象存储 COS 上的数据安全性也越来越受到了重视,COS 本身提供了一系列高安全性的防护,包括:数据加密、链路加密、权限控制、版本控制、跨地域复制等等。

结合最近互联网上出现的安全事故,我们发现 COS 的权限控制和管理是用户最容易造成疏漏的地方,本文将从 COS 的权限介绍和最佳实践等方面来对 COS 的权限管理做深入分析,希望对你理解 COS 的权限控制和有效管理 COS 的权限有所帮助。

COS 相关权限

首先我们先从逻辑上介绍下 COS 权限的分类,并对每一分类详细分析。

1、访问权限

分为公共权限和用户权限两类:

1)公共权限

公共权限是 COS 最基本的权限配置,包括:继承权限、私有读写、公有读私有写和公有读写,支持的配置对象和说明如下:

权限类型

配置项

说明

继承权限

虚拟目录、Object

存储桶里对象权限的默认值,继承存储桶的权限

私有读写

Bucket、虚拟目录、Object

仅主账号可写可读,非主账号用户(子账号、其他用户的主账号或者匿名用户)不可访问

公有读私有写

Bucket、虚拟目录、Object

主账号可写可读,非主账号用户(子账号、其他用户的主账号或者匿名用户)可以读取,但是不可写入新数据

公有读写

Bucket、虚拟目录

主账号和非主账号用户(子账号、其他用户的主账号或者匿名用户)均可写可读

这里着重对 Bucket 支持的公有权限做下说明:

  • 私有读写:默认创建 Bucket 的权限,这个是比较安全的权限配置,也是我们推荐的!

  • 公有读私有写:若你需要公开 Bucket 里的数据,可以这样配置,允许任何用户不携带签名来读取 Bucket 里的 Object。

  • 公有读写:这个是最不安全的权限配置了,相当于你把修改数据的权限都暴露了,请谨慎配置!

COS 对存储桶的公共权限配置,在存储桶的权限管理页面,参考下图:

对象存储 COS 的权限管理分析_第1张图片

公共权限配置

2)用户权限

用户权限,这里指的是 ACL,全称:Access Control List,即权限控制列表,它是一种比较传统的权限管理方式。

与常见的 Linux 的 ACL 有所不同,对象存储的 ACL 有自己的控制粒度和权限集合。COS 支持向每个存储桶和对象都设置关联的 ACL,支持向其他主账号、子账号和用户组,授予基本的读、写权限。

ACL 支持的控制粒度分类如下:

  • 存储桶(Bucket)

  • 对象键前缀(Prefix)

  • 对象(Object)

ACL 支持的权限操作组介绍如下:

操作组

授予存储桶

授予前缀

授予对象

READ

列出和读取存储桶中的对象

列出和读取目录下的对象

读取对象

WRITE

创建、覆盖和删除存储桶中的任意对象

创建、覆盖和删除目录下的任意对象

不支持

READ_ACP

读取存储桶的 ACL

读取目录下的 ACL

读取对象的 ACL

WRITE_ACP

修改存储桶的 ACL

修改目录下的 ACL

修改对象的 ACL

FULL_CONTROL

对存储桶和对象的任何操作

对目录下的对象做任何操作

对对象执行任何操作

另外 ACL 的管理权限还有以下限制:

  • 仅支持对腾讯云的账户赋予权限

  • 仅支持读对象、写对象、读 ACL、写 ACL 和全部权限等五个操作组

  • 不支持赋予生效条件

  • 不支持显式拒绝效力

所以通过 ACL,我们可以方便的授予其他用户访问存储桶或对象的权限,比如:

  • 与其他主账号的数据共享

    示例:允许另一个主账号对某个存储桶的读取权限:

对象存储 COS 的权限管理分析_第2张图片

user-read-acl

  • 授予子账号访问的权限,做到权限的下放

    示例:授予一个子账号对某个存储桶的数据读写权限:

对象存储 COS 的权限管理分析_第3张图片

subuser-read-write-acl

2、Policy 权限

相比简单的 COS 访问权限配置,COS 还支持配置较为复杂的 Bucket 粒度的 Policy 权限。

Bucket Policy 权限使用 JSON 语言描述,支持向匿名身份或腾讯云任何 CAM 账户授予对存储桶、存储桶操作、对象或对象操作的权限。Bucket Policy 权限可以用于管理该存储桶内的几乎所有操作,推荐你使用存储桶策略来管理通过 ACL 无法表述的访问策略。

Bucket Policy 权限的配置界面如下:

对象存储 COS 的权限管理分析_第4张图片

bucket-policy

  • 效力:允许/禁止

  • 用户:单击添加用户,用户类型包括:所有用户/根账号/子账号/云服务

  • 资源:根据需要选择,默认为整个存储桶,也可指定资源

  • 资源路径:仅指定资源时需要填写,根据需要填写,仅支持使用*做前缀匹配

  • 操作:单击添加操作,选择所有操作,如仅需授权部分操作,也可以选择一个或多个实际需要的操作

  • 条件:根据需要填写,如不需要可留空。当前条件名支持:IP 和 VPC ID

注意:上述用户配置中的所有用户,一般是针对匿名用户的意思。

  • 配置允许所有用户访问,则匿名的请求会被允许访问

  • 配置拒绝所有用户访问,则匿名的请求会被拒绝,携带签名的请求会以基于身份的策略进行鉴权

3、CAM 策略

访问管理(Cloud Access Management,CAM)是腾讯云提供的一套 Web 服务,用于帮助客户安全地管理腾讯云账户的访问权限,资源管理和使用权限。通过 CAM,你可以创建、管理和销毁用户(组),并通过身份管理和策略管理控制哪些人可以使用哪些腾讯云资源。

COS 作为腾讯云的一种资源,可以通过 CAM 策略来管理用户、用户组对 COS 资源的访问权限,使得不同团队或人员能够相互协作。

首先,我们需要先了解几个关键概念:主账号、子账号和用户组。

  • 主账号:

    • 用户申请腾讯云账号时,系统会创建一个用于登录腾讯云服务的主账号身份

    • 主账号默认拥有其名下所拥有的资源的完全访问权限

  • 子账号:

    • 子账号是由主账号创建的实体,有确定的身份 ID 和身份凭证,拥有登录腾讯云控制台的权限

    • 子账号默认不拥有资源,必须由所属主账号进行授权

  • 用户组:

    • 多个相同职能的用户(子账号)的集合

    • 可以根据业务需求创建不同的用户组,为用户组关联适当的策略,以分配不同权限

赋予子账号或用户组访问 COS 资源的权限,可以通过下面两种方式:

1)COS 预设策略

COS 提供了很多种 COS 资源的预设策略,可以满足你大部分的需求,这些预设策略仅仅是从 COS 的操作权限的粒度来做区分,比如:QcloudCOSFullAccess、QcloudCOSDataFullControl、QcloudCOSListOnly 等。

2)自定义策略

顾名思义,自定义策略就是你来根据策略语法,制定自己的规则,这个的灵活性很大,功能性也最丰富。在实践中,客户针对不同 Bucket,或不同前缀的访问控制,都可以通过自定义策略来实现。

所以基于 CAM,我们可以完成更复杂的权限管理,结合用户组、子账号、COS 预设策略和自定义策略,可以更灵活、更精细的来管理用户访问的 COS 权限,这也是我们推荐客户使用的!

4、角色策略

角色(Role)是腾讯云访问管理(Cloud Access Management,CAM)提供的拥有一组权限的虚拟身份,主要用于对角色载体授予腾讯云中服务、操作和资源的访问权限,这些权限附加到角色后,通过将角色赋予腾讯云的服务,允许服务代替用户完成对授权资源的操作。

目前腾讯云支持的角色载体类型为:

  • 腾讯云账号

  • 支持角色的腾讯云服务

从上面的描述可以看出,角色主要是用在以下两种场景:

1)授权资源访问权限给其他腾讯云主账号,而又不期望把永久访问密钥直接给对方,可以配置角色的载体为腾讯云主账号,绑定相关权限策略。比如你期望把 COS 所有 Buckets 的只读权限授权给另一个腾讯云主账号:100000xxxx,则可以通过创建下面的角色来实现:

  • 角色载体:腾讯云主账号100000xxxx

  • 角色策略:仅仅指定 QcloudCOSDataReadOnly

2)授权其他腾讯云服务访问指定资源的权限。比如你期望通过云函数(SCF)来对 COS Bucket 上传对象做进一步处理,就需要 SCF 有创建 COS 触发器,拉取代码包等的权限,这时候你就可以通过创建下面的角色来实现:

  • 角色载体:腾讯云的 SCF 服务

  • 角色策略:包含创建 COS 触发器,拉取代码包等的权限

权限策略判断规则

上文中我们提到,COS 的相关权限有很多种:访问权限、Policy 权限、CAM 策略等,那用户的访问请求发到 COS 端,是按照什么规则来检查权限的呢?

首先介绍下要对访问用户分为两类:

  1. 匿名用户:不带签名的访问

  2. 认证用户:携带签名的用户,解析出对应的账号信息

而认证用户的访问策略又分如下两类:

  1. 用户组策略

  2. 用户策略

另外,COS 自身的访问策略也分为两类:

  1. 存储桶和对象的 ACL

  2. 存储桶的 Policy

基于上面用户、访问策略和 COS 自身策略的分类,从流程上来看,COS 端收到用户请求后的权限判断如下:

对象存储 COS 的权限管理分析_第5张图片

访问策略评估流程

另外,在访问权限的判断中,有下面的几项原则,也需要我们注意:

  1. 主账号默认有账号下所有 bucket 的访问权限;

  2. 默认所有匿名用户访问都被拒绝;

  3. 显式拒绝的优先级最大;

  4. 生效权限范围为基于身份策略和基于资源策略的并集。

最佳实践

从上文的介绍来看,COS 的权限管理这块还是非常复杂的。而很多管理员为了方便,相信会有直接配置 COSFullAccess 策略的冲动 -_-||,这个还请慎重,它会给你带来很大的安全隐患!

下面从管理的便捷性和数据的安全性出发,我们推荐一些 COS 权限的最佳实践原则。

1、子用户与分组策略

如之前描述,CAM 支持子账号和分组,那在实际使用中,为了管理的方便,我们可以根据组织规则来创建出对应的用户组和子账号,然后再做权限分配。

这里的原则是:

  • 先创建用户组,并关联适当的 COS 权限

  • 再创建子用户,把子用户添加到用户组里

比如我们期望某员工有对 COS 所有资源的读写权限,则可以操作如下:

1) 创建用户组:cos-buckets-read-write-group1,然后给其关联上 COS 资源的 read 和 write 权限:QcloudCOSDataReadOnly 和 QcloudCOSDataWriteOnly;

2) 创建子用户:cos-subuser1,并把它添加到用户组 cos-buckets-read-write-group1;

3) 把子用户的 SecretId 和 SecretKey 授予具体使用的员工。

2、最小权限原则

最小权限原则是 COS 权限安全的最重要策略,就是针对用户的需求,授予他最小访问资源的访问权限。

把握最小权限原则,可以从下面几个方面考虑:

  • 指定用户:针对每个子用户授予权限

  • 指定 bucket:不要随便赋予所有 bucket 的访问权限

  • 指定 bucket 里 objects 的前缀:能明确只有固定资源,就通过前缀规则限制

  • 指定操作:明确对 bucket/object 的操作集合,比如:GetBucket、HeadBucket、GetObject 等

  • 指定条件:明确策略生效的约束条件,比如 IP 地址、VPCID 等

3、使用临时密钥

客户端使用 COS 时,通过固定密钥计算签名方式不能有效地控制权限,同时把永久密钥放到客户端代码中有极大的泄露风险。如若通过临时密钥方式,则可以方便、有效地解决权限控制问题。

例如,在客户端申请临时密钥过程中,可以通过设置权限策略 policy 字段,限制操作和资源范围,将权限限制在指定的范围内。

使用临时密钥访问 COS 资源的整体架构图如下:

对象存储 COS 的权限管理分析_第6张图片

cos 接入 cam 框架图

上述架构图中各个组件的功能如下:

1、用户客户端:用户服务的客户端;

  • 向用户服务器发送申请临时密钥请求

  • 根据获取的临时密钥,携带签名访问 COS 对象存储

2、用户服务端:提供临时密钥服务;

  • 配置永久密钥,向 CAM 权限系统申请临时密钥

  • 向客户端提供临时密钥 API

3、CAM 权限系统:腾讯云的 CAM 服务;

  • 响应用户服务端的临时密钥请求

  • 与 COS 对象存储同步临时密钥

4、COS 对象存储

  • 支持临时密钥签名的访问

分析 COS 权限的脚本

如上文描述,COS 相关的权限,我们可以从 COS 和 CAM 的控制台上来分别获取。

基于最佳实践原则,我们推荐 COS Bucket 配置为私有读写,这也就要求访问 COS 需要是 CAM 的主账号、子账号或角色等。而 CAM 和 COS 都提供了 API 来获取到权限相关的信息,基于这些 API 的返回结果,我们可以从 CAM USERCAM ROLE 的维度来分析账号下所有 COS Bucket 的权限配置。

从 Bucket 的维度分析用户权限,请到 COS 控制台,选取 bucket 后,到权限管理页面查看

1、脚本概述

CAM 和 COS 都提供了很多语言的 SDK 支持,这里选择 Python 语言的 SDK,调用 CAM 和 COS 的 API,来分析一个账户下所有 COS Bucket 的权限配置信息。

脚本下载链接:https://github.com/ictfox/tools/blob/master/cos-auth-analyse.py

参考 API 和 Python SDK 的链接如下:

  • COS

    • API:https://cloud.tencent.com/document/product/436/12269

    • Python SDK:https://github.com/tencentyun/cos-python-sdk-v5

  • CAM:

    • API:https://cloud.tencent.com/document/api/598/43337

    • Python SDK:https://github.com/TencentCloud/tencentcloud-sdk-python

2、脚本使用说明

1)配置脚本

# vim cos-auth-analyse.py
...
# Config with your own secretid/secretkey
secret_id = 'your secret id'
secret_key = 'your secret key'
...

配置有 CAM 相关权限和 COS 所有 Buckets 访问权限的 CAM 子账号的 SecretId 和 SecretKey。

比较方便的权限为:QcloudCamFullAccess 和 QcloudCOSFullAccess,或仅仅用主账号运行

2)运行脚本

# python cos-auth-analyse.py
Initialize user related cos buckets and cam group info, waiting...
Response Error Msg Is INVALID


============
Input: user-name/uin/bucket-name? or r(camrole)? or a(all)? or q(quit)? a
...

Response Error Msg Is INVALID - 错误信息输出可能是因为 cos bucket 没有配置 policy,可以忽略

在提示输出栏输入:a,即可获取到所有 CAM USER 的分析输出。

分析单个 user,输入:user-name 或 uin 即可。

3)输出分析

该脚本主要从 CAM USERCAM ROLE 两个维度输出其相关 COS Bucket 的权限,下面分别介绍如下:

  • CAM USER 输出

    输出示例如下:

CamUser:  {
    "ConsoleLogin" : 0,
    "CosPolicy" : [
      {
        "PolicyName" : "QcloudCOSDataWriteOnly",
        "PolicyType" : "",
        "Remark" : "对象存储(COS)数据只写的访问权限(不含删除)"
      },
      ...
    ],
    "Name" : "cosnew",
    "Remark" : "",
    "Uid" : xxxxx,
    "Uin" : xxxxxxxxx
  }
  
  COS Buckets:  [
    {
      "Bucket" : "picture-123456789",
      "acl" : [],
      "policy" : [
        {
          "Action" : [
            "name/cos:GetBucketACL",
            "name/cos:GetObjectACL"
          ],
          "Effect" : "Allow",
          "Principal" : {
            "qcs" : [
              "qcs::cam::uin/10000067xxxx:uin/1000107xxxx"
            ]
          },
          "Resource" : [
            "qcs::cos:na-ashburn:uid/123456789:picture-123456789/*"
          ],
          "Sid" : "costs-158684633500000xxxxx-11615-2"
        }
      ]
    }
  ]
  
  COS Related CamGroup: [
    {
      "Name" : "cos",
      "Policy" : [
        {
          "PolicyName" : "QcloudCOSFullAccess",
          "PolicyType" : "QCS",
          "Remark" : "对象存储(COS)全读写访问权限"
        }
      ]
    }
  ]

基于 CAM USER 的输出,与 COS 权限相关的有如下三个:

  1. CamUser 里的 CosPolicy:直接绑定在 CamUser 上与 COS 相关的 policies,可以从 PolicyName 中获取大概的 COS 权限信息,详细的请到 CAM 的策略管理里查询;

  2. COS Buckets:该 CamUser 有访问权限的 COS Buckets,里面的 Policy 里是详细的权限信息;

  3. COS Related CamGroup:该 CamUser 关联到的有 COS 访问权限的 CamGroup,可以从 Policy 里的 PolicyName 中获取到大概的 COS 权限信息,详细的请到 CAM 的策略管理里查询;

  • CAM ROLE 输出

    输出示例如下:

 CamRole:  {
    "ID" : "xxxxxxxxx",
    "Name" : "test-cos-role",
    "Type" : "user",
    "description" : "",
    "policy" : [
      {
        "Description" : "对象存储(COS)数据读、写、删除、列出的访问权限",
        "PolicyId" : 52xxxxxxx,
        "PolicyName" : "QcloudCOSDataFullControl",
        "PolicyType" : "QCS"
      }
    ],
    "policy document" : [
      {
        "action" : "name/sts:AssumeRole",
        "effect" : "allow",
        "principal" : {
          "qcs" : [
            "qcs::cam::uin/100000xxxxxx:root"
          ]
        }
      }
    ]
  }

基于 CAM ROLE 的输出,我们主要关注以下两个方面:

  1. policy:与 COS 相关的 policies,可以从 Description 上获取大概信息,详细的请通过 PolicyId 调用相关 API 查询

  2. policy document:角色绑定的载体信息,可以看出角色授权给了哪个腾讯云主账号或腾讯云服务

本文系作者授权发表,未经许可,不得转载。

如有侵权,请联系小编删除,谢谢。

 点击阅读原文,领取 COS 限时1元礼包!

你可能感兴趣的:(对象存储 COS 的权限管理分析)