keystone
基础概念
官网手册
Keystone 是 OpenStack 的身份认证与服务目录组件,作为整个云平台的核心服务之一,提供统一的认证、授权和服务发现功能。它确保所有用户和服务之间的交互受到严格的身份验证和权限控制
主要功能
- 身份认证(Authentication)
功能:验证用户或服务的身份。
机制:通过用户名、密码、API 密钥或令牌进行验证。
支持方式:
传统用户名和密码认证。
外部身份认证(LDAP、Kerberos、OAuth、SAML 等)。
单点登录(SSO)集成。 - 授权(Authorization)
功能:基于角色的访问控制 (RBAC)。
工作流程:
用户通过 Keystone 进行身份认证后,获取临时令牌。
令牌中嵌入用户的角色和权限范围。
其他服务根据令牌校验用户的访问权限。
- 组件的相关名词
-
用户(User):
用户是能够通过 Keystone 进行认证的实体。用户可以是人,也可以是系统进程。
用户拥有凭证(如用户名和密码、API 密钥等)以进行身份验证。 -
角色(Role):
角色是权限的集合,用于定义用户在租户中的操作权限。
角色并不直接授予用户,而是通过与租户的关联来实现授权。 -
租户(Tenant)/ 项目(Project):
租户(也称为项目)是一个逻辑上的组,用于隔离资源(如虚拟机、存储、网络等)。
一个租户可以包含多个用户,并且每个用户可以拥有不同的角色。 -
域(Domain):
域是一种高级别的分区,用于管理用户和项目的命名空间。
域允许对不同组织的用户和项目进行隔离和独立管理。 -
凭证(Credential):
凭证是用户的认证信息,如用户名和密码、API 密钥、令牌等。
凭证用于身份验证,以确保用户能够访问其被授权的资源。 -
服务(Service):
服务是 OpenStack 中的组件,如计算服务(Nova)、对象存储服务(Swift)、镜像服务(Glance)等。
每个服务都在 Keystone 中注册,并与一个或多个端点关联。 -
端点(Endpoint):
端点是服务的网络访问点,定义了服务 API 的访问 URL。
每个服务可以有多个端点,通常包括公共端点(用于外部访问)、内部端点(用于内部通信)和管理端点(用于管理操作)。 -
令牌(Token):
令牌是用户成功认证后获得的一种临时的认证凭证。
令牌在用户访问 OpenStack 服务时用于认证和授权。 -
策略(Policy):
策略定义了用户或角色在租户中的权限,通常以 JSON 文件的形式存在。
策略规则用于控制用户对 OpenStack 资源的访问。 -
身份提供者(Identity Provider, IdP):
身份提供者是外部的身份认证系统,如 LDAP、Active Directory 或 OpenID Connect。
Keystone 可以集成身份提供者,允许外部用户通过其已有的认证系统进行认证。
-
通俗易懂的来说;
在 某某公司,Alice 和 Bob 是 OpenStack 用户,分别参与“开发项目”和“测试项目”这两个租户。Alice 作为开发项目的管理员拥有管理虚拟机等资源的权限(角色),而 Bob 作为普通用户权限较低。这些用户和项目属于“总部”域,凭借用户名和密码(凭证)登录系统后,他们获得临时令牌以访问计算(Nova)等服务的端点。公司使用 LDAP 作为身份提供者(IdP)来统一管理登录信息,策略文件则定义了不同角色的具体权限。所有这些身份和访问管理都由 Keystone 负责。
在 OpenStack 中,用户(User)、角色(Role)、项目(Project)、域(Domain)之间有特定的包含和关联关系。以下是它们之间的关系:
-
域(Domain):
域是最顶层的容器,用于管理用户和项目的命名空间和隔离。
一个域可以包含多个用户和多个项目。 -
用户(User):
用户是能够通过 Keystone 进行认证的实体。
用户属于一个域,并且可以被分配到多个项目中。 -
项目(Project):
项目(也称为租户)是一个逻辑上的组,用于隔离资源(如虚拟机、存储、网络等)。
一个项目属于一个域。
一个项目可以包含多个用户,用户在项目中执行具体操作。 -
角色(Role):
角色是权限的集合,定义用户在项目中的操作权限。
角色不直接属于用户或项目,而是通过将角色分配给用户在特定项目中来实现授权。
简化的层次关系如下: -
域(Domain)
包含多个 用户(User)
包含多个 项目(Project)
每个项目包含多个 用户(User)
每个用户在项目中有特定的 角色(Role)
身份服务会为用户分配一个项目和一个角色。例如可以在项目中compute-user为用户分配角色 :
openstack role add --project acme --user alice compute-user
一个用户可以在不同项目中拥有不同的角色。例如,Alice 可能admin在项目中也拥有该角色Cyberdyne。一个用户还可以在同一个项目中拥有多个角色。policy.yaml文件控制用户可以针对给定服务执行的任务。例如,该 /etc/nova/policy.yaml文件指定 Compute 服务的访问策略,该/etc/glance/policy.yaml文件指定 Image 服务的访问策略,
该 /etc/keystone/policy.yaml文件指定 Identity 服务的访问策略。policy.yamlCompute、Identity 和 Image 服务中的默认文件仅识别admin角色。项目中具有任何角色的任何用户都可以访问不需要角色的所有操作 admin。(默认策略配置文件中主要识别和限制的是 admin 角色,确保只有管理员能执行关键操作。而对于那些没有特定角色限制的操作,任何在项目中拥有某个角色的用户都可以执行。这种设计允许更广泛的用户访问基本功能,同时确保关键管理操作的安全性。)
假设在 policy.yaml 中有以下策略定义:
"identity:create_user": "rule:admin_required"
"identity:list_projects": ""
identity:create_user:这项操作需要 admin 角色才能执行。
identity:list_projects:这项操作没有特别的角色要求,即任何被分配了某个角色的用户都可以执行。
为了限制用户执行计算服务等操作,必须在身份服务中创建一个角色,然后修改该/etc/nova/policy.yaml文件,以便计算操作需要该角色。
需要注意的是,openstack最新的C版中policy.yaml默认不存在,需要手动创建,官网keystone策略文件
- 服务管理
身份服务提供身份、令牌、目录和策略服务。它包括:
keystone Web 服务器网关接口 (WSGI) 服务
可以在支持 WSGI 的 Web 服务器(如 Apache httpd)中运行,以提供身份服务。服务和管理 API 作为 WSGI 服务的单独实例运行。
身份服务功能
每个服务都有一个可插入的后端,允许以不同的方式使用特定服务。大多数服务都支持 LDAP 或 SQL 等标准后端。
Identity 服务还维护着与每个服务对应的用户,比如,nova为 Compute 服务命名的用户,以及名为 的特殊服务项目service。
- 群组
组是域中的用户集合。管理员可以创建组并向其中添加用户。然后可以为组分配角色,而不是为单个用户分配角色。组是 Identity API v3 中引入的。
Identity API V3 提供以下与群组相关的操作:- 创建群组
删除群组
更新群组(更改其名称或描述)
将用户添加到组
从组中删除用户
列出群组成员
列出用户的组
将项目上的角色分配给组
将域中的角色分配给组
查询组的角色分配
- 创建群组
工作原理详细流程
(1)身份认证流程
身份认证的目的是验证用户身份并生成访问令牌,具体流程如下:
用户认证请求:
- 用户向 Keystone 发起身份认证请求,通常包含以下信息:
用户名或用户 ID。
密码或其他认证凭证。
项目 ID 或域 ID(可选,用于多租户场景)。
Keystone 验证身份:
Keystone 检查用户凭证的有效性。
- 验证方式可以是:
内置数据库:检查用户信息是否与 Keystone 数据库匹配。
外部认证系统:如 LDAP、SAML、OAuth。
生成令牌:
验证通过后,Keystone 返回一个访问令牌。
- 令牌中包含:
用户身份信息(用户名、用户 ID)。
角色信息(用户的权限)。
项目信息(用户所属租户)。
令牌有效期。
返回认证响应:
用户收到令牌后,可以使用它访问 OpenStack 的其他服务。
(2)服务调用与授权控制
在完成身份认证后,用户通过 Keystone 的令牌访问其他服务:
- 用户请求服务:
用户向特定服务(如 Nova)发起请求,并附带 Keystone 返回的令牌。
- 服务验证令牌:
服务接收到请求后,将令牌发送给 Keystone,验证其有效性。
Keystone 检查令牌是否:
已过期。
属于合法用户。
包含访问该服务的权限。
授权检查:
服务检查令牌中的角色和权限信息。
如果用户权限符合服务的访问控制策略,则允许操作。
服务响应:
服务完成操作后,返回结果给用户。
(3)服务目录管理
服务目录允许用户动态发现 OpenStack 服务的端点信息:
服务注册:
-
在 OpenStack 部署过程中,各服务(如 Nova、Cinder)会在 Keystone 中注册。
Keystone 为每个服务生成一个唯一 ID,并记录服务的端点地址(如 Public、Internal、Admin)。
用户请求服务目录: -
用户通过令牌向 Keystone 请求服务目录。
Keystone 根据用户的角色和项目返回可用的服务列表。
服务目录结构:
- 服务目录以 JSON 格式返回,包括:
服务名称(如 Compute)。
端点地址(如 Public API 地址)。
区域信息(Region,用于多区域部署)。
(4)令牌管理
令牌是 Keystone 工作的核心,它用来验证用户身份并授权服务访问。以下是令牌的管理流程:
-
令牌类型:
UUID 令牌:简单易用,长度较短,但依赖后端数据库存储。
PKI/PKIZ 令牌:包含加密签名,安全性更高,但体积较大。
OAuth 令牌:适合第三方认证集成。 -
令牌验证:
服务通过 Keystone 验证令牌的有效性。
Keystone 会检查令牌是否:
仍在有效期内。
符合当前请求的服务权限。 -
令牌的失效与刷新:
令牌通常有固定的生命周期(如 1 小时)。
到期后,用户需重新认证获取新令牌。
Keystone使用
环境:Ubuntu2404server,Keystone客户端版本25.0.0
用户向 Keystone 发起身份认证请求时,通常包含以下信息:
用户名或用户 ID。
密码或其他认证凭证。
项目 ID 或域 ID(可选,用于多租户场景)。
root@controller:~# openstack user list
Missing value auth-url required for auth plugin password
通过加载配置好的认证参数进行授权
root@controller:~# source /etc/keystone/admin-openrc.sh
root@controller:~# cat /etc/keystone/admin-openrc.sh
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=000000
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2
此时检查用户信息是否与 Keystone 数据库匹配,验证通过后,Keystone 返回一个访问令牌。
令牌中包含:
用户身份信息(用户名、用户 ID)。
角色信息(用户的权限)。
项目信息(用户所属租户)。
令牌有效期。
返回认证响应:
用户收到令牌后,可以使用它访问 OpenStack 的其他服务。
root@controller:~# openstack user list
+----------------------------------+-----------+
| ID | Name |
+----------------------------------+-----------+
| 9d36572a16054f5086ab505ac840cdfe | admin |
| 30dbf02c17624981b902669f7767aefd | glance |
| 66d556c5d8f54caca664e6169996a915 | placement |
| dfb7c9d483fc49ca85858f8d277fa209 | nova |
| ddff224653014471af1cba0a6f2eea6e | neutron |
+----------------------------------+-----------+
OpenStack 支持三种接口类型,每种类型适用于不同的访问场景:
- Public(公共接口):
对外部用户和服务开放。
例如,云平台的用户使用浏览器或 CLI 客户端访问服务时,通过公共端点。 - Internal(内部接口):
用于 OpenStack 服务之间的内部通信。
例如,Nova 与 Keystone 的身份验证通常使用内部端点。 - Admin(管理员接口):
提供管理员权限的操作接口。
例如,创建或删除用户等敏感操作通常通过管理员端点。
root@controller:~# openstack endpoint list
+--------------------------+-----------+--------------+--------------+---------+-----------+---------------------------+
| ID | Region | Service Name | Service Type | Enabled | Interface | URL |
+--------------------------+-----------+--------------+--------------+---------+-----------+---------------------------+
| 0046730dce4644f2b5bed611 | RegionOne | neutron | network | True | admin | http://controller:9696 |
| 4eedf5f3 | | | | | | |
| 0277cb223e964d3cba8d1046 | RegionOne | glance | image | True | public | http://controller:9292 |
| c5bcccdf | | | | | | |
| 411193c0313b431585330521 | RegionOne | neutron | network | True | internal | http://controller:9696 |
| 5c1aa1d9 | | | | | | |
| 5059265225d4409a868632f7 | RegionOne | nova | compute | True | internal | http://controller:8774/v2 |
| 5c408e8b | | | | | | .1 |
| 5529bb8e44624472a527e227 | RegionOne | glance | image | True | internal | http://controller:9292 |
| 5c05ae87 | | | | | | |
| 5b640c4b217a4c7b97b70515 | RegionOne | placement | placement | True | public | http://controller:8778 |
| 3b4e2d82 | | | | | | |
| 62bde9d889324473a1645937 | RegionOne | nova | compute | True | admin | http://controller:8774/v2 |
| f1c139e5 | | | | | | .1 |
| 7454ab45b5384a7b9d96f580 | RegionOne | keystone | identity | True | internal | http://controller:5000/v3 |
| a1fe3cb5 | | | | | | / |
| 9f02b231430c43db95f71b6a | RegionOne | keystone | identity | True | admin | http://controller:5000/v3 |
| dd2c4a41 | | | | | | / |
| aa830252877b425b91f4f0e4 | RegionOne | glance | image | True | admin | http://controller:9292 |
| 4dba5229 | | | | | | |
| d1484cbc7cd7423caeb37b49 | RegionOne | nova | compute | True | public | http://controller:8774/v2 |
| 9cd9322d | | | | | | .1 |
| da41cf2944b849faad23db0f | RegionOne | placement | placement | True | admin | http://controller:8778 |
| 6e3dc5d6 | | | | | | |
| e9edddb6f6614bab822eccb4 | RegionOne | placement | placement | True | internal | http://controller:8778 |
| 9b672f34 | | | | | | |
| f7a2ebff545b453f97a69f2a | RegionOne | keystone | identity | True | public | http://controller:5000/v3 |
| dbc63564 | | | | | | / |
| f872fec69c584e50b3b985dd | RegionOne | neutron | network | True | public | http://controller:9696 |
| 0aeae739 | | | | | | |
+--------------------------+-----------+--------------+--------------+---------+-----------+---------------------------+
使用 openstack token issue 命令可以直接获取当前用户的认证令牌
root@controller:~# openstack token issue
+------------+-----------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+-----------------------------------------------------------------------------------------------------------------+
| expires | 2024-12-03T07:36:17+0000 |
| id | gAAAAABnTqbhYf2YhY2tzbP4YLVhMx-7Vqgkbse0QmS8arhWL1DlVOMUMN_HWFBs- |
| | RqK9uf7X0IkzUd5dpvZqsdK0uJoUhTweTa9eym16ifH6N6a-IxRETa4OJS6EMZLmDPNjmPHGrmvHnXOV- |
| | WTMY5KQ8VW4U-KeZi1ht3yENbsMsA0lEJl-QY |
| project_id | e85a7093d85344378bb1b016fc6a1b1b |
| user_id | 9d36572a16054f5086ab505ac840cdfe |
+------------+-----------------------------------------------------------------------------------------------------------------+
- id:这是生成的令牌。OpenStack 支持多种类型的令牌(如 UUID、PKI)。默认通常使用 UUID。
- expires:令牌的过期时间。到期后需要重新认证获取新令牌,
- project_id 和 user_id:关联的项目和用户
在 OpenStack 中,应用程序凭证(Application Credential) 是一种授权机制,用于允许外部应用程序以安全和受控的方式访问 OpenStack 服务。它为应用程序提供了一种替代用户令牌的方式,可以用于调用 OpenStack API,而无需直接使用用户的凭证。
(1)为外部应用程序提供安全访问
当外部应用程序需要访问 OpenStack 服务时,使用应用程序凭证而不是用户的密码。
这样可以避免直接暴露用户凭证,提高安全性。
(2)提供权限最小化控制
应用程序凭证可以限制访问的资源范围和权限(Scope),确保应用程序只能执行被授权的操作。
例如,某个凭证可能仅允许访问特定项目中的镜像服务,而不能修改其他资源。
(3)支持长期凭证
可以为应用程序凭证设置较长的有效期,而用户令牌通常有较短的生命周期(如 1 小时)。
适合需要长期访问的应用场景。
(4)独立于用户认证
即使用户的密码发生更改或重置,应用程序凭证仍然有效(除非被显式撤销)。
这种独立性可以减少用户密码变更对应用程序的影响。
yaml文件内容如下:
# This is a clouds.yaml file, which can be used by OpenStack tools as a source
# of configuration on how to connect to a cloud. If this is your only cloud,
# just put this file in ~/.config/openstack/clouds.yaml and tools like
# python-openstackclient will just work with no further config. (You will need
# to add your password to the auth section)
# If you have more than one cloud account, add the cloud entry to the clouds
# section of your existing file and you can refer to them by name with
# OS_CLOUD=openstack or --os-cloud=openstack
clouds:
openstack:
auth:
auth_url: http://controller:5000/v3/
application_credential_id: "44cf4b5adba14d04979a8ba283dd4845"
application_credential_secret: "000000"
region_name: "RegionOne"
interface: "public"
identity_api_version: 3
auth_type: "v3applicationcredential"
keystone配置
OpenStack Identity 支持位于可配置子系统(例如 token)之上的缓存层。这能够灵活地为所有或部分子系统设置缓存。OpenStack Identity 使用oslo.cache库,该库允许灵活的缓存后端。大多数缓存配置选项都在文件[cache]的 部分中设置/etc/keystone/keystone.conf。 必须将 部分enabled的选项[cache]设置为True,以便任何子系统都可以缓存响应。每个具有缓存功能的部分都将有一个caching布尔值,用于切换该特定子系统的缓存行为。
因此,要仅启用令牌后端缓存,请按如下方式设置值:
[cache]
enabled=true
[catalog]
caching=false
[domain_config]
caching=false
[federation]
caching=false
[resource]
caching=false
[revoke]
caching=false
[role]
caching=false
[token]
caching=true
每个子系统都默认配置为缓存。但是,缓存的全局切换默认为False。只有启用了全局切换,子系统才能够缓存响应。
- 配置 Memcached 后端示例
[cache]
enabled = true
backend = dogpile.cache.memcached
backend_argument = url:127.0.0.1:11211
- 详细缓存日志
我们不建议在生产系统中默认使用详细缓存日志记录,因为它非常嘈杂。但是,您可能需要调试缓存问题。查看 keystone 如何与缓存后端交互的一种方法是增强日志记录。以下配置将以更高的详细程度将 oslo 和 dogpile 日志聚合到 keystone 的日志文件中:
[DEFAULT]
default_log_levels = oslo.cache=DEBUG,dogpile.core.dogpile=DEBUG
[cache]
debug_cache_backend = True
- 设置账户锁定阈值
帐户锁定功能可限制密码尝试失败的次数。如果用户在最大尝试次数后仍无法通过身份验证,服务将禁用该用户。可以通过使用 update user v3 API 调用明确设置 enable user 属性来重新启用用户。
可以通过设置以下内容来设置身份验证尝试失败的最大次数lockout_failure_attempts:
[security_compliance]
lockout_failure_attempts = 6
可以通过设置秒数来设置用户被锁定的分钟数lockout_duration:如果未设置lockout_duration,用户将被无限期锁定,直到通过 API 明确启用用户。
[security_compliance]
lockout_duration = 1800
- 禁用不活跃用户
PCI-DSS 8.1.4 要求在 90 天内删除或禁用不活跃的用户帐户。可以通过设置以下内容来实现此目的 disable_user_account_days_inactive:
[security_compliance]
disable_user_account_days_inactive = 90
- 强制用户在首次使用时更改密码
PCI-DSS 8.2.6 要求用户在首次使用和管理密码重置时更改密码。在身份用户 API中, 创建用户和更新用户被视为管理密码更改。而更改用户密码则属于自助密码更改。启用此功能后,新用户和已重置密码的用户将需要在下次身份验证(首次使用)时更改密码,然后才能访问任何服务。
在启用此功能之前,可能希望豁免某些您不希望被要求更改密码的用户。可以通过设置用户选项属性 ignore_change_password_upon_first_use将用户标记为豁免。
[security_compliance]
change_password_upon_first_use = True
- 配置密码过期
可以通过设置以下内容将密码配置为在一定天数内过期password_expires_days:
[security_compliance]
password_expires_days = 90
一旦设置,任何新的密码更改都会有一个到期日期,该日期/时间基于密码更改的日期/时间加上此处定义的天数。现有密码不会受到影响。如果您希望现有密码具有到期日期,则需要针对数据库中的密码表运行 SQL 脚本以更新 expires_at 列。
如果存在一个你不希望其密码过期的用户,keystone 支持通过用户选项ignore_password_expiry进行设置。
- 配置密码强度要求
可以通过在设置中添加正则表达式来设置密码强度要求,例如要求密码中包含数字或设置最小密码长度password_regex:
[security_compliance]
password_regex = ^(?=.*\d)(?=.*[a-zA-Z]).{7,}$
上面的例子是一个正则表达式,要求密码必须具备:
一 (1) 个字母
一 (1) 位数字
最小长度为七 (7) 个字符
如果确实设置了password_regex,则应提供描述密码强度要求的文本。可以通过设置 来执行此操作 password_regex_description:
[security_compliance]
password_regex_description = Passwords must contain at least 1 letter, 1
digit, and be a minimum length of 7
characters.
必须与password_regex_description实际正则表达式匹配。如果password_regex与password_regex_description不匹配,则会导致用户体验不佳,因为此描述将返回给用户,以解释为什么他们请求的密码不够充分。