一直以来想看看LDAP在keystone中如何应用的,最近终于静下心来好好的看了一下,keystone曾经有许多backends,SQL,memcache, LDAP, KVS等,随着版本的演进,现在的版本主要只支持SQL,与LDAP后端,而且LDAP与只是保留在Identity这一个组件中,且只支持读而不再支持写操作。但是LDAP在企业用的这么广泛,有必要来研究研究keystone是如何LDAP这个后端的。
这里只是记录一些基本的配置,只是用于实验与记录,不适用于实际的生产环境。Keystone中Identity组件主要的概念包括用户与组,将LDAP用于Keystone的Identity的backend,就是将这些用户与组的信息存放在LDAP server中而不是存放在Keystone server中。所以首先我们要做的是,搭建一个LDAP server的环境,而后利用LDAP支持的语法创建一个用户(组),修改Keystone的配置,基于此,我们期望Keystone能使用这些用户组信息,继而我们可以创建成功一个project scoped的token,用此令牌来访问Keystone或者云中的资源。
搭建LDAP server,Ubuntu上一个命令就搞定:
sudo apt install slapd ldap-utils
dn: ou=Users,dc=intel,dc=com objectClass: organizationalUnit ou: Users dn: ou=UserGroups,dc=intel,dc=com objectClass: organizationalUnit ou: UserGroups dn: cn=tester,ou=UserGroups,dc=intel,dc=com objectClass: posixGroup cn: tester gidNumber: 5002 dn: uid=john,ou=Users,dc=intel,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: john sn: Sve givenName: John cn: John Sve displayName: John Sve uidNumber: 10002 gidNumber: 5002 userPassword: johnldap gecos: John Doe loginShell: /bin/bash homeDirectory: /home/john dn: uid=dave,ou=Users,dc=intel,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: davechen sn: Dave givenName: Wei cn: davechen displayName: Dave Chen uidNumber: 10003 gidNumber: 5002 userPassword: abc123 gecos: Dave Chen loginShell: /bin/bash homeDirectory: /home/dave
这里我们定义一个用户组tester,两个用户john与davechen,注意这里的cn=admin,dc=intel,dc=com为root DN, abc123为安装LDAP server时用的密码:
ldapadd -H ldap:/// -x -D "cn=admin,dc=intel,dc=com" -f addentry.ldif -w abc123
如果你对ldap操作命令不是很熟练的话,建议安装一个图形化工具,网络上可以找到很多种选择,在Ubuntu上我最终能用起来的也就是jxplorer,安装jxplorer也很简单,命令如下:
sudo apt-get install jxplorer
打开图形化界面,IP地址可以直接写localhost,连接端口为389,可以用默认的协议ldap v3,连接用户名密码就是root DN与上面提到的创建时设置的密码,成功登陆后就可以看到刚创建好的用户与组信息。
接下来就是配置Keystone了,配置keystone分两部分,设置identity的backend从默认的SQL改为LDAP,个性化配置LDAP参数。
#/etc/keystone/keystone.conf
[identity] driver = ldap # driver = sql # # From keystone #
[ldap] # # From keystone # # URL(s) for connecting to the LDAP server. Multiple LDAP URLs may be specified # as a comma separated string. The first URL to successfully bind is used for # the connection. (string value) url = ldap://localhost # url = ldap:/// # The user name of the administrator bind DN to use when querying the LDAP # server, if your LDAP server requires it. (string value) user = cn=admin,dc=intel,dc=com # The password of the administrator bind DN to use when querying the LDAP # server, if your LDAP server requires it. (string value) password = abc123 # The default LDAP server suffix to use, if a DN is not defined via either # `[ldap] user_tree_dn` or `[ldap] group_tree_dn`. (string value) suffix = cn=intel,cn=com # The search base to use for users. Defaults to the `[ldap] suffix` value. # (string value) user_tree_dn = ou=Users,dc=intel,dc=com #user_tree_dn = <None> # The LDAP object class to use for users. (string value) #user_objectclass = inetOrgPerson user_objectclass = inetOrgPerson # The search base to use for groups. Defaults to the `[ldap] suffix` value. # (string value) #group_tree_dn = <None> group_tree_dn = ou=UserGroups,dc=intel,dc=com # The LDAP object class to use for groups. If setting this option to # `posixGroup`, you may also be interested in enabling the `[ldap] # group_members_are_ids` option. (string value) #group_objectclass = groupOfNames group_objectclass = posixGroup # Enable this option if the members of the group object class are keystone user # IDs rather than LDAP DNs. This is the case when using `posixGroup` as the # group object class in Open Directory. (boolean value) #group_members_are_ids = false group_members_are_ids = true ...
Keystone支持ldap的参数有很多种,我们只修改(打开)了核心的几个配置参数,各个参数代表什么意思,注释已经说明的很详细,看一下应该就大致知道是干什么用的,几个参数重点说明一下,user为*root DN*而非admin,password为搭建ldap server时创建的密码,Keystone需要他们去连接访问LDAP server以获取数据。user_tree_dn与group_tree_dn与LDAP中用户的目录地址是一致的, 如果不一致,即便你创建了用户组,Keystone也查找不到。
重启Keystone server,我们来看看Keystone能否读出我们创建的用户。
curl -g -i -X GET http://10.239.159.68:35357/v3/users -H "Accept: application/json" -H "X-Auth-Token: hideme"HTTP/1.1 200 OK Date: Sun, 16 Oct 2016 10:22:57 GMT Server: Apache/2.4.7 (Ubuntu) Vary: X-Auth-Token x-openstack-request-id: req-28c9a656-44df-47f2-b20b-35c140d38ba3 Content-Length: 262 Content-Type: application/json Via: 1.1 shzintpr02.sh.intel.com Proxy-Connection: Keep-Alive Connection: Keep-Alive {"users": [{"domain_id": "default", "links": {"self": "http://10.239.159.68/identity/v3/users/John Sve"}, "password_expires_at": null, "name": "Sve", "id": "John Sve"}, {"domain_id": "default", "links": {"self": "http://10.239.159.68/identity/v3/users/davechen"}, "password_expires_at": null, "name": "Dave", "id": "davechen"}], "links": {"self": "http://10.239.159.68/identity/v3/users", "previous": null, "next": null}} { "users": [{ "domain_id": "default", "links": { "self": "http://10.239.159.68/identity/v3/users/John Sve" }, "password_expires_at": null, "name": "Sve", "id": "John Sve" }, { "domain_id": "default", "links": { "self": "http://10.239.159.68/identity/v3/users/davechen" }, "password_expires_at": null, "name": "Dave", "id": "davechen" }], "links": { "self": "http://10.239.159.68/identity/v3/users", "previous": null, "next": null } }
$ openstack user list +----------+------+ | ID | Name | +----------+------+ | John Sve | Sve | | davechen | Dave | +----------+------+
Nice!
注意这里需要用到admin token,因为你尚未对这些ldap user授权,没有类似的admin用户,不使用admin token你是无法访问keystone的。好了,有了这些信息我们来定义一个LDAP的admin吧。
授权("hideme"为admin token,davechen为用户ID):
curl -g -i -X PUT http://10.239.159.68:35357/v3/projects/caaa06cf868e44c2882623afd34eea60/users/davechen/roles/9cf8420ea5324f79b9d740e3ce5f0e04 -H "Accept: application/json" -H "X-Auth-Token: hideme"
一切就绪,我们来创建一个project scoped token,
$ curl -i \ -H "Content-Type: application/json" \ -d ' { "auth": { "identity": { "domain": { "id": "default" }, "methods": ["password"], "password": { "user": { "name": "Dave", "domain": { "id": "default" }, "password": "abc123" } } }, "scope": { "project": { "name": "admin", "domain": { "id": "default" } } } } }' \ http://10.239.159.68:5000/v3/auth/tokens HTTP/1.1 201 Created Date: Fri, 21 Oct 2016 06:00:29 GMT Server: Apache/2.4.7 (Ubuntu) X-Subject-Token: 7cc4ea015dbf4bc48b4a6141f618e8d4 Vary: X-Auth-Token x-openstack-request-id: req-bd98058d-cbf6-4bd8-84af-6b964dcfdadc Content-Length: 5407 Content-Type: application/json Via: 1.1 shzintpr02.sh.intel.com Proxy-Connection: Keep-Alive Connection: Keep-Alive …….
好了,所有的准备工作就绪,我们创建了LDAP用户,并给用户davechen授权为admin,通过该用户我们创建了一个project scoped token,有了这个token我们就可以任意操作Keystone继而操作整个云了!
创建一个keystone trust!
$ curl -g -i -X POST -H "Accept: application/json" -H "X-Auth-Token: 7cc4ea015dbf4bc48b4a6141f618e8d4" -H "Content-Type: application/json" -d '{ "trust": { "expires_at": "2017-02-27T18:30:59.999999Z", "impersonation": true, "allow_redelegation": true, "project_id": "caaa06cf868e44c2882623afd34eea60", "roles": [ { "name": "admin" } ], "trustee_user_id": "John Sve", "trustor_user_id": "davechen", "redelegation_count": 3 } }' http://10.239.159.68:5000/v3/OS-TRUST/trusts
$ openstack trust list +----------------------------------+-----------------------------+---------------+----------------------------------+-----------------+-----------------+ | ID | Expires At | Impersonation | Project ID | Trustee User ID | Trustor User ID | +----------------------------------+-----------------------------+---------------+----------------------------------+-----------------+-----------------+ | 4cd8a7d12a05461980c887c91b63c773 | 2017-02-27T18:30:59.000000Z | True | caaa06cf868e44c2882623afd34eea60 | John Sve | davechen | +----------------------------------+-----------------------------+---------------+----------------------------------+-----------------+-----------------+
大功告成!
参考资料:
【1】 http://www.zytrax.com/books/ldap/ 学习ldap很好的资料
【2】 https://help.ubuntu.com/lts/serverguide/openldap-server.html 如何搭建LDAP server
【3】http://docs.openstack.org/admin-guide/keystone-integrate-identity-backend-ldap.html 集成LDAP backend官方文档