当前位置 : 首页 » 博文聚焦 » 正文

Play with LDAP + Keystone (by quqi99)

分类 : 博文聚焦 | 发布时间 : 2018-06-08 18:10:40 | 浏览 : 31

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (作者:张华 发表于:2018-05-29)

Install OpenLDAP

OpenLDAP Server可以使用这个charm安装 - https://jujucharms.com/u/openstack-charmers/ldap-test-fixture/3, 最终要添加的yaml如下:

  keystone-ldap:
    charm: cs:keystone-ldap-10
  ldap-test-fixture:
    charm: cs:~openstack-charmers/ldap-test-fixture

  - [ keystone-ldap, keystone ]

也可以根据这个链接分步安装 - https://api.jujucharms.com/charmstore/v5/~openstack-charmers/ldap-test-fixture-3/archive/hooks/install

export DEBIAN_FRONTEND=noninteractive
echo -e " \ slapd slapd/internal/generated_adminpw password password slapd slapd/password2 password password slapd slapd/internal/adminpw password password slapd slapd/password1 password password " | sudo debconf-set-selections
sudo apt install slapd ldap-utils phpldapadmin
sed -i "s/dc=example/dc=test/g" /etc/phpldapadmin/config.php
service apache2 restart
sudo service slapd restart
#sudo dpkg-reconfigure slapd #configure domain=test.com
#slappasswd -h {SSHA} -s password
#sudo apt-get install jxplorer #GUI

# How to test it
sudo ldapsearch -h 10.5.0.72 -x -w password -D"cn=admin,dc=test,dc=com" -b dc=test,dc=com -s sub '(objectclass=*)' cn sn
sudo ldapsearch -h 10.5.0.72 -x -w password -D"cn=admin,dc=test,dc=com" -b ou=users,dc=test,dc=com  '(objectclass=*)'  cn sn
sudo ldapsearch -h 10.5.0.72 -x -w password -D"cn=admin,dc=test,dc=com" -b dc=test,dc=com

Modify default schema to support OpenStack

wget https://api.jujucharms.com/charmstore/v5/~openstack-charmers/ldap-test-fixture-3/archive/files/backup.ldif
slapadd -v -c -l .backup.ldif
$ sudo ldapsearch -h 10.5.0.72 -x -w password -D"cn=admin,dc=test,dc=com" -b dc=test,dc=com
# extended LDIF
#
# LDAPv3
# base <dc=test,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# test.com
dn: dc=test,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: test
dc: test

# admin, test.com
dn: cn=admin,dc=test,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9Q1RxNU1nNHA5blhlL25WVjBqenZSYTZ2VkxQQnVJZjc=

# groups, test.com
dn: ou=groups,dc=test,dc=com
objectClass: organizationalUnit
objectClass: top
ou: groups

# admin, groups, test.com
dn: cn=admin,ou=groups,dc=test,dc=com
cn: admin
gidNumber: 500
memberUid: johndoe
objectClass: posixGroup
objectClass: top

# openstack, groups, test.com
dn: cn=openstack,ou=groups,dc=test,dc=com
cn: openstack
gidNumber: 501
memberUid: johndoe
objectClass: posixGroup
objectClass: top

# users, test.com
dn: ou=users,dc=test,dc=com
objectClass: organizationalUnit
objectClass: top
ou: users

# janedoe, users, test.com
dn: cn=janedoe,ou=users,dc=test,dc=com
cn: janedoe
gidNumber: 500
givenName: Jane
homeDirectory: /home/users/janedoe
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: Jane Doe
uid: janedoe
uidNumber: 1001
userPassword:: e01ENX1IT01SNHBNMTV0M2dZZDhXVXhNRzhnPT0=

# johndoe, users, test.com
dn: cn=johndoe,ou=users,dc=test,dc=com
cn: johndoe
gidNumber: 501
givenName: John
homeDirectory: /home/users/jdoe
loginShell: /bin/sh
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: John Doe
uid: johndoe
uidNumber: 1000
userPassword:: e01ENX1IT01SNHBNMTV0M2dZZDhXVXhNRzhnPT0=

# search result
search: 2
result: 0 Success

# numResponses: 9
# numEntries: 8

Configure Keystone

juju config keystone preferred-api-version=3
juju deploy keystone-ldap --series xenial 
juju add-relation keystone-ldap keystone

juju config keystone-ldap ldap-server="ldap://10.5.0.72" ldap-user="cn=admin,dc=test,dc=com" ldap-password="crapper" ldap-suffix="dc=test,dc=com"
juju config keystone-ldap domain-name="aaa_domain"
juju config keystone-ldap ldap-config-flags="{ user_tree_dn: 'dc=test,dc=com', query_scope: 'sub', user_objectclass: posixAccount, user_id_attribute: uid, user_name_attribute: uid, group_tree_dn: 'ou=groups,dc=test,dc=com', group_objectclass: posixGroup, group_id_attribute: gidNumber, group_name_attribute: cn, group_member_attribute: memberUid, group_members_are_ids: True}"

root@juju-67d093-xenial-queens-ldap-2:~# cat /etc/keystone/domains/keystone.aaa_domain.conf
[ldap]
url = ldap://10.5.0.72
user = cn=admin,dc=test,dc=com
password = password
suffix = dc=test,dc=com

user_allow_create = False
user_allow_update = False
user_allow_delete = False

group_allow_create = False
group_allow_update = False
group_allow_delete = False

# User supplied configuration flags
group_id_attribute = gidNumber
group_member_attribute = memberUid
group_members_are_ids = True
group_name_attribute = cn
group_objectclass = posixGroup
group_tree_dn = ou=groups,dc=test,dc=com
query_scope = sub
#user_id_attribute = uidNumber
user_id_attribute = uid
user_name_attribute = uid
user_objectclass = posixAccount
user_tree_dn = dc=test,dc=com
[identity]
driver = ldap

注意, 上面有几个重要参数,注意是group_members_are_ids = True,下面将要着重讲解。
query_scope = sub
user_tree_dn = dc=test,dc=com
user_id_attribute = uid
group_members_are_ids = True
下面配置也可以work:
query_scope = base
user_tree_dn = dc=users,test,dc=com
user_id_attribute = uid
group_members_are_ids = True

Test

export OS_REGION_NAME=RegionOne
export OS_USER_DOMAIN_NAME=admin_domain
export OS_AUTH_VERSION=3
export OS_IDENTITY_API_VERSION=3
export OS_PASSWORD=openstack
export OS_DOMAIN_NAME=admin_domain
export OS_AUTH_URL=http://10.5.0.53:5000/v3
export OS_USERNAME=admin

openstack domain create --description "aaa_domain" aaa_domain openstack domain list openstack project list --domain aaa_domain openstack group list --domain aaa_domain openstack role list #openstack project create aaa_project --domain aaa_domain #openstack role create aaa_role # Assign Role to a user in a Domain, quqi is from ldap #openstack role add --project procloud --user quqi ladmin # Assign Role to a group named openstack in a project #openstack role add --group openstack --group-domain aaa_domain --project aaa_project Member $ openstack user list --domain aaa_domain +------------------------------------------------------------------+---------+ | ID | Name | +------------------------------------------------------------------+---------+ | 5d15ad6474b1f212d159d974eba4d6b402636e67a7253bf7acb64403ff8c2c53 | janedoe | | dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe | +------------------------------------------------------------------+---------+ $ openstack group contains user --group-domain aaa_domain --user-domain aaa_domain openstack johndoe johndoe in group openstack 

问题一,找不着用户的调试

找不着用户时, 可查看日志:

(keystone.common.ldap.core): 2018-06-08 12:13:23,145 DEBUG LDAP bind: who=cn=admin,dc=cloud,dc=sts
(keystone.common.ldap.core): 2018-06-08 12:13:23,145 DEBUG LDAP search: base=dc=cloud,dc=sts scope=2 filterstr=(&(uidNumber=10002)(objectClass=inetOrgPerson)) attrs=['description', 'uidNumber', 'userPassword', 'enabled', 'mail', 'uid'] attrsonly=0

转换成下列命令看是否能运行:

sudo ldapsearch -h 10.5.0.53 -x -b 'dc=cloud,dc=sts' -s sub "(&(uidNumber=10002)(objectClass=inetOrgPerson))" description uidNumber userPassword enabled mail uid attrsonly=0

问题二,group_members_are_ids = True

例如本例数据:

# Entry 5: cn=openstack,ou=groups,dc=test,dc=com
dn: cn=openstack,ou=groups,dc=test,dc=com
cn: openstack
gidnumber: 501
memberuid: johndoe
objectclass: posixGroup
objectclass: top

# Entry 8: cn=johndoe,ou=users,dc=test,dc=com
dn: cn=johndoe,ou=users,dc=test,dc=com
cn: johndoe
gidnumber: 501
givenname: John
homedirectory: /home/users/jdoe
loginshell: /bin/sh
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: John Doe
uid: johndoe
uidnumber: 1000
userpassword: {MD5}HOMR4pM15t3gYd8WUxMG8g==
# password is crapper

根据这个bug描述 - https://bugs.launchpad.net/keystone/+bug/1526462
我们得知在posixGroup类型的group下可以有很多memberuid属性,如本例中为id的形式:
memberuid: johndoe
也可能为下列dn的形式:
memberuid: johndoe,ou=users,dc=test,dc=com
在使用rpdb (import rpdb;rpdb.set_trace())对代码调试(nc 127.0.0.1 4444)时会发现, 当group_members_are_ids=true时,list_group_users就不会再根据dn找id了。
同时下面的一个if语句(if group_member_id == user_id)决定配置中得是:user_id_attribute = uid

(Pdb) p group_member_id
u'johndoe'
(Pdb) p user_id
u'johndoe'
(Pdb) l
142             # work.
143             self.get_user(user_id)
144             import rpdb;rpdb.set_trace()
145             member_list = self.group.list_group_users(group_id)
146             for group_member_id in self._transform_group_member_ids(member_list):
147  ->             if group_member_id == user_id:
148                     break
149             else:
150                 raise exception.NotFound(_("User '%(user_id)s' not found in"
151                                            " group '%(group_id)s'") %
152                                          {'user_id': user_id,

相关阅读:

LDAP Query to list all users of a certain group

What are the differences between LDAP and Active Directory?

What are CN, OU, DC in an LDAP search?

How to write LDAP query to test if user is member of a group?

sAMAccountName和Domain的Active Directory LDAP查询

轻松测试LDAP用户凭据的方法

如何找出哪个服务器在我的Windows域上托管LDAP?

使用LDAP通过Active Directory在PHP中进行身份验证

什么是LDAP用于?

如何在C#中获取当前用户的Active Directory详细信息