问题导读 1.Keystone服务主要提供哪两个功能? 2.Keystone的主要服务进程有哪些? 3.LDAP服务与keystone整合的前提是什么?
在我们阅读之前,需要明白什么是LDAP LDAP简介
LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务。目录服务是一种特殊的数据库系统,其专门针对读取,浏览和搜索操作进行了特定的优化。目录一般用来包含描述性的,基于属性的信息并支持精细复杂的过滤能力。目录一般不支持通用数据库针对大量更新操作操作需要的复杂的事务管理或回卷策略。而目录服务的更新则一般都非常简单。这种目录可以存储包括个人信息、web链结、jpeg图像等各种信息。为了访问存储在目录中的信息,就需要使用运行在TCP/IP 之上的访问协议—LDAP。 LDAP目录中的信息是是按照树型结构组织,具体信息存储在条目(entry)的数据结构中。条目相当于关系数据库中表的记录;条目是具有区别名DN (Distinguished Name)的属性(Attribute),DN是用来引用条目的,DN相当于关系数据库表中的关键字(Primary Key)。属性由类型(Type)和一个或多个值(Values)组成,相当于关系数据库中的字段(Field)由字段名和数据类型组成,只是为了方便检索的需要,LDAP中的Type可以有多个Value,而不是关系数据库中为降低数据的冗余性要求实现的各个域必须是不相关的。LDAP中条目的组织一般按照地理位置和组织关系进行组织,非常的直观。LDAP把数据存放在文件中,为提高效率可以使用基于索引的文件数据库,而不是关系数据库。类型的一个例子就是mail,其值将是一个电子邮件地址。 LDAP的信息是以树型结构存储的,在树根一般定义国家(c=CN)或域名(dc=com),在其下则往往定义一个或多个组织 (organization)(o=Acme)或组织单元(organizational units) (ou=People)。一个组织单元可能包含诸如所有雇员、大楼内的所有打印机等信息。此外,LDAP支持对条目能够和必须支持哪些属性进行控制,这是有一个特殊的称为对象类别(objectClass)的属性来实现的。该属性的值决定了该条目必须遵循的一些规则,其规定了该条目能够及至少应该包含哪些属性。例如:inetorgPerson对象类需要支持sn(surname)和cn(common name)属性,但也可以包含可选的如邮件,电话号码等属性。
OpenStack Keystone与只读LDAP集成实践 云计算已经成为炙手可热的话题,越来越多的企业已经开始了数据中心云计算化的实施规划。随着OpenStack的崛起以及迅速走红,很多企业已经将OpenStack作为自身私有云建设的首选。但是在企业内部部署OpenStack的过程中,跟企业内部现有服务进行整合的过程中也出现各种必须面对的问题。 例如企业内部统一身份验证的问题。企业内部已有成熟的LDAP服务,如何与OpenStack的验证服务进行整合,以实现统一身份验证便是一个较为普遍的问题。OpenStack现在的Grizzly版本对LDAP验证机制已经有非常好的支持。但是却对LDAP服务有较为严苛的要求,例如需要拥有写权限,需要按照Keystone的需求建立LDAP中的组织结构及角色定义。 但是,通常成熟的LDAP服务组织结构及角色定义都已经成型不宜进行改变,并且通常只会开放只读权限,以提供身份验证服务。因此,OpenStack中对LDAP的支持并不适合那些已经拥有成熟LDAP服务的企业及组织。 本文主要向读者介绍利用OpenStack现有对SQL及LDAP验证的支持,自定义一个通过只读LDAP进行验证的混合验证后端,使OpenStack可以通过顺利通过企业内部已有的只读LDAP服务进行统一身份验证。 1) Keystone简介 Keystone是OpenStack的一个核心项目,其作用是为OpenStack其他各个组件提供统一的身份验证服务,例如nova、glance、cinder等。 Keystone的主要功能 Keystone服务主要提供两个功能: •用户管理:记录用户信息及用户权限信息 Keystone主要通过users(用户帐号),tenants(租户),roles(权限)来进行用户管理。 而用户具体可以访问的资源,可以通过policy.json进行限制及调整。 •服务目录:提供可用可用服务的目录以及可用服务的API服务接入点。 Keystone通过services(服务),endpoints(接入点)来提供服务目录的管理。 Keystone的主要概念 在OpenStack Keystone中,主要存在以下几个重要概念: •User:用户。 在keystone中,user是指使用OpenStack云服务的人、系统、或者服务的帐号。 •Credentials:数字凭证。 是指有用户拥有并且由用户生成的数据。例如,匹配的用户名和密码。 •Authentication:验证。 在keystone环境中,验证是指确认用户的身份或者某服务声明的真实性的行为。 在keystone服务中,keystone会首先通过数字凭证(Credential,即keystone里面所存储的用户名和密码)来进行初始验证。验证通过后,keystone服务会给用户分配一个令牌(Token)。用户即可通过该令牌进行权限范围内的后续操作。 •Token:令牌。 在keystone中,是指用来访问资源的一组随机文字。每个令牌都会描述其所能访问的资源范围。 Tenant:租户。 在keystone中,租户是用来分组或隔离资源和被管理对象的容器。该租户可以是一个组织、项目、或者一个客户。 •Service:服务。 是指一个OpenStack服务,例如计算服务(nova)、对象存储服务(swift)或者镜像服务(Glance)。 一个服务会提供一个或多个接入点,使用户可以用来访问资源以及执行相应的操作。
•Endpoint:接入点。 是一个通过网络进行访问的地址,例如访问服务的URL。 •Role:角色。 角色包含一套访问权限和授权。例如管理员权限admin和普通用户组权限member。 下图是一个用户验证过程的流程示例。
▲图1:用户验证流程示例
Keystone的主要服务进程 Keystone有一组内部服务组成。这些服务包含: •Identity 该服务主要提供对身份信息的验证包含用户、租户和角色,以及相关联的元数据。 •Token 该服务验证并且管理所有的令牌信息。 •Catalog 该服务提供对所有服务接入点的注册管理。 •Policy 该服务提供了一个基于角色的授权管理系统及规则管理接口。 Keystone主要验证后端简介 Gizzly版本中的keystone功能已经非常丰富,提供了多种验证后端以期适应不同的环境需求。所有的后端都可在keystone.conf文件中进行定义。 SQL验证后端简介 基于SQL的验证后端是通过使用SQLAlchemy进行数据的持久存储。所有的用户帐号、租户以及角色等信息都会被存储在SQL数据库中。例如MySQL,DB2。 LDAP后端简介 LDAP后端经用户和租户分别存储在单独的子树种。而角色则作为租户的一条记录进行存储。 其他验证后端 PAM验证后端,是利用当前操作系统的用户管理体系进行帐号验证,提供用户和租户间一对一的关系信息,并且root帐号享用admin的权限。 其他验证后端与本文表达内容无关,故不在此进行描述。 2) Keystone对LDAP的支持 在上节keystone的简介中,我们已经提到,目前keystone已经有对LDAP的支持,并且已经有一个成熟稳定的验证后端可以在实际环境中使用。 现有LDAP后端对LDAP服务的需求 如果Keystone利用现有的LDAP后端进行账户验证时,LDAP服务需要满足keystone的一些较为严苛的需求,主要几点如下: •用户和租户分别在不同的子树中存储 •角色必须作为用户及租户的一个属性记录在相应的子树中 •拥有LDAP服务的写权限,并且提前写入各个服务帐号(nova、glance、cinder、neutron、ceilometer等组件)以及各组件所在的服务租户(即service租户)。 已有LDAP服务与keystone整合的需求 对于目前已经拥有成熟LDAP服务的企业及组织,目前keystone对LDAP的需求过于严苛。对于已有LDAP服务的企业组织,LDAP服务通常已经担负起整个企业组织内部的统一身份验证服务,所以很难为满足keystone的需求进行大规模结构调整。因此对于这些组织来说,其目标要求,通常仅是需要通过已有LDAP验证,减少组织内部用户的系统验证数量及复杂程度,并且要保持各个服务之间的独立性。 因此,这类需求的可简要概括如下: •保持OpenStack服务的独立性,即OpenStack的系统服务帐号及某些特定管理员帐号不依赖于已有的LDAP服务 •使用只读权限与已有LDAP服务整合,只进行帐号验证
3) Keystone通过只读LDAP验证 根据上文中提及,企业组织对已有LDAP服务与keystone整合的需求来看,现有的LDAP后端不满足于企业的需求。因此,本文提出通过自定义验证后端的方式,来满足这类用户的实际需求。 自定义LDAP后端的功能需求 如前面所述,已有LDAP服务的企业组织,对Keystone的需求可以简化如下: •Keystone所有的系统服务账号及特定管理员帐号存储于OpenStack的本地MySQL数据库中,不依赖于现有LDAP服务。 •Keystone中所需要的用户角色及租户信息存储于OpenStack的本地MySQL数据库中,不依赖于现有LDAP。 •Keystone中所有常规的用户帐号验证通过现有的LDAP服务进行验证。 上述简化的需求既可以保证OpenStack系统各组件服务的独立性,也可以通过现有的LDAP服务进行常规用户的验证,实现企业内部统一的身份验证机制。 自定义LDAP后端的简单实现 依据上述简化的需求,keystone现有的SQL后端和LDAP后端均可满足部分需求。因此,我们只需基于现有的SQL和LDAP后端定制一个混合的验证后端即可。 具体实现的思路如下: •以现有的SQL验证后端为基础,列出OpenStack各系统服务帐号及特定管理员帐号的列表,在该服务帐号列表中的服务帐号通过SQL验证后端进行本地验证。 •在服务帐号列表以外的其他帐号,以现有LDAP后端为基础,仅利用现有LDAP后端中的密码验证部分,实现仅通过LDAP服务进行帐号的密码验证功能。 自定义LDAP后端的验证流程如下: 1) 用户登陆时,自定义后端会通过现有的SQL后端查询账号是否存在。如果不存在直接返回,如果存在继续2); 2) 如果账户存在,查询该账号是否属于系统服务账号。如果是系统账号继续a); a) 如果账号属于系统账号,则通过SQL后端进行密码验证。密码验证失败,则返回;密码验证成功,则继续4); b) 如果不是系统账号,而是普通用户账号,继续3); 3) 如果账号存在,并且是普通用户账号,则通过LDAP后端进行密码验证。如果密码验证失败,则返回;如果密码验证成功,则继续4) 4) 继续通过SQL后端进行其他验证步骤。 注意:建议保留一个系统管理员帐号,用以进行必要的初始化配置。本文中保留的系统管理员帐号为“admin”。
具体自定义LDAP后端的示例: Keystone的各个验证后端均是通过python语言实现,下面的具体的示例代码即是基于现有的SQL验证后端及LDAP后端,由python语言实现。具体示例代码,请参考如下清单一。
- # vim: tabstop=4 shiftwidth=4 softtabstop=4
-
- """CustomLDAP Identity backend for Keystone on top of the LDAP and SQL backends"""
-
- from keystone import config
-
- from keystone import exception
-
- from keystone.common import sql
-
- from keystone.common import utils
-
- from keystone import identity
-
- from keystone.identity.backends import ldap as ldap_backend
-
- from keystone.identity.backends import sql
-
- CONF = config.CONF
-
- class Identity(sql.Identity):
-
- def _check_password(self, password, user_ref):
-
- username = user_ref.get('name')
-
- if (username in ['admin', 'nova', 'glance', 'cinder', 'swift', 'quantum']):
-
- return super(Identity, self)._check_password(password, user_ref)
-
- return base_ldap.UserApi(CONF).get_connection(base_ldap.UserApi(CONF)._id_to_dn(username), password)
复制代码
清单一:自定义LDAP后端customLDAP.py 4) 测试及总结 配置自定义LDAP后端 创建自定义LDAP后端 将自定义LDAP后端customLDAP.py复制到/usr/lib/python2.6/site-packages/keystone/identity/backends 目录下。并注意修改该文件的属主及权限信息,保持与其他该目录下的文件保持一致。 可通过chown命令修改属主,通过chmod命令修改文件权限。 修改/etc/keystone/keystone.conf配置文件 修改验证后端为自定义LDAP后端customLDAP 。
- [identity]
-
- driver = keystone.identity.backends.bluepages.Identity
复制代码
代码清单二:在keystone.conf中配置自定义LDAP后端 配置LDAP后端: - [ldap]
-
- url = ldap://ldap.your.com
-
- user = ou=Users,dc=your,dc=com
-
- suffix = dc=your,dc=com
-
- query_scope = sub
-
- user_tree_dn = ou=Users,dc=your,dc=com
-
- user_objectclass = inetOrgPerson
-
- user_domain_id_attribute = businessCategory
-
- user_id_attribute = cn
-
- user_name_attribute = sn
-
- user_mail_attribute = email
-
- user_pass_attribute = userPassword
-
- user_allow_create = False
-
- user_allow_update = False
-
- user_allow_delete = False
-
- tenant_tree_dn = ou=Groups,dc=example,dc=com
-
- tenant_objectclass = groupOfNames
-
- tenant_domain_id_attribute = businessCategory
-
- tenant_id_attribute = cn
-
- tenant_name_attribute = ou
-
- tenant_domain_id_attribute = co
-
- tenant_id_attribute = dept
-
- tenant_name_attribute = dept
-
- tenant_allow_create = False
-
- tenant_allow_update = False
-
- tenant_allow_delete = False
复制代码
代码清单三:在keystone.conf中配置原LDAP后端 同步LDAP用户帐号 由于本示例自定义后端没有自定义user、tenant等的创建、修改、删除等方法,因此需要手工同步已有LDAP中的用户帐号。 同步帐号有多种方法,比如利用自定义后端中保留的本地admin帐号,可以通过keystone的Rest API利用脚本自动同步,或直接通过admin帐号手工创建。 测试及结果 本示例,目的仅是验证该自定义LDAP后端的可行性,因此仅通过admin帐号手工同步少数LDAP进行验证。 注意:密码处可随意填写,在自定义后端中,仅需要MySQL中有该用户存在,并且配置有相应的项目及角色,实际验证时则是通过LDAP验证。因此该处的密码无效。
▲图 2. 手工将LDAP帐号添加到Keystone 帐号创建成功以后,可以退出当前的admin帐号,测试以LDAP帐号登陆。 下图为成功登录后:
▲图 3. 以LDAP帐号成功登录 总结 通过上面的简单示例,我们可以验证自定义keystone验证后端的可行性,以此展现OpenStack的灵活性及或扩展性。当然,本文仅是一个简化的可行性验证,在实际企业组织中,根据组织自身的需求不同,可以自定义一个功能丰富并且完整的验证后端,以实现和满足企业内部自身的需求。 通过本文,仅希望能够以细微的需求来展现OpenStack作为一个云计算平台的开放性、灵活性以及易扩展性。以期能起到抛砖引玉的效果。 作者简介: 刘成龙 IT工程师 任职于某大型外资IT企业,参与企业私有云基础架构设计、私有云部署,具有丰富的IT基础架构、虚拟化及孕计算经验,熟悉主流的虚拟化技术,熟悉IBM的x86架构服务器、刀片服务器和磁盘存储产品。
|