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.
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?
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.