[EDP] 使用信任委托进行 Swift 身份验证¶
https://blueprints.launchpad.net/sahara/+spec/edp-swift-trust-authentication
Sahara 当前存储和分发访问 Swift 对象的凭据。这些凭据是存储在 Sahara 数据库中的用户名/密码对。此蓝图描述了一种使用 Keystone 的信任委托机制与临时代理用户结合的方法,以消除 Sahara 存储用户凭据的需求。
问题描述¶
Sahara 允许通过存储用户对 Swift 容器中作业二进制文件和数据源的凭据来访问它们。这些凭据存储在 Sahara 的数据库中,并作为作业流程的一部分分发给集群实例,或者由 Sahara 用于访问作业二进制文件。在 Sahara 的数据库中存储用户凭据存在安全风险,可以避免。
提议的变更¶
使用凭据访问 Swift 对象的一种解决方案是在具有访问这些对象的用户和 Sahara 代理用户之间生成 Keystone 信任关系。该信任关系将基于用户在包含 Swift 对象的项目的成员资格而建立。使用此信任关系,Sahara 代理用户可以生成身份验证令牌来访问 Swift 对象。当不再需要访问时,可以撤销信任关系并删除代理用户,从而使令牌失效。
每个作业执行将创建一个代理用户,并属于堆栈管理员专门为容纳这些新用户而创建的无角色域。该域将允许 Sahara 根据需要创建用户,以委托访问 Swift 对象的信任关系。
Sahara 将为创建的代理用户生成用户名和密码。这些凭据将与信任关系结合使用,以允许集群实例访问 Swift。
流程总览
启动时,Sahara 确认代理域是否存在。如果未找到代理域且用户已配置 Sahara 使用它,则 Sahara 将记录错误并恢复到向后兼容模式。
当执行涉及 Swift 对象的新作业时,将在当前上下文用户和新创建的代理用户之间创建信任关系。代理用户的名称和密码由 Sahara 创建并临时存储。
当实例需要访问 Swift 对象时,它将使用代理用户的凭据和信任标识符来创建必要的身份验证令牌。
作业结束后,代理用户和信任关系将从 Keystone 中删除。
详细分解
步骤 1。
启动时,Sahara 将确认管理员在配置文件中指定的代理域是否存在。如果未找到域,并且用户已配置 Sahara 使用它,则它将记录错误并恢复到向后兼容模式。该域将用于存储在作业执行期间创建的代理用户。它应显式具有 SQL 身份后端,或允许 Sahara 创建用户的另一个后端。(SQL 是 Keystone 的默认设置)
如果用户已配置 Sahara 不使用代理域,则它将回退到使用向后兼容的 Swift 身份验证方式。需要用户名和密码才能访问 Swift。
步骤 2。
每当通过 Sahara 发起新的作业执行时,都会在代理域中创建一个新的代理用户。该用户的名称将基于作业执行 ID 生成,并且密码将随机生成。
创建代理用户后,Sahara 将从当前上下文用户委托给代理用户的信任关系。该信任关系将默认授予“Member”角色,但允许配置并模拟上下文用户。由于 Sahara 不会知道作业执行的长度,因此信任关系将生成不带到期时间和无限次重用的信任关系。
步骤 3。
在作业执行期间,当实例需要访问 Swift 对象时,它将使用代理用户的名称和密码与信任标识符结合使用,以创建身份验证令牌。然后将使用此令牌访问 Swift 对象存储。
步骤 4。
作业执行完成后,无论成功与否,代理用户和信任关系都将从 Keystone 中删除。
将定期执行一项任务,以检查代理域用户列表,以确保在作业执行完成后没有用户被卡住或遗弃。
替代方案¶
已经讨论了三种关于此问题的替代方案;使用 Swift 的 TempURL 机制,加密 Swift 凭据,以及将令牌从 Sahara 分发到集群实例。
Swift 实现了一个名为 TempURL 的功能,该功能允许生成临时 URL 以允许公开访问 Swift 对象。使用此功能,Sahara 可以为需要访问的每个 Swift 对象创建 TempURL,然后将这些 URL 分发到作业流程中的集群实例。
虽然 TempURL 在实施所需的工作量方面影响较小,但它们对 Sahara 的用例有一些主要缺点。在创建 TempURL 时,必须将到期日期与 URL 相关联。由于 Sahara 无法预测作业的长度,这意味着为 TempURL 创建无限到期日期。解决此问题的方法是删除 Swift 对象或更改与 TempURL 的创建相关的身份验证标识符。这两个选项都提出了超出 Sahara 范围的影响。此外,TempURL 需要以密码形式传递给实例,以避免潜在的安全漏洞。
讨论的另一种方法涉及加密 Swift 凭据并允许集群实例在需要访问时解密它们。此方法涉及 Sahara 生成用于加密所有凭据的两部分公钥/私钥。解密或私钥部分将分发到所有集群节点。在作业创建期间,与作业关联的 Swift 凭据将被加密并存储。加密的凭据将分发到作业流程中的集群实例。当需要访问 Swift 对象时,实例将使用本地存储的密钥解密凭据。
加密凭据比使用 Keystone 信任关系变化较小,但延续了 Sahara 存储 Swift 对象凭据的当前理念。此外,还涉及一个新的安全管理层,即 Sahara 需要生成和存储用于凭据的密钥。这种复杂性增加了一层管理,可以委托给更合适的 OpenStack 服务(例如 Keystone)。
最后,另一种实现从 Sahara 中删除凭据的可能性是主控制器将预授权令牌分发到集群实例。这些令牌将由实例用于验证其 Swift 访问权限。先前版本的此蓝图由于实施问题而放弃了这种方法。
Keystone 令牌的默认生存期为一小时,此值可以由堆栈管理员调整。这意味着必须至少每小时更新一次令牌,甚至更频繁。更新过程被证明会增加难以克服的障碍。更新频率是一个,但实例上的资源争用是另一个。对这种方法的进一步研究表明,对 Hadoop Swift 文件系统组件的更新将围绕配置数据注入产生不和谐的设计。
数据模型影响¶
作业执行模型当前将用户名和密码信息存储在字典中。该模型不会有任何更改,但信任标识符需要与用户名和密码一起存储。
将凭据传递到集群后,只需要存储用户 ID 和信任标识符。这些需要用于在作业执行后销毁信任关系和用户。代理用户的密码仅在作业执行创建期间需要,并将分发到实例,但不需要长期存储。
REST API 影响¶
应从作业执行输出中删除代理用户名和信任标识符。
其他最终用户影响¶
用户在将 Swift 数据源添加到其作业时不再需要输入凭据。
用户的 OpenStack 凭据需要具有足够的权限才能访问他们添加的 Swift 对象。
从 python-saharaclient,开发人员在发出创建数据源的请求时不再需要输入 credential_user 或 credential_pass。
使用 LDAP 支持的域的 Keystone 部署需要按照 Keystone 组的建议进行配置,使用基于域的配置。这可确保创建的新域将由 SQL 支持。
部署者影响¶
部署者需要了解 Keystone 配置,特别是默认身份后端。他们还需要创建代理域,并为 Sahara 服务用户提供足够的权限,以便在该域中创建新用户。
开发者影响¶
开发人员在创建数据源时不再需要传递凭据。
Sahara-image-elements impact¶
无
Sahara-dashboard / Horizon 影响¶
为了保持向后兼容性,应将用户名和密码字段保留在 Swift 数据源表单和视图中,但应允许用户输入空白数据。
实现¶
负责人¶
主要负责人
Michael McCune
其他贡献者
Trevor McKay
工作项¶
域检测和配置选项
代理用户创建/销毁
信任关系获取/撤销
工作流更新
Swift 文件系统组件更新以使用信任标识符
定期代理用户删除任务
文档
测试
依赖项¶
此功能需要使用启用 OS-TRUST 机制的 Keystone v3。
Horizon 中 Swift 数据源的表单需要允许用户名和密码字段为空条目。
Hadoop Swift 文件系统组件也需要更新。
测试¶
当前针对基于 Swift 的对象的测试需要修改,以删除对用户名/密码凭据的使用。否则,这些测试应证明信任方法正常工作。
应实施针对用户 Keystone 访问权限不允许访问他们添加的 Swift 对象的情况的测试。
Swift 文件系统组件需要对其测试进行修改,以使用信任标识符来限定身份验证令牌的范围。
文档影响¶
使用 Swift 存储的文档需要删除对对象凭据的引用。此外,应添加有关用户无法访问 Swift 资源的影响的文档。
应记录代理域的使用情况,以便为堆栈管理员提供对 Sahara 使用情况和需求的清晰了解。这还应注意 Keystone 配置对不提供默认 SQL 身份后端的影响。
参考资料¶
原始错误报告 https://bugs.launchpad.net/sahara/+bug/1321906
Keystone 信任 API 参考 https://github.com/openstack/identity-api/blob/master/v3/src/markdown/identity-api-v3-os-trust-ext.md