使用 X.509 客户端 SSL 证书的无令牌授权

bp keystone-tokenless-authz-with-x509-ssl-client-cert

支持使用 X.509 客户端 SSL 证书进行无令牌授权,以提高安全性并简化部署。

有关 X.509 证书的更多信息,请参阅 X.509

问题描述

在典型的企业部署中,服务与 Keystone 通信时需要 SSL 客户端证书身份验证,例如用于令牌验证和资源查找。例如,我们为在服务上运行的 auth_token 中间件配置客户端证书,以便在验证用户令牌时与 Keystone 建立 SSL 客户端证书身份验证会话。在这种情况下,服务无需采取额外的、不必要的步骤来获取服务令牌,以便授权令牌验证调用。我们可以有效地通过其 X.509 SSL 客户端证书来识别服务。借助来自客户端证书的属性以及在请求标头中传达的作用域信息,我们可以通过查找必要身份数据来直接创建授权 credential,而无需颁发令牌。如果满足以下所有条件,则授权 credential 将成功创建

  1. 服务与 Keystone 之间已成功建立 SSL 客户端证书身份验证会话。这意味着客户端证书有效。

  2. 证书满足我们的过滤要求,即证书颁发者匹配我们信任的颁发者之一。

  3. 客户端证书中的属性映射到现有的 Keystone 用户。

  4. Keystone 用户帐户已启用。

  5. 作用域信息在请求标头中传达(例如,X-Project-Id)。

  6. 用户具有给定作用域的一个或多个角色。

使用 X.509 SSL 客户端证书进行无令牌授权的优点是

  • 安全性 - 无需在配置文件中暴露服务用户密码。此外,这具有非承载令牌的效果,因为 SSL 客户端必须拥有相应的私钥。

  • 简单性 - 无需密码。相同的证书可用于身份验证和安全通信。

  • 灵活性 - 此机制不限于 X.509 证书身份验证。它可以扩展到通过不同的映射支持其他外部身份验证机制。例如,如果使用 Kerberos 并且 Apache 前端以完全相同的方式填充 WSGI 请求环境,我们所要做的就是创建一个新的身份提供程序及其相应的映射。无需更改代码。

提议的变更

这是通过实现一个中间件过滤器来实现的,该过滤器根据证书属性和请求标头中的作用域信息构建授权 credential。授权 credential 是一个 Python 字典,它表示 Oslo 策略执行中使用的 credential

由于我们使用 Apache mod_ssl 来处理 SSL 请求,因此 Apache 会在 WSGI 请求环境中传达客户端证书信息。例如

SSL_CLIENT_S_DN
SSL_CLIENT_S_DN_CN
SSL_CLIENT_S_DN_O
SSL_CLIENT_S_DN_OU
SSL_CLIENT_I_DN

有关更多详细信息,请参阅 https://httpd.apache.org/docs/current/mod/mod_ssl.html

此中间件将使用为联合身份验证实现的映射功能,从 SSL 环境变量中构建 Keystone 身份。每个颁发者(即,证书颁发机构)将构成一个身份提供程序 (IdP)。每个 IdP 将恰好有一个映射。IdP ID 将是颁发者 DN 的 SHA256 哈希值。

此外,此中间件将接受以下可配置选项,在 keystone.conf 中的 [auth] 配置部分中定义,以进一步过滤允许参与无令牌授权的证书

trusted_issuers = [<list of trust issuer DNs>]

如果缺少 trusted_issuers,则不允许任何证书参与无令牌授权。

此外,此中间件将期望以下请求标头来传达作用域信息

HTTP_X_PROJECT_ID
HTTP_X_PROJECT_NAME
HTTP_X_PROJECT_DOMAIN_ID
HTTP_X_PROJECT_DOMAIN_NAME
HTTP_X_DOMAIN_ID
HTTP_X_DOMAIN_NAME

缺少作用域标头等同于未作用域的令牌。请注意,对于给定的请求只能指定一个作用域。例如,如果同时指定项目和域作用域,则将构成错误。

备选方案

使用现有的机制,即使用服务令牌进行授权。

数据模型影响

REST API 影响

安全影响

此机制具有非承载令牌的效果,因为 SSL 客户端必须拥有其 SSL 证书的相应私钥。

通知影响

其他最终用户影响

为了使用此功能,服务必须具有有效的 X.509 客户端 SSL 证书。但是,证书管理不在本规范的范围内。

性能影响

其他部署者影响

此功能仅与 Apache mod_ssl 或 mod_nss 结合使用,因为独立的基于 eventlet 的 Keystone 不会解析或传达 WSGI 请求环境中的 X.509 客户端 SSL 证书属性。因此,Keystone 必须在 Apache mod_wsgi 中运行。

请注意,如果部署在负载均衡器中终止 SSL,则负载均衡器必须配置为转发 SSL 客户端证书。

为了使 Apache mod_ssl 在请求环境中传达 SSL 客户端证书信息,SSLOptions 指令必须包含 +StdEnvVars,并且 SSLUserName 指令必须设置为有效的 SSL 要求环境属性。

例如

SetEnv AUTH_TYPE SSL
SSLOptions +StdEnvVars
SSLUserName SSL_CLIENT_S_DN_CN

注意

SSLUserName 指令不能与 +FakeBasicAuth 选项一起使用。有关更多详细信息,请参阅 Apache mod_ssl 此外,请注意环境变量 AUTH_MECHANISM,它用于确定在未来我们支持其他协议时使用哪个映射。

开发人员影响

实现

负责人

主要负责人

guang-yee (gyee)

其他贡献者

工作项

  1. 实现新的中间件,根据 X.509 证书属性创建用于无令牌授权的身份验证上下文。

  2. 更新 auth_token 中间件以使服务令牌可选。

依赖项

此功能仅与 Apache mod_ssl 或 mod_nss 结合使用。因此,Keystone 必须在 Apache mod_wsgi 中运行。

测试

将会有单元测试。对于集成测试,我们可能需要 X.509 证书管理功能(即,Barbican + DogTag)和 Jenkins 中启用的 Apache。

文档影响

  1. 更新 Keystone 配置文档,说明如何使用新的中间件。

  2. 更新 Keystone 中间件配置文档,说明如何使用 SSL 客户端证书代替服务令牌。

参考资料