FreeIPA Keystone LDAP Store

The next interim release of Openstack  Keystone will once again have LDAP support.  I am developing against OpenLDAP to start, as that is what the LDAP support has been based on in the past.  However, the directory server that backs FreeIPA works perfectly well,  and provides a backend that allows for Keystone support.

I am running FreeIPA in a virtual machine (KVM) that runs on my laptop.  I have a /etc/host entry that allows it to resolve.  I’ve taken the pattern of using my laptops name as the domain for IPA to control.  Since my laptop

ayoung@ayoung etc]$ hostname
ayoung.boston.devel.redhat.com

I’ve named the vm: f16server.ayoung.boston.devel.redhat.com. To install FreeIPA, I ran:

 ipa-server-install --forwarder=192.168.122.1  --setup-dns -n `hostname -d` -U -r `hostname  | tr "[:lower:]" "[:upper:]"` -p freeipa4all -a freeipa4all

Which should almost work for you, too: You will want to modify the forwarder to be one of the current nameserver values in /etc/resolv.conf

I loaded it up with sample data, including the following line as part of a batch command:

 {"method":"user_add", "params":[["zmarsh"],{"givenname":"Zackary","sn":"Marsh"}]},

Note that I first run

ipapasswd zmarsh

And set the password to 1 to one, and then I

kinit  zmarsh

to change the password to be the old standby of freeipa4all.

I made the following changes to my keystone.conf file:

diff --git a/etc/keystone.conf b/etc/keystone.conf
index 9020ea6..c929b42 100644
--- a/etc/keystone.conf
+++ b/etc/keystone.conf
@@ -23,17 +23,21 @@ max_pool_size = 10
 pool_timeout = 200

 [ldap]
-#url = ldap://localhost
-#tree_dn = dc=example,dc=com
-#user_tree_dn = ou=Users,dc=example,dc=com
-#role_tree_dn = ou=Roles,dc=example,dc=com
-#tenant_tree_dn = ou=Groups,dc=example,dc=com
-#user = dc=Manager,dc=example,dc=com
-#password = freeipa4all
-#suffix = cn=example,cn=com
+url = ldap://f16server.ayoung.boston.devel.redhat.com
+tree_dn = cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
+
+user_id_attribute=uid
+user_tree_dn = cn=users,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
+role_tree_dn = cn=groups,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
+tenant_tree_dn = cn=groups,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
+user = uid=admin,cn=users,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
+password = freeipa4all
+ldapsearch -x -W -D  uid=admin,cn=users,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com     -H ldap://f16server.ayoung.boston.devel.redhat.com  -b ""
+
+

 [identity]
-driver = keystone.identity.backends.kvs.Identity
+driver = keystone.identity.backends.ldap.Identity

 [catalog]
 driver = keystone.catalog.backends.templated.TemplatedCatalog

Yes, I am aware that using the LDAP protocol in the clear is not the preferred way to do things. LDAPS support is coming, I promise.

Now I fired up Keystone ( I run it in Eclipse, for integrated debugging) and first tested it using curl.

curl -s  -H "Content-Type:application/json"          -H "Accept:applicaton/json"  -d '{"auth":{"passwordCredentials":{"userId":"zmarsh", "password":"freeipa4all"} ,"tenantId":"ipausers"}}'   -X POST  http://0.0.0.0:35357/v2.0/tokens

Which returned the value.

{"access": {"token": {"expires": "2012-03-01T22:06:49Z", "id": "bfd6299ac37c4c91982867eb269b4505", "tenant": {"enabled": true, "id": "ipausers"}}, "serviceCatalog": [{"endpoints": [{"adminURL": "http://localhost:8774/v1.1/ipausers", "region": "RegionOne", "publicURL": "http://localhost:8774/v1.1/ipausers", "internalURL": "http://localhost:8774/v1.1/ipausers"}], "endpoints_links": [], "type": "compute", "name": "'Compute Service'"}, {"endpoints": [{"adminURL": "http://localhost:35357/v2.0", "region": "RegionOne", "publicURL": "http://localhost:5000/v2.0", "internalURL": "http://localhost:35357/v2.0"}], "endpoints_links": [], "type": "identity", "name": "'Identity Service'"}], "user": {"username": "Marsh", "roles_links": [], "id": "zmarsh", "roles": [], "name": "Marsh"}}}

And hit it from Keystone client (running in the python interpreter)

>>> from keystoneclient.v2_0 import client
>>> keystone = client.Client(username='Marsh', password='freeipa4all', tenant_name='', auth_url='http://0.0.0.0:5000/v2.0')
>>> print keystone

One trick that makes ipa a great teaching tool for ldap is running ipa show and ipa find commands with the –raw and –all switches. For example, to confirm the distinguished name of the test user, I can run:

[root@f16server ~]# ipa user-show zmarsh --all --raw
  dn: uid=zmarsh,cn=users,cn=accounts,dc=f16server,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com
  uid: zmarsh
  givenname: Zackary
...

Some details and warts.

  • I’m using FreeIPA’s User Groupsfor the tenant grouping. I’d prefer long term to use netgroups.
  • Keystone Roles are not yet implemented.
  • The User object usese SN for the user name, which is not a unique field.

2 thoughts on “FreeIPA Keystone LDAP Store

  1. Hi,
    thanx for the tutorial but my small mind is having a hard time understanding it’s begining.
    I saw you used
    “ipa-server-install –forwarder=192.168.122.1 –setup-dns -n `hostname -d` -U -r `hostname | tr “[:lower:]” “[:upper:]”` -p freeipa4all -a freeipa4all”
    I don’t know much about freeipa but after googling I found out it’s related to DNS service.
    Does it mean that to establish anykind of ldap over keystone (say an already existing and loaded one wether Openldap or WinAD), the ldap server needs to recognize the keystone server?

  2. FreeIPA includes an LDAP server. It is the heart of FreeIPA, really. All of the Data that IPA manages is stored and exposed via LDAP, to include the DNS entries. I worked on FreeIPA for a while prior to working on Keystone, and I wanted to make sure I could get the two to work together. This is not the main way we expect LDAP/Keystone integration to be performed, but it will be useful to many people.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.