1. 程式人生 > >Play with LDAP + Keystone (by quqi99)

Play with LDAP + Keystone (by quqi99)

版權宣告:可以任意轉載,轉載時請務必以超連結形式標明文章原始出處和作者資訊及本版權宣告 (作者:張華 發表於: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}"

[email protected]:~# 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

source ~/stsstack-bundles/novarcv3_domain
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 create myproject --domain aaa_domain
openstack project list --domain aaa_domain
#The token used to make the request was project scoped but the policy requires ['system'] scope
#so it should be 'openstack  group create aaa_group'
#openstack group create aaa_group --domain aaa_domain 
#openstack group create aaa_group        #we use the default openstack instead
openstack group list --domain aaa_domain
openstack role list
openstack user list --domain aaa_domain
openstack user list --group openstack --domain aaa_domain

#Assign Role to a user in a Domain, it used --domain
#openstack role add --user johndoe --domain aaa_domain Member
#Assign Role to a group in a project, it used --group-domain
openstack role add --group openstack --group-domain aaa_domain --project myproject Member
openstack role add --group openstack --group-domain aaa_domain --project myproject Admin
openstack role list --group openstack --group-domain aaa_domain --project myproject

$ 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

source ~/stsstack-bundles/novarcv3_project
export OS_USER_DOMAIN_NAME=aaa_domain
export OS_PROJECT_DOMAIN_NAME=aaa_domain
export OS_PROJECT_NAME=myproject
export OS_USERNAME=johndoe
export OS_PASSWORD=crapper
export OS_AUTH_URL=http://10.5.0.72:5000/v3
export OS_AUTH_VERSION=3
export OS_IDENTITY_API_VERSION=3
export OS_REGION_NAME=RegionOne

[email protected]:~⟫ openstack user show johndoe
+---------------------+------------------------------------------------------------------+
| Field               | Value                                                            |
+---------------------+------------------------------------------------------------------+
| domain_id           | ae678292805a4db7917137c0621fe4cc                                 |
| id                  | dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 |
| name                | johndoe                                                          |
| options             | {}                                                               |
| password_expires_at | None                                                             |
+---------------------+------------------------------------------------------------------+

[email protected]:~⟫ openstack user list
You are not authorized to perform the requested action: identity:list_users. (HTTP 403) (Request-ID: req-8c373161-37d7-4d33-9dda-16bdbd2cecb7)

Why we are not authorized to run 'openstack user list', that's because the following policy rules.

"admin_required": "role:Admin",
"cloud_admin": "rule:admin_required and (is_admin_project:True or domain_id:59d6b9c88f654dba9d06772ec1b197f0 or project_id:bbbb856f30b042a9a64d6646273a9ae2)",
"owner" : "user_id:%(user_id)s or user_id:%(target.token.user_id)s",
"admin_and_matching_group_domain_id": "rule:admin_required and domain_id:%(group.domain_id)s",
"admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s",

"identity:get_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id or rule:owner",
"identity:list_users": "rule:cloud_admin or rule:admin_and_matching_domain_id",

問題一,找不著使用者的除錯

找不著使用者時, 可檢視日誌:

(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裡的使用者

1, Confirm the user johndoe is in the domain aaa_domain

[email protected]:~⟫ openstack user list --domain aaa_domain
+------------------------------------------------------------------+---------+
| ID                                                               | Name    |
+------------------------------------------------------------------+---------+
| 5d15ad6474b1f212d159d974eba4d6b402636e67a7253bf7acb64403ff8c2c53 | janedoe |
| dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe |
+------------------------------------------------------------------+---------+

2, Create a project myproject

openstack project create myproject --domain aaa_domain

[email protected]:~⟫ openstack project list --domain aaa_domain
+----------------------------------+-----------+
| ID                               | Name      |
+----------------------------------+-----------+
| f239a9aebc974664b3fb7823d7d873fa | myproject |
+----------------------------------+-----------+

3, LDAP has two groups, one is admin, one is openstack, see https://api.jujucharms.com/charmstore/v5/~openstack-charmers/ldap-test-fixture-3/archive/files/backup.ldif

[email protected]:~⟫ openstack group list --domain aaa_domain
+------------------------------------------------------------------+-----------+
| ID                                                               | Name      |
+------------------------------------------------------------------+-----------+
| a202723c28709cef142842b452fc93caf45d6b661e5d636a96cd10b9379fe0d2 | admin     |
| c94536ce5d46380996999782dacf490b640385cd9b75450782cb279501238eac | openstack |
+------------------------------------------------------------------+-----------+

[email protected]:~⟫ openstack user list --group openstack --domain aaa_domain
+------------------------------------------------------------------+---------+
| ID                                                               | Name    |
+------------------------------------------------------------------+---------+
| dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe |
+------------------------------------------------------------------+---------+
[email protected]:~⟫ openstack user list --group admin --domain aaa_domain
+------------------------------------------------------------------+---------+
| ID                                                               | Name    |
+------------------------------------------------------------------+---------+
| dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe |
+------------------------------------------------------------------+---------+

3, Assign Role to a group in a project

openstack role add --group openstack --project myproject --group-domain aaa_domain Member
openstack role add --group openstack --project myproject --group-domain aaa_domain Admin

[email protected]:~⟫ openstack role list --group openstack --project myproject --group-domain aaa_domain
Listing assignments using role list is deprecated. Use role assignment list --group <group-name> --project <project-name> --names instead.
+----------------------------------+--------+-----------+-----------+
| ID                               | Name   | Project   | Group     |
+----------------------------------+--------+-----------+-----------+
| 578a7eca0d184945b57ed0b718e59ae0 | Member | myproject | openstack |
| 64c64c90886d4f3cb13d3c599748086b | Admin  | myproject | openstack |
+----------------------------------+--------+-----------+-----------+

4, Confirm the user johndoe in the the domain aaa_domain and group openstack

[email protected]:~⟫ openstack user list --group openstack --domain aaa_domain
+------------------------------------------------------------------+---------+
| ID                                                               | Name    |
+------------------------------------------------------------------+---------+
| dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe |
+------------------------------------------------------------------+---------+

5, Switch to use the user johndoe

source ~/stsstack-bundles/novarcv3_project
export OS_USER_DOMAIN_NAME=aaa_domain
export OS_PROJECT_DOMAIN_NAME=aaa_domain
export OS_PROJECT_NAME=myproject
export OS_USERNAME=johndoe
export OS_PASSWORD=crapper
export OS_AUTH_URL=http://10.5.0.72:5000/v3
export OS_AUTH_VERSION=3
export OS_IDENTITY_API_VERSION=3
export OS_REGION_NAME=RegionOne

6, Test the user johndoe

[email protected]:~⟫ openstack user show johndoe
+---------------------+------------------------------------------------------------------+
| Field               | Value                                                            |
+---------------------+------------------------------------------------------------------+
| domain_id           | ae678292805a4db7917137c0621fe4cc                                 |
| id                  | dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 |
| name                | johndoe                                                          |
| options             | {}                                                               |
| password_expires_at | None                                                             |
+---------------------+------------------------------------------------------------------+

[email protected]:~⟫ openstack user list
You are not authorized to perform the requested action: identity:list_users. (HTTP 403) (Request-ID: req-8c373161-37d7-4d33-9dda-16bdbd2cecb7)

Why we are not authorized to run 'openstack user list', that's because the following policy rules.

"admin_required": "role:Admin",
"cloud_admin": "rule:admin_required and (is_admin_project:True or domain_id:59d6b9c88f654dba9d06772ec1b197f0 or project_id:bbbb856f30b042a9a64d6646273a9ae2)",
"owner" : "user_id:%(user_id)s or user_id:%(target.token.user_id)s",
"admin_and_matching_group_domain_id": "rule:admin_required and domain_id:%(group.domain_id)s",
"admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s",

"identity:get_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id or rule:owner",
"identity:list_users": "rule:cloud_admin or rule:admin_and_matching_domain_id",

怎麼才能讓openstack user list生效呢?
1, LDAP中的兩個組openstack與admin, johndoe都在這兩個組下。
[email protected]:~⟫ openstack user list --group openstack --domain aaa_domain
+------------------------------------------------------------------+---------+
| ID                                                               | Name    |
+------------------------------------------------------------------+---------+
| dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe |
+------------------------------------------------------------------+---------+
[email protected]:~⟫ openstack user list --group admin --domain aaa_domain
+------------------------------------------------------------------+---------+
| ID                                                               | Name    |
+------------------------------------------------------------------+---------+
| dcb455d78a9cc380d615fa79c56569b3e9947d9af7a2f83813b53fca198b61a5 | johndoe |
+------------------------------------------------------------------+---------+
2, policy rules中在用project_id:bbbb856f30b042a9a64d6646273a9ae2
所以首先得用admin許可權為bbbb856f30b042a9a64d6646273a9ae2這個project新增Admin role:
openstack role add --group admin --project bbbb856f30b042a9a64d6646273a9ae2 --group-domain aaa_domain Admin
其將環境變數得使用這個group:
unset OS_PROJECT_NAME
export OS_PROJECT_ID=bbbb856f30b042a9a64d6646273a9ae2
[email protected]:~⟫ openstack user list
+----------------------------------+-------------------+
| ID                               | Name              |
+----------------------------------+-------------------+
| 12507a988b8a438e85ee36617302fd34 | neutron           |
| 1b8ad6f6fc4c479a90b7a34c8187cd3b | cinderv2_cinderv3 |
| 2c6d8f3b156c45b5bb7998cca056edc4 | nova_placement    |
| feaaf07467f142a5a5901ab066af9dca | glance            |
+----------------------------------+-------------------+
[email protected]:~⟫ env |grep OS_
OS_PROJECT_ID=bbbb856f30b042a9a64d6646273a9ae2
OS_REGION_NAME=RegionOne
OS_USER_DOMAIN_NAME=aaa_domain
OS_AUTH_VERSION=3
OS_IDENTITY_API_VERSION=3
OS_PASSWORD=crapper
OS_AUTH_URL=http://10.5.0.72:5000/v3
OS_USERNAME=johndoe
OS_PROJECT_DOMAIN_NAME=aaa_domain