This work is licensed under a Creative Commons Attribution 3.0
Unported License.
http://creativecommons.org/licenses/by/3.0/legalcode

组合令牌和专用帐户

这是一个关于如何使用组合令牌的提案,供 Glance 和 Cinder 等服务存储项目特定的帐户中的对象,同时保留对这些对象访问方式的控制。

该提案使用了 auth_token Keystone 中间件中的“服务令牌组合授权”支持(http://git.openstack.org/cgit/openstack/keystone-specs/plain/specs/keystonemiddleware/service-tokens.rst)。

问题描述

Swift 被许多 OpenStack 服务用于代表用户存储数据。通常有两种方法来存储数据

  • 单项目。对象存储在单个专用的 Swift 帐户中(即,所有用户的所有数据都存储在同一个帐户中)。
  • 多项目。对象存储在最终用户的 Swift 帐户(项目)中。通常,会创建专用的容器来保存这些对象。

以下表格描述了两种方法各自的优点和局限性

项目 特性/主题 单项目 多项目
1 密码泄露易受攻击 (CVE-2013-1840)
2 令牌泄露易受攻击
3 容器删除易受攻击
4 服务用户删除易受攻击
5 Swift 帐户中的“噪音”
6 命名空间冲突(用户和服务选择相同的名称)
7 一致性保证(服务数据库与 swift 帐户)
8 策略执行(例如,镜像下载)

提议的变更

建议将服务数据放入与最终用户的“正常”帐户不同的帐户中。虽然帐户具有不同的名称,但该帐户与最终用户的项目相关联。这解决了噪音和命名空间冲突的问题。为了消除脆弱性并提高一致性保证,建议使用组合令牌功能来管理对该帐户的访问。

总而言之,有三个相关的更改

  • 支持组合令牌
  • 授权逻辑可以需要来自组合令牌的身份验证信息
  • 支持多个经销商前缀,每个前缀都有自己的配置

效果是必须通过服务访问数据。此外,服务只有在处理来自最终用户的请求时才能访问数据(即,当它具有最终用户的令牌时)。

本文档逐一描述这些更改。不耐烦的人可以直接跳到“OpenStack 环境中的组合令牌”以获取完整的示例。

组合令牌

身份验证系统将验证第二个令牌。该令牌存储在 X-Service-Token 标头中,因此被称为服务令牌(Keystone 选择的名称)。

令牌身份验证方案的核心功能是确定用户是谁、正在访问哪个帐户以及应用哪些角色。Keystoneauth 和 Tempauth 具有略微不同的语义,因此令牌的组合方式略有不同,如下面各节所述。

Keystoneauth 中组合角色

当存在服务令牌时,将使用以下规则

  • user_id 是第一个令牌中的 user_id(即,没有更改)。
  • 帐户(项目)由第一个令牌指定(即,没有更改)。
  • 用户角色最初由第一个令牌确定(即,没有更改)。
  • 服务令牌中的角色在 service_roles 中可用。

示例 1 - 在 keystoneauth 中组合角色

在此示例中,<token-two> 的范围是与正在访问的帐户/项目不同的项目

Client
  |                               <user-token>: project-id: 1234
  |                                                user-id: 9876
  |                                                  roles: admin
  | X-Auth-Token: <user-token>
  | X-Service-Token: <token-two>
  |
  |                                <token-two>: project-id: 5678
  v                                                user-id: 5432
Swift                                                roles: service
  |
  v
Combined identity information:
     user_id: 9876
     project_id: 1234
     roles: admin
     service_roles: service

Tempauth 中组合组

两个令牌的用户组简单地组合成一个列表。下图给出了一个示例

Client
  |                               <user-token>: from "joe"
  |
  |
  | X-Auth-Token: <user-token>
  | X-Service-Token: <token-two>
  |
  |                               <token-two>: from "glance"
  v
Swift
  |
  |  [filter:tempauth]
  |  user_joesaccount_joe: joespassword .admin
  |  user_glanceaccount_glance: glancepassword servicegroup
  |
  v
Combined Groups: .admin servicegroup

支持多个经销商前缀

reseller_prefix 现在将支持一个前缀列表。例如,以下支持AUTH_SERVICE_在 keystoneauth 中

[filter:keystoneauth]
reseller_prefix = AUTH_, SERVICE_

为了向后兼容,默认值仍然是AUTH_.

假定所有现有的配置选项都适用于列表中的第一个项目。但是,为了指示选项适用于哪个前缀,请将前缀放在选项名称之前。这适用于以下选项

  • operator_roles (keystoneauth)
  • service_roles (如下所述) (keystoneauth)
  • require_group (如下所述) (tempauth)

其他选项(日志记录、storage_url_scheme 等)不特定于经销商前缀。

例如,这显示了两个前缀和一些选项

[filter:keystoneauth]
reseller_prefix = AUTH_, SERVICE_
reseller_admin_role = ResellerAdmin     <= global, applies to all
AUTH_operator_roles = admin             <= new style
SERVICE_operator_roles = admin
allow_overrides = false

支持组合授权

我们将向 keystoneauth 添加一个名为“service_roles”的选项。如果存在,则必须使用组合令牌,并且 service_roles 必须包含列出的角色。这是一个示例,其中AUTH_命名空间需要将“admin”角色与 X-Auth-Token 相关联。该SERVICE_命名空间需要将“admin”角色与 X-Auth-Token 相关联。此外,它需要将“service”角色与 X-Service-Token 相关联

[filter:keystoneauth]
reseller_prefix = AUTH_, SERVICE_
AUTH_operator_roles = admin
SERVICE_operator_roles = admin
SERVICE_service_roles = service

在 tempauth 中,我们将添加一个名为“require_group”的选项。如果存在,则用户或服务用户必须是此组的成员。(由于 tempauth 组合来自 X-Auth-Token 和 X-Service-Token 的组,所需的组可能来自任一或两个令牌)。

以下显示了一个示例

[filter:tempauth]
reseller_prefix = AUTH_, SERVICE_
SERVICE_require_group = servicegroup

OpenStack 环境中的组合令牌

本节介绍一个简单的配置,显示从客户端通过 OpenStack 服务到 Swift 的流程。我们在此示例中使用 Glance,但原理对于所有服务都是相同的。有关更具体的服务设置,请参见后面的内容。

流程如下

Client
   |                               <user-token>: project-id: 1234
   |                                                user-id: 9876
   | (request)                                        roles: admin
   | X-Auth-Token: <user-token>
   |
   v
Glance
   |
   | PUT /v1/SERVICE_1234/container/object
   | X-Auth-Token: <user-token>
   | X-Service-Token: <glance-token>
   |
   |                             <glance-token>: project-id: 5678
   v                                                user-id: 5432
 Swift                                                roles: service
   |
   v
 Combined identity information:
      user_id: 9876
      project-id: 1234
      roles: admin
      service_roles: service

      [filter:keystoneauth]
      reseller_prefix = AUTH_, SERVICE_
      AUTH_operator_roles = admin
      AUTH_reseller_admin_roles = ResellerAdmin
      SERVICE_operator_roles = admin
      SERVICE_service_roles = service
      SERVICE_reseller_admin_roles = ResellerAdmin

授权逻辑如下

 /v1/SERVICE_1234/container/object
     -------
        |
       in?
        |
reseller_prefix = AUTH_, SERVICE_
        \
        Yes
          \
    Use SERVICE_* configuration
           |
           |
    /v1/SERVICE_1234/container/object
                ----
                 |
             same as? project-id: 1234
                 \
                 Yes
                   \
               roles: admin
                   |
                  in? SERVICE_operator_roles = admin
                   \
                   Yes
                     \
                   service_roles: service
                     |
                    in? SERVICE_service_roles = service
                     \
                     Yes
                       \
                        ----> swift_owner = True

其他方面

Tempurl, FormPOST, 容器同步

这些工作原理是密钥存储在特权标头中。没有提出更改,因为本文档中描述的帐户控制继续使用此概念。但是,可以使用临时 URL 来允许客户端上传或下载到服务帐户的对象,从而实现一个额外的用例。

特定于服务的帐户

使用通用的SERVICE_命名空间意味着所有 OpenStack 服务共享同一个帐户。一个简单的替代方案是使用多个帐户 - 对应于 reseller_prefixes 和服务目录条目。例如,Glance 可以使用IMAGE_而 Cinder 可以使用VOLUME_。该提案中没有任何内容限制此选项。这是一个可能的配置示例

[filter:keystoneauth]
reseller_prefix = AUTH_, IMAGE_, VOLUME_
IMAGE_service_roles glance_service
VOLUME_service_roles = cinder_service

python-swiftclient

python-swiftclient 不需要任何更改来支持此功能。

服务更改以使用SERVICE_命名空间

服务(如 Glance、Cinder)需要进行增强,如下所示才能使用SERVICE_namespace

  • 更改路径以使用适当的前缀。应用程序在其环境中具有 HTTP_X_SERVICE_CATALOG,因此很容易构造适当的路径。
  • 将他们的令牌添加到 X-Service-Token 标头
  • 他们应该为此令牌具有适当的服务角色
  • 他们应该将他们的服务类型(例如,image)作为他们创建的任何容器名称的前缀。这将防止共享帐户的服务之间的冲突。

升级影响

在服务尝试使用SERVICE_命名空间之前,必须升级 Swift 软件。由于服务使用可配置的选项来决定它们如何使用 Swift,因此应该很容易地进行排序(即,首先升级软件,然后更改服务的配置选项)。

服务如何处理现有的遗留数据不在本提案的范围内。

备选方案

帐户 ACL

早期草案提出了扩展帐户 ACL。它还提出了添加默认帐户 ACL 概念。经审查,认为这对于此用例是不必要的(尽管这项工作可能会自行进行)。

共同所有者 sysmeta

早期草案提出了建立容器“共同所有权”规则的新 sysmeta。

policy.xml 文件:

Keystone 组合授权方案对其他 Openstack 项目具有用例。OSLO 孵化器策略检查器模块可以扩展以支持从 X-Service-Token 获取的角色。但是,只有当 keystoneauth 已经使用 policy.xml 文件时,才会使用它。

如果 keystoneauth 调整了策略文件,则应该很容易应用。实际上,将为每个经销商前缀提供不同的 policy.xml 文件。

代理日志记录:

代理日志记录中间件记录 X-Auth-Token 的值。没有提出更改。

实现

负责人

主要负责人
donagh.mccabe@hp.com

为了完全有效,其他项目需要进行更改

  • Keystone 中间件。完成
  • OSLO。如上所述,可能不需要或依赖于。
  • Glance。 stuart.mclaren@hp.com 将进行 Glance 的更改。
  • Cinder。未知。
  • Devstack。Swift 的更改本身可能不需要 Devstack 的更改。Glance 和 Cinder 服务可能需要额外的配置选项才能启用 X-Service-Token 功能。Assignee:未知
  • Tempest。原则上,不需要进行任何更改,因为该提案旨在对最终用户透明。但是,有些测试可能直接访问镜像或卷备份,这可能会出错。Assignee:未知
  • Ceilometer(用于SERVICE_命名空间)。尚不清楚是否需要任何更改或是否可取。

工作项

  • swift/common/middleware/tempauth.py 已修改以支持多个经销商前缀、require_group 选项以及处理 X-Service-Token 标头
  • swift/common/middleware/keystoneauth.py 已修改以支持多个经销商前缀和 service_roles 选项。
  • 编写单元测试
  • 编写功能测试

仓库

不会创建新的 git 存储库。

服务器

不会创建新的服务器。keystoneauth 中间件由代理服务器使用。

DNS 条目

不会创建或更新 DNS 条目。

依赖项