配置 Keystone 以进行无令牌授权¶
定义¶
X.509 无令牌授权: 提供了一种使用 X.509 SSL 客户端证书在 Keystone 中授权客户端操作的方式,而无需颁发令牌。
此功能旨在通过消除对服务用户令牌进行身份验证和授权的需求,从而降低 Keystone
auth_token中间件中用户令牌验证的复杂性。因此,无需创建和维护服务用户帐户,仅用于用户令牌验证。此外,此功能通过避免服务用户令牌处理(即请求、缓存和续订)来提高效率。通过无需在配置文件中处理服务用户凭据,部署者无需承担在整个部署生命周期中保护服务器用户密码的负担。此功能还通过使用 X.509 证书而不是密码进行身份验证来提高安全性。有关详细信息,请参阅规范 使用 X.509 客户端 SSL 证书进行无令牌授权
公钥基础设施或 PKI: 一种利用公钥密码学实现身份验证、授权、机密性、完整性、不可否认性的系统。在该系统中,身份由公钥证书表示。公钥证书处理受 X.509 标准管理。
X.509 证书: 一种有时间限制的数字身份,由其颁发者使用加密方式进行认证或数字签名,如 X.509 标准所定义。它包含可用于唯一标识其所有者的信息。例如,证书的所有者由
Subject属性标识,而颁发者由Issuer属性标识。在操作中,证书通常以 隐私增强邮件 (PEM) 格式存储。
以下是一个证书通常包含的内容的示例
Certificate: Data: Version: 3 (0x2) Serial Number: 4098 (0x1002) Signature Algorithm: sha256WithRSAEncryption Issuer: DC = com, DC = somedemo, O = openstack, OU = keystone, CN = Intermediate CA Validity Not Before: Jul 5 18:42:01 2019 GMT Not After : Jul 2 18:42:01 2029 GMT Subject: DC = com, DC = somedemo, O = Default, OU = keystone, CN = glance Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:cf:35:8b:cd:4f:17:28:38:25:f7:e2:ac:ce:4e: d7:05:74:2f:99:04:f8:c2:13:14:50:18:70:d6:b0: 53:62:15:60:59:99:90:47:e2:7e:bf:ca:30:4a:18: f5:b8:29:1e:cc:d4:b8:49:9c:4a:aa:d9:10:b9:d7: 9f:55:85:cf:e3:44:d2:3c:95:42:5a:b0:53:3e:49: 9d:6b:b2:a0:9f:72:9d:76:96:55:8b:ee:c4:71:46: ab:bd:12:71:42:a0:60:29:7a:66:16:e1:fd:03:17: af:a3:c7:26:c3:c3:8b:a7:f9:c0:22:08:2d:e4:5c: 07:e1:44:58:c1:b1:88:ae:45:5e:03:10:bb:b4:c2: 42:52:da:4e:b5:1b:d6:6f:49:db:a4:5f:8f:e5:79: 9f:73:c2:37:de:99:a7:4d:6f:cb:b5:f9:7e:97:e0: 77:c8:40:21:40:ef:ab:d3:55:72:37:6c:28:0f:bd: 37:8c:3a:9c:e9:a0:21:6b:63:3f:7a:dd:1b:2c:90: 07:37:66:86:66:36:ef:21:bb:43:df:d5:37:a9:fa: 4b:74:9a:7c:4b:cd:8b:9d:3b:af:6d:50:fe:c9:0a: 25:35:c5:1d:40:35:1d:1f:f9:10:fd:b6:5c:45:11: bb:67:11:81:3f:ed:d6:27:04:98:8f:9e:99:a1:c8: c1:2d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Client, S/MIME Netscape Comment: OpenSSL Generated Client Certificate X509v3 Subject Key Identifier: EE:38:FB:60:65:CD:81:CE:B2:01:E3:A5:99:1B:34:6C:1A:74:97:BB X509v3 Authority Key Identifier: keyid:64:17:77:31:00:F2:ED:90:9A:A8:1D:B5:7D:75:06:03:B5:FD:B9:C0 X509v3 Key Usage: critical Digital Signature, Non Repudiation, Key Encipherment X509v3 Extended Key Usage: TLS Web Client Authentication, E-mail Protection Signature Algorithm: sha256WithRSAEncryption 82:8b:17:c6:f4:63:eb:8d:69:03:7a:bf:54:7f:37:02:eb:94: ef:57:fd:27:8f:f8:67:e9:0e:3b:0a:40:66:11:68:e6:04:1a: 8a:da:47:ed:83:eb:54:34:3b:5b:70:18:cf:62:e2:6d:7c:74: 4c:cf:14:b3:a9:70:b2:68:ed:19:19:71:6f:7d:87:22:38:8d: 83:c6:59:15:74:19:5b:a2:64:6f:b9:9a:81:3d:0a:67:58:d1: e2:b2:9b:9b:8f:60:7a:8c:0e:61:d9:d7:04:63:cc:58:af:36: a4:61:86:44:1c:64:e2:9b:bd:f3:21:87:dd:18:81:80:af:0f: d6:4c:9f:ae:0f:01:e0:0e:38:4d:5d:71:da:0b:11:39:bd:c3: 5d:0c:db:14:ca:bf:7f:07:37:c9:36:bd:22:a5:73:c6:e1:13: 53:15:de:ac:4a:4b:dc:48:90:47:06:fa:d4:d2:5d:c6:d2:d4: 3f:0f:49:0f:27:de:21:b0:bd:a3:92:c3:cb:69:b6:8d:94:e1: e3:40:b4:80:c7:e6:e2:df:0a:94:52:d1:16:41:0f:bc:29:a8: 93:40:1b:77:28:a3:f2:cb:3c:7f:bb:ae:a6:0e:b3:01:78:09: d3:2b:cf:2f:47:83:91:36:37:43:34:6e:80:2b:81:10:27:95: 95:ae:1e:93:42:94:a6:23:b8:07:c0:0f:38:23:70:b0:8e:79: 14:cd:72:8a:90:bf:77:ad:74:3c:23:9e:67:5d:0e:26:15:6e: 20:95:6d:d0:89:be:a3:6c:4a:13:1d:39:fb:21:e3:9c:9f:f3: ff:15:da:0a:28:29:4e:f4:7f:5e:0f:70:84:80:7c:09:5a:1c: f4:ac:c9:1b:9d:38:43:dd:27:00:95:ef:14:a0:57:3e:26:0b: d8:bb:40:d6:1f:91:92:f0:4e:5d:93:1c:b7:3d:bd:83:ef:79: ee:47:ca:61:04:00:e6:39:05:ab:f0:cd:47:e9:25:c8:3a:4c: e5:62:9f:aa:8a:ba:ea:46:10:ef:bd:1e:24:5f:0c:89:8a:21: bb:9d:c7:73:0f:b9:b5:72:1f:1f:1b:5b:ff:3a:cb:d8:51:bc: bb:9a:40:91:a9:d5:fe:95:ac:73:a5:12:6a:b2:e3:b1:b2:7d: bf:e7:db:cd:9f:24:63:6e:27:cf:d8:82:d9:ac:d8:c9:88:ea: 4f:1c:ae:7d:b7:c7:81:b2:1c:f8:6b:6b:85:3b:f2:14:cb:c7: 61:81:ad:64:e7:d9:90:a3:ea:69:7e:26:7a:0a:29:7b:1b:2a: e0:38:f7:58:d1:90:82:44:01:ab:05:fd:68:0c:ab:9e:c6:94: 76:34:46:8b:66:bb:02:07
有关更多信息,请参阅 公钥证书。
颁发者: X.509 证书的颁发者。它也被称为 证书颁发机构 (CA) 或认证机构。颁发者通常以 RFC 2253 格式表示。在本文档中,
issuer、issuer DN、CA和trusted issuer可以互换使用。
先决条件¶
此功能要求 Keystone API 代理 SSL 终止器验证传入的 X.509 SSL 客户端证书,并将证书信息(即主题 DN、颁发者 DN 等)作为请求环境的一部分传递给 Keystone 应用程序。在撰写本文时,此功能仅使用 HAProxy 或 Apache 作为 Keystone API 代理 SSL 终止器进行了测试。
本文档的其余部分要求读者熟悉
配置此功能需要 OpenSSL 命令行工具 (CLI)。请参阅各自的操作系统安装指南,了解如何安装它。
Keystone 配置¶
此功能利用 Keystone 联合能力来确定与传入的 X.509 SSL 客户端证书关联的授权,方法是将证书属性映射到 Keystone 身份。因此,客户端证书的直接颁发者或受信任的证书颁发机构 (CA) 是远程身份提供者 (IDP),并且颁发者专有名称 (DN) 的 SHA256 哈希的十六进制输出用作 IDP ID。
注意
客户端证书颁发者 DN 的格式可能因 SSL 终止器而异。例如,Apache mod_ssl 可能会使用 RFC 2253,而 HAProxy 可能会使用旧格式。旧格式由链接到 OpenSSL 旧版本的应用程序使用,其中专有名称的字符串表示形式尚未成为事实标准。有关旧格式的更多信息,请参阅 OpenSSL CLI 手册中的 nameopt。因此,在整个配置中保持格式一致非常重要,因为 Keystone 在比较证书属性时会进行精确的字符串匹配。
如何获取受信任的颁发者 DN¶
如果 SSL 在 HAProxy 或 Apache 处终止,则可以使用 OpenSSL CLI 获取客户端证书颁发者 DN。
从版本 2.3.11 开始,Apache mod_ssl 默认使用 RFC 2253 处理证书专有名称。但是,部署者可以通过配置 LegacyDNStringFormat 选项来使用旧格式。
另一方面,HAProxy 仅支持旧格式。
要以 RFC 2253 格式获取颁发者 DN
$ openssl x509 -issuer -noout -in client_cert.pem -nameopt rfc2253 | sed 's/^\s*issuer=//'
要以旧格式获取颁发者 DN
$ openssl x509 -issuer -noout -in client_cert.pem -nameopt compat | sed 's/^\s*issuer=//'
如何从受信任的颁发者 DN 计算 IDP ID¶
受信任颁发者 DN 的 SHA256 哈希的十六进制输出正在 Keystone 中用作身份提供者 ID。可以使用 OpenSSL CLI 获取它。
要为 RFC 2253 格式的颁发者 DN 计算 IDP ID
$ openssl x509 -issuer -noout -in client_cert.pem -nameopt rfc2253 | tr -d '\n' | sed 's/^\s*issuer=//' | openssl dgst -sha256 -hex | awk '{print $2}'
要为旧格式的颁发者 DN 计算 IDP ID
$ openssl x509 -issuer -noout -in client_cert.pem -nameopt compat | tr -d '\n' | sed 's/^\s*issuer=//' | openssl dgst -sha256 -hex | awk '{print $2}'
Keystone 配置文件更改¶
Keystone 配置文件 keystone.conf 的 tokenless_auth 部分中的以下选项用于启用 X.509 无令牌授权功能
trusted_issuer- X.509 SSL 客户端证书的受信任颁发者列表。更具体地说,是 如何获取受信任的颁发者 DN 部分中提到的受信任颁发者 DN 列表。受信任颁发者 DN 的格式必须与 SSL 终止器传递到请求环境中的格式完全匹配。例如,如果 SSL 在 Apache mod_ssl 中终止,则颁发者 DN 应该采用 RFC 2253 格式。如果 SSL 在 HAProxy 中终止,则预计颁发者 DN 将采用旧格式。这是一个多字符串列表选项。没有任何受信任的颁发者意味着实际上禁用了 X.509 无令牌授权功能。protocol- 与选项 issuer_attribute 结合使用,用于查找其对应的映射的 X.509 无令牌授权协议名称。默认值为x509。issuer_attribute- 作为 X.509 无令牌授权的 IdP ID 的颁发者属性,并与协议结合使用以查找其对应的映射。它是 WSGI 环境中的环境变量,引用客户端证书的颁发者。默认值为SSL_CLIENT_I_DN。
这是一个包含两个 trusted_issuer 和将 protocol 设置为 x509 的示例配置。
[tokenless_auth]
trusted_issuer = emailAddress=admin@foosigner.com,CN=Foo Signer,OU=eng,O=abc,L=San Jose,ST=California,C=US
trusted_issuer = emailAddress=admin@openstack.com,CN=OpenStack Cert Signer,OU=keystone,O=openstack,L=Sunnyvale,ST=California,C=US
protocol = x509
设置映射¶
与联合身份验证一样,X.509 无令牌授权也利用映射机制来确定与传入的 X.509 SSL 客户端证书关联的身份,方法是将证书属性映射到 Keystone 身份。因此,身份提供者对应于 X.509 SSL 客户端证书的颁发者。默认情况下,给定身份的协议为 x509,但可以进行配置。
创建身份提供者 (IDP)¶
如前所述,身份提供者 ID 是颁发者专有名称 (DN) 的 SHA256 哈希的十六进制输出。
注意
如果有多个受信任的颁发者,则必须创建多个 IDP,每个受信任的颁发者一个。
要为给定的受信任颁发者创建 IDP,请遵循 如何从受信任的颁发者 DN 计算 IDP ID 部分中的说明来计算 IDP ID。然后使用 OpenStack CLI 创建 IDP。例如:
$ openstack identity provider create --description 'IDP foo' <IDP ID>
创建映射¶
需要创建映射,将客户端证书中的 Subject DN 映射为用户,如果用户的 type 在映射中定义为 local,则产生有效的本地用户。例如,如果客户端证书具有 Subject DN 为 CN=alex,OU=eng,O=nice-network,L=Sunnyvale, ST=California,C=US,在以下示例中,user_name 将映射到``alex``,domain_name 将映射到 nice-network。并且用户的 type 设置为 local。如果未定义用户的 type,则默认设置为 ephemeral。
请参阅 mod_ssl,了解详细的映射属性。
[
{
"local": [
{
"user": {
"name": "{0}",
"domain": {
"name": "{1}"
},
"type": "local"
}
}
],
"remote": [
{
"type": "SSL_CLIENT_S_DN_CN",
"whitelist": ["glance", "nova", "swift", "neutron"]
},
{
"type": "SSL_CLIENT_S_DN_O",
"whitelist": ["Default"]
}
]
}
]
当用户的 type 未定义或设置为 ephemeral 时,映射的用户不必是有效的本地用户,但映射必须产生至少一个有效的本地组。例如
[
{
"local": [
{
"user": {
"name": "{0}",
"type": "ephemeral"
},
"group": {
"domain": {
"name": "{1}"
},
"name": "openstack_services"
}
}
],
"remote": [
{
"type": "SSL_CLIENT_S_DN_CN",
"whitelist": ["glance", "nova", "swift", "neutron"]
},
{
"type": "SSL_CLIENT_S_DN_O",
"whitelist": ["Default"]
}
]
}
]
注意
上述映射假定 openstack_services 组已存在并具有适当的角色分配(即允许令牌验证)。如果不是,则需要创建它。
要使用 OpenStack CLI 创建映射,假设映射已保存到文件 x509_tokenless_mapping.json
$ openstack mapping create --rules x509_tokenless_mapping.json x509_tokenless
注意
映射 ID 是任意的,它可以是任何字符串,与 IDP ID 不同。
创建协议¶
协议名称必须与 tokenless_auth 部分 Keystone 配置文件的 protocol 选项指定的名称相同。协议名称由用户设计,可以采用任何名称,与 IDP ID 不同。
协议名称和 IDP ID 将唯一标识映射。
要使用 OpenStack CLI 创建协议
$ openstack federation protocol create --identity-provider <IDP ID>
--mapping x509_tokenless x509
注意
如果有多个受信任的颁发者,则必须为每个 IDP 创建多个协议。所有 IDP 可以共享相同的映射,但 IDP ID 和协议的组合必须是唯一的。
SSL 终止器配置¶
Apache 配置¶
如果 SSL 在 Apache mod_ssl 处终止,则 Apache 必须配置为处理双向 SSL,并将 SSL 证书信息作为请求环境的一部分传递给 Keystone 应用程序。
客户端身份验证属性 SSLVerifyClient 应设置为 optional 以允许其他令牌身份验证方法,并且属性 SSLOptions 需要设置为 +StdEnvVars 以允许传递证书属性。例如,
<VirtualHost *:443>
WSGIScriptAlias / /var/www/cgi-bin/keystone/main
ErrorLog /var/log/apache2/keystone.log
CustomLog /var/log/apache2/access.log combined
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.cer
SSLCertificateKeyFile /etc/apache2/ssl/apache.key
SSLCACertificatePath /etc/apache2/capath
SSLOptions +StdEnvVars
SSLVerifyClient optional
</VirtualHost>
HAProxy 和 Apache 配置¶
如果 SSL 在 HAProxy 处终止,而 Apache 是 Keystone 应用程序的 API 代理,则 HAProxy 必须配置为处理双向 SSL,并通过请求标头传递 SSL 证书信息。Apache 反过来需要将这些请求标头引入请求环境。
以下是如何配置 HAProxy 以处理双向 SSL 并通过请求标头传递 SSL 证书信息的示例。
frontend http-frontend
mode http
option forwardfor
bind 10.1.1.1:5000 ssl crt /etc/keystone/ssl/keystone.pem ca-file /etc/keystone/ssl/ca.pem verify optional
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
http-request set-header X-SSL %[ssl_fc]
http-request set-header X-SSL-Client-Verify %[ssl_c_verify]
http-request set-header X-SSL-Client-SHA1 %{+Q}[ssl_c_sha1]
http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn]
http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)]
http-request set-header X-SSL-Client-O %{+Q}[ssl_c_s_dn(o)]
http-request set-header X-SSL-Issuer %{+Q}[ssl_c_i_dn]
http-request set-header X-SSL-Issuer-CN %{+Q}[ssl_c_i_dn(cn)]
当请求到达 Apache Keystone API 代理时,Apache 需要将这些 SSL 标头引入请求环境。以下是如何配置 Apache 以实现此目的的示例。
<VirtualHost 192.168.0.10:5000>
WSGIScriptAlias / /var/www/cgi-bin/keystone/main
# Bring the needed SSL certificate attributes from HAProxy into the
# request environment
SetEnvIf X-SSL-Issuer "^(.*)$" SSL_CLIENT_I_DN=$0
SetEnvIf X-SSL-Issuer-CN "^(.*)$" SSL_CLIENT_I_DN_CN=$0
SetEnvIf X-SSL-Client-CN "^(.*)$" SSL_CLIENT_S_DN_CN=$0
SetEnvIf X-SSL-Client-O "^(.*)$" SSL_CLIENT_S_DN_O=$0
</VirtualHost>
设置 auth_token 中间件¶
为了将 auth_token 中间件用作 X.509 无令牌授权的服务客户端,需要设置可配置的选项和范围信息。
可配置的选项¶
应将 auth_token 中间件中的以下可配置选项设置为正确的值
auth_type- 必须设置为v3tokenlessauth。certfile- 设置为证书文件的完整路径。keyfile- 设置为私钥文件的完整路径。cafile- 设置为受信任的 CA 证书文件的完整路径。project_name或project_id- 设置为作用域项目。project_domain_name或project_domain_id- 如果指定了project_name。
这是一个使用 X.509 无令牌授权进行用户令牌验证的 auth_token 中间件配置的示例。
[keystone_authtoken]
memcached_servers = localhost:11211
cafile = /etc/keystone/ca.pem
project_domain_name = Default
project_name = service
auth_url = https://192.168.0.10/identity/v3
auth_type = v3tokenlessauth
certfile = /etc/glance/certs/glance.pem
keyfile = /etc/glance/private/glance_private_key.pem