自助服务代理用户服务域¶
https://storyboard.openstack.org/#!/story/2001214
为了向 Monasca 发送指标和日志,Monasca 代理目前需要一个具有特殊 Keystone 角色的 Keystone 用户,通常是 monasca-agent。这对于 OpenStack 云的基础设施监控来说是可行的,因为对监控感兴趣的人通常也可以创建用户帐户,并且这些帐户的凭据存储在云的计算节点和控制器上,这些节点和控制器应该得到良好保护以防止泄露。将此类凭据存储在面向公众的实例上,由 Monasca 监控会成为一个问题,因为这些实例 (a) 更容易暴露,并且 (b) 因为创建实例的 OpenStack 用户通常无法创建专用用户帐户。本规范提出了解决这两个问题的方案。
问题描述¶
目前有两种方式为给定的 OpenStack 项目提交指标和日志
跨租户提交:这需要一个具有特殊角色的用户,该用户可以代表任何任意项目提交指标或日志。此角色目前由计算节点使用,以提交其运行实例所在项目的 libvirt 指标。这些角色由 monasca-api 的 security/delegate_authorized_roles 设置和 monasca-log-api 的 roles_middleware/delegate_roles 设置控制。
项目内用户提交指标:这是正常方式。项目中任何具有指定 Monasca 代理角色(默认为 monasca-agent)的用户都可以为该项目提交指标和日志。这些角色由 monasca-api 的 security/agent_authorized_roles 设置和 monasca-log-api 的 roles_middleware/agent_roles 设置控制。
从安全角度来看,这两种选择都很糟糕。(1) 更糟糕,因为它允许为任意项目提交任意虚假日志条目/指标事件。由于这种高滥用潜力,并且因为它目前仅在 monasca-agent 的 libvirt 监控插件中实现,因此不太可能用于实例监控。(2) 带来了略低但仍然存在问题的安全风险
如果用户想要监控他们的实例,他们需要将具有 monasca-agent 角色的 OpenStack 用户的 Keystone 凭据传递给他们的实例。与项目中任何具有任何角色的 OpenStack 用户一样,该用户可以访问任意 OpenStack API 并随意创建/删除资源。虽然可以为 monasca-agent 角色向每个其他 OpenStack 服务的 policy.json 添加全局拒绝规则,但这在实践中不太可能实现。因此,实例及其 monasca-agent 泄露通常会导致攻击者无限制地带外访问其创建用户的 Keystone 项目。这通常允许它,例如:
创建、查看和删除 Nova 实例
创建、查看和删除 Neutron 网络
创建、查看和删除 Cinder 卷
创建、查看和删除 Glance 镜像
除了这个安全问题,还有一个可用性问题。一个普通的 OpenStack 用户既不能创建 Keystone 用户,也不能将 monasca-agent 角色分配给这些用户。因此,任何需要为其实例进行 Monasca 监控的用户都需要请求具有管理员权限的人创建用户并将 monasca-agent 角色分配给该用户。因此,自助实例监控是不可能的。
用例¶
本规范提出的更改将如下改善上述情况
最终用户将能够以自助服务方式获取其实例的指标和日志代理的访问凭据。
最终用户因受损的带有 Monasca 代理的实例而面临的攻击面将减少到为其项目提交虚假指标/日志。
提议的变更¶
这项更改借鉴了 OpenStack Magnum,特别是 CVE-2016-7404[0] 的修复。在此修复之前,Magnum 会在单独的域中创建 Keystone 委托用户,并通过 Keystone 信任委托集群所有者的一个或多个角色。这些用户帐户在大多数情况下只用于向 Magnum API 提交证书签名请求,因此它们与 monasca 代理用户拥有同样宽松的权限。对 CVE-2016-7404 的修复将信任的使用范围缩小到真正需要它们的场景:在默认情况下,这些用户不会获得任何委托的信任,也没有分配角色,这使得它们对大多数 OpenStack API 来说毫无用处。Magnum API 的 certificate:create 和 certificate:sign 的策略规则是此规则的唯一例外:如果用户存在于 Magnum 域中且用户 ID 与给定集群的记录用户 ID 匹配,则允许访问。
对于 Monasca,本规范提出了一个类似的代理用户 Keystone 域,就像 Magnum 的委托用户域一样。同样,Monasca API 服务将获得对此域的管理帐户的访问权限,以便它可以在该域中创建用户。最后一块拼图是 Monasca 指标和日志 API 的两个扩展
一个 monasca-api 端点,允许最终用户为其项目创建这些特殊的代理用户并检索其凭据。
对 monasca-api 和 monasca-log-api 的日志和指标提交端点的修改,允许为与相关代理用户关联的项目提交。
本节的其余部分将详细描述此更改如何影响 monasca-api 的各个部分。
备选方案¶
有些事情可以通过与下面概述的方法不同的方式来实现
可以用一个轻量级的自动生成的 API 密钥来代替用于代理用户的相当重量级的 Keystone 域。这将使凭据更精简,但它将允许完全不通过 Keystone 进行 monasca-api/monasca-log-api 提交的授权。这更多是一个政治问题,而不是技术问题。此外,monasca-client 将需要额外的自定义代码来使用此 API 密钥进行身份验证,这可能会引入额外的安全错误。总的来说,这可能是一个坏主意(在 IRC 上讨论时,人们也赞成使用 Keystone)。
可以不在数据库中记录代理用户的项目关联和权限,而是将其编码在代理用户的用户名中。不过,这就不够优雅了。另一方面,我们就不需要创建数据库表/向 monasca-log-api 添加数据库客户端代码了。
当前方法是 monasca-api 处理指标和日志提交的代理用户的创建/删除。可以设想为两个 API 实现独立的用户创建,但这会增加大量的实现开销,却没什么好处。
数据模型影响¶
我们将需要引入一个名为 agent_users 的新表,包含以下字段
id (字符串):代理用户的 Keystone 用户 UUID。唯一主键。
creator_id (字符串):创建用户的 Keystone 用户 UUID
project_id (字符串):用户可以为其提交日志指标的项目
- submit_metrics (布尔值):创建时指定的可选标志。默认为
如果未指定则为 True。控制用户是否被允许提交指标
- submit_logs (布尔值):创建时指定的可选标志。默认为
如果未指定则为 True。控制用户是否被允许提交日志。
为了使此功能正常工作,monasca-log-api 将需要数据库客户端实现和相应的配置选项,这是理所当然的。为了减少代码重复,尽可能多的 monasca-api 数据库处理代码将被移动到 monasca-common,monasca-api 和 monasca-log-api 都可以从中调用。
REST API 影响¶
REST API 需要在 3 个地方进行修改
需要有一个自助服务代理用户创建功能
monasca-api 需要根据代理用户关联的项目以及其 submit_metrics 标志是否设置为 True 来授予或拒绝指标提交。
monasca-api 需要根据代理用户关联的项目以及其 submit_metrics 标志是否设置为 True 来授予或拒绝日志提交。
本节的其余部分将详细描述这些 API 更改。
代理用户处理¶
为了能够创建、删除和列出代理用户,以及检索代理用户的凭据,本规范提议对 monasca-api 进行以下扩展
POST /v2.0/agent_users
此请求创建代理用户。请求体必须遵循以下 JSON 模式
{
type: "map",
required: "true",
"mapping": {
"password": { "type": "int", "required": false },
"submit_metrics": { "type": "boolean", "required": false },
"submit_logs": { "type": "boolean", "required": false }
}
}
参数行为如下:
- password:如果设置此项,则提供的密码将用作代理
用户的密码。否则,将使用随机生成的 40 个字符的字符串。
- submit_metrics:如果此项设置为 False,则此代理用户将不被
允许向 monasca-api 提交指标。此参数是可选的。如果省略,默认为 True,并且代理用户将被允许发送指标。
- submit_logs:如果此项设置为 False,则此代理用户将不被
允许向 monasca-log-api 发送日志。此参数是可选的。如果省略,默认为 True,并且代理用户将被允许向 monasca-log-api 发送日志。
此请求将
如果请求成功,则返回 200,并在正文中包含代理用户的 JSON 格式数据库记录。除了数据库记录外,响应还将包含一个 password 字段,其中包含新创建用户的密码。此密码将**不**记录在数据库中。
如果用户创建失败,则返回 500 并在正文中包含错误消息。
对于未经身份验证的用户或没有任何角色的用户,返回 401。
GET /v2.0/agent_users
此请求列出代理用户。它将
返回 200 OK 和一个 JSON 格式的代理用户数据库记录列表,用于请求者的项目。对于具有 admin 角色的请求者,将列出所有项目的代理用户。列表可能为空。
对于未经身份验证的用户或没有任何角色的用户,返回 401。
GET /v2.0/agent_users/<id>
此请求检索代理用户的数据库记录。它将
如果数据库中存在 <id> 的记录且请求者被允许访问,则返回 200,并在正文中包含由 Keystone 用户 ID <id> 标识的代理用户的 JSON 格式记录。如果请求者的项目与 project_id 匹配,或者请求者满足 oslo.policy is_admin 条件,则允许请求者访问记录。
如果用户没有记录或请求者不允许访问,则返回 404。
对于未经身份验证的用户或没有任何角色的用户,返回 401。
指标提交的扩展策略检查¶
请求
POST /v2.0/metrics
将需要扩展,不仅检查 security/agent_authorized_roles 中配置的角色,还需要验证以下内容:
请求用户是否在指定的代理用户域中
如果是,则在 agent_users 表中查找用户,并为代理用户的记录项目提交正在发送的指标。
如果查找因某种原因失败(例如,代理用户域中手动创建的用户在数据库中没有记录),则请求被视为未经授权。
日志提交的扩展策略检查¶
以下请求
POST /v3.0/logs
…将需要扩展,不仅要检查 roles_middleware/delegate_roles 中配置的角色,还需要验证以下内容:
请求用户是否在指定的代理用户域中
如果是,请在 agent_users 表中查找用户,并为代理用户的记录项目提交正在发送的日志。
如果查找因某种原因失败(例如,代理用户域中手动创建的用户没有关联的域),则请求被视为未经授权。
客户端影响¶
python-monascaclient 将需要扩展,以实现上述 代理用户处理 部分中描述的 API 操作。
monasca-agent 将不需要修改。
配置更改¶
monasca-api 将需要配置设置,以便为其代理用户域提供管理员设置。
monasca-log-api 将需要配置设置,以便其能够访问 monasca-api 数据库。
monasca-api 和 monasca-log-api 都需要配置,允许操作员根据需要禁用此功能。由于它允许用户创建监控用户,因此默认情况下应禁用。另外,应该可以配置创建代理用户所需的 Keystone 角色。如果未指定此角色,则任何用户都应该能够创建代理用户)
安全影响¶
此功能引入了一种机制,允许普通用户在专用 Keystone 域中创建非特权专用用户帐户。这可能不适用于每个操作员,因此上一节中规定了禁用或限制它的条款。
所涉专用用户没有 Keystone 角色,因此对大多数用途而言是不可用的。这在 Heat 和 Magnum 中有先例。前者创建此类用户作为 Heat 堆栈创建用户委托的 Keystone 信任的目标。后者创建此类用户作为 CVE-2016-7404[0] 修复的一部分,并以与本规范提议的完全相同的方式使用它们。
其他最终用户影响¶
用户将能够以自助服务方式创建专用监控/日志记录用户,这比目前的情况有所改进(他们需要请求具有管理员权限的人创建具有特殊 monasca-agent 角色的用户)。
性能影响¶
此更改可能会因为每次指标提交尝试都增加一次数据库查找而带来少量性能损失。不过,这应该不会太糟糕,因为每次指标提交尝试都需要 Keystone 令牌验证,而一次数据库查找的影响相对较小。尽管如此,如果此功能被证明会导致严重的性能问题,则可以在找到修复方案之前禁用它。
其他部署者影响¶
N/A
开发者影响¶
N/A
实现¶
负责人¶
- 主要负责人
jgr-启动板
工作项¶
将通用数据库代码添加到 monasca-common。
修改 monasca-api 以使用 monasca-common 中的数据库代码并删除其自身的数据库代码。
在 monasca-api 中实现代理用户 CRUD 操作
扩展 monasca-api 策略强制代码以授权代理用户
扩展 monasca-log-api 策略强制代码以授权代理用户
依赖项¶
测试¶
文档影响¶
代理用户的自助服务创建需要进行文档说明。
各种新引入的配置设置需要进行文档说明。
需要记录为代理用户创建域的过程。
参考资料¶
[0] https://github.com/openstack/magnum/commit/2d4e617a529ea12ab5330f12631f44172a623a14
历史记录¶
发布名称 |
描述 |
|---|---|
Queens |
引入 |