Most people cannot write to the LDAP servers except to manage their own data. Thus, OpenStack requiring the Service users in LDAP is a burden that many IT organizations cannot assume. In Juno we have support for Multiple backends for domains.
Update: I wrote this before the OpenStack common CLI was ready. A much better starting point is: Adding an LDAP backed domain to a Packstack install which applies even for installs other than Packstack.
Starting with a devstack install, (and an unrelated bug fix) I created a file: /etc/keystone/domains/keystone.freeipa.conf. The naming of this file is essential: keystone..conf is the expected form. It looks like this.
# The domain-specific configuration file for the test domain # 'domain1' for use with unit tests. [ldap] url=ldap://ipa.cloudlab.freeipa.org user_tree_dn=cn=users,cn=accounts,dc=ipa,dc=cloudlab,dc=freeipa,dc=org user_id_attribute=uid user_name_attribute=uid group_tree_dn=cn=groups,cn=accounts,dc=ipa,dc=cloudlab,dc=freeipa,dc=org [identity] driver = keystone.identity.backends.ldap.Identity
And made the following changes to /etc/keystone/keystone.conf
[identity] domain_specific_drivers_enabled=true domain_config_dir=/etc/keystone/domains
I restarted HTTPD to get Keystone to pick up my changes:
sudo systemctl restart httpd.service
Then followed the steps from my earlier blog post to list domains.
export TOKEN=`curl -si -d @token-request-admin.json -H "Content-type: application/json" http://localhost:35357/v3/auth/tokens | awk '/X-Subject-Token/ {print $2}'` curl -s -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" http://localhost:35357/v3/domains | jq '.domains[] | {id, name}
Note that I used a little jq to make things easier to read.
To add the new domain:
curl -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" -d '{"domain": {"description": "FreeIPA Backed LDAP Domain", "enabled": true, "name": "freeipa"}}' http://localhost:35357/v3/domains
Now to test out the new domain I have a user from the LDAP server. Good Old Edmund. Here is token-request-edmund-freeipa.json
{ "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "name": "freeipa" }, "name": "edmund", "password": "freeipa4all" } } } } }
-sh-4.2$ curl -si -d @token-request-edmund-freeipa.json -H "Content-type: application/json" http://localhost:35357/v3/auth/tokens HTTP/1.1 201 Created Date: Mon, 11 Aug 2014 14:52:14 GMT Server: Apache/2.4.10 (Fedora) mod_wsgi/3.5 Python/2.7.5 X-Subject-Token: PKIZ_eJx1VMmSozgUvPMVfa-oKBaD8aEPEsIgXJILEJtuBmw2eTfG5uuHcnXEzBxat5ehzHxPynjv79OBtoPpL4uE38W7RDC2FkPmrY4c1_eCAr-wjhNmIMsCvW8B335YDLiwii6oIpbTTngkO1Z4dkKcaxLybRdsJpDN7Kqyje3Tk3P1JvIGG9i9NpuUjmUSd6m6lHF7rHCLB8L8G0HVjbBlJE2FQRk2CIt6OgKFjL6eNPiKLU9s3eCZpaRZN3C-C4cK7xVROvWduy8sxwdYS4VGtVzzOizkPyR4Kvbx-DfHyeh_hhIZ7ecfR6VQ4-c3aRqjy1Wl3iSzlzvei-4lto9mJMlmdMzGSWTM2qCW1gzPqIp1uqdijYjME77nrf3EzXfLep0n0SQCGn7wBE_EkIXe4tMCzSbxX7hE2u5BR9FRFj04KkbSQkEZUAnzGo6EyJjYUyduCYINYbAlaiSTlsgk8ZU1657S2glqymx1ndgyZ2QkqGz5z0h9lijip_W4y9O455a32KXyo6ocOH0_3PkYSoDBgiyLhzUCD1Y0hiBjQMSM-LMBgQzFvo8RiOP8QEWJ7DUBgwOUyIbDsIwTfZR46j9QC8gP-UhgHPfTY8okqIZl9RJACCy0Uit6ntZ1nsIrD_U2V-XvkA0SHLLlapghUB8H5P83kTaEPvgOF-hIdpO7UNSmnLZXeLqXffBhOUwPUkvqdg2vHx_mmSu1YVy9ozbUnLAzTd5clJkqKoubnU_xTtfHMdymNRgRCdEFB4fDoC2FxKNP9iXicA6avAtquQzmJ8q-jK3XDHvVgIvNTW9P84-3dsvNNemCw2fDqUfHWX18rORAuga7U2WaXChPLVF7S9bedL3Tmtonpb4KFqnBBdP7Q9-cD0O5L8doU503fsVcC33V50pq7-N93n0cyf0xLE1MS3exq4P0pmwwnNkm0a1NWG2s3fnpuKWD36gd3k9qtu0uF4Nw5ErZ7cbnZn9wL8FQ6NvKzDy7genTjYRjlm_bL_eL59Pl-c1V9B20i3b3qWIOVsPv39JrI9gU_bsd_gH7ultg Vary: X-Auth-Token Content-Length: 314 Content-Type: application/json {"token": {"issued_at": "2014-08-11T14:52:15.705349Z", "extras": {}, "methods": ["password"], "expires_at": "2014-08-11T15:52:15.705312Z", "user": {"domain": {"id": "e81f8763523b4a9287b96ce834efff12", "name": "freeipa"}, "id": "29179d551d7320e50612bd9ea9f4ec00b10c3e42341d59928da5169a4e3307cf", "name": "edmund"}}}-sh-4.2$
It works! Henry Nash worked hard on this. IT was supposed to land for Havana, but it got delayed by several issues. Probably the biggest was the User_Id. Notice in the Token response above that Edmund’s User ID is not the UID field from the LDAP query, but rather 29179d551d7320e50612bd9ea9f4ec00b10c3e42341d59928da5169a4e3307cf. This value is a SHA256 of the LDAP assigned filed and the domain_id combined. This mechanism was select to prevent conflicts between two different Identity Providers assigning the same value. To confirm:
$ echo "select * from id_mapping;" | mysql keystone public_id domain_id local_id entity_type 29179d551d7320e50612bd9ea9f4ec00b10c3e42341d59928da5169a4e3307cf e81f8763523b4a9287b96ce834efff12 edmund user
Thanks for sharing and documenting this. I exactly searched for this use case.
I have similar requirements and am trying to follow your commands. More specifically, I am trying to integrate with an existing AD server that contains a specific AD group. I am trying to read the group, users and mappings from AD. In my keystone..conf file, using the user_filter I am able to read all the users from AD by using memberof=myADgroup. I have a similar group_filter specifying my group as the cn (cn=myADgroup) but am unable to get any groups created. Would you be able to tell me if this is possible?
What do you mean by “created?” If you are doing AD, it should probably treat LDAP as read only, and I am going to assume this is what you meant. That you could not read the groups out of LDAP. I’d turn on logging and see what the LDAP query you are generating, as it probably doesn’t quite match your schema. You are close; you should be able to fetch groups and group assignments out of AD.
Thanks Adam – I noticed the user names are not getting set to the cn value which is what I have set in my keystone.conf file – I currently have the user_id_attribute and user_name_attribute set to the cn value but the user name gets set to the sn value. Do you know how I can get the username to be cn value?
The best bet is to us rpdb to debug, and see what is happening for yourself.
I have implemented keystone as above, can still login as admin to the dashboard, but cannot list users. I am able to successfully perform the curl validation using an existing AD user as in the last screen shot. I have a read-only AD, and want SQL to manage roles, etc. Is there a setting for backends for [role] and [resource} I need in my /etc/keystone/keystone.conf file ?
“cannot list users” in what domain? In order to do a list users, you need an account with the admin role on the admin domain.
There are a lot of variables in play here, including what you have for you policy file. I’d recommend starting with the cloud sample policy file, but be aware that you need to edit that before deploying it to set the “admin domain”.
If you have more questions, please ask on the openstack mailing list, and provide lots of context.