LDAP Authentication for OpenStack

By Gema Gomez

One of the things we needed to do to be able to manage the Linaro Developer Cloud sensibly was to use LDAP for user authentication. It is interesting to note that our cloud being ARM64 didn’t make any difference in terms on how to configure LDAP or the dependencies that were required. Documentation for LDAP configuration is scattered and unclear in terms of what is or what is not up to date, so I reached out to the Keystone PTL for guidance on where to find the right documentation. He was very helpful and pointed me to his blog post “Configuring Keystone with IBM’s Bluepages LDAP”.

When I started this work I had a few questions:

  • How will we manage projects?
  • Will we be able to have users outside LDAP?
  • How will we disable users when they no longer require access?

In the case of the Linaro Developer Cloud, we are producing/using/testing our own build of OpenStack for ARM64, this build is based on Newton and was installed on Debian.

Searching for the right docs I found a page that seemed to have old instructions, I did get deprecation messages when trying to follow these instructions.

Our cloud is deployed using our own ansible scripts, so a few changes were required for LDAP to be integrated with our deployment. There are two projects that were affected by this change, Keystone and Horizon.

One of the most important things to take away is that there is still need for a services domain, so you will need to store the services accounts in SQL. LDAP will take care of user authentication and however you decide to manage projects for those users is independent of the initial set up of LDAP.

I followed Steve’s instructions and created a domain for us and a project to test the set up:

# openstack domain create your_domain
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description |                                  |
| enabled     | True                             |
| id          | c99102f5d72b45b380b2fda60eb59a36 |
| name        | your_domain                      |
+-------------+----------------------------------+

# openstack project create your_project --domain your_domain
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description |                                  |
| domain_id   | c99102f5d72b45b380b2fda60eb59a36 |
| enabled     | True                             |
| id          | ecde336d467a49928add5ee13b8f1b9d |
| is_domain   | False                            |
| name        | your_project                     |
| parent_id   | c99102f5d72b45b380b2fda60eb59a36 |
+-------------+----------------------------------+

Then added the three lines that tell Keystone to enable domain specific identity drivers to our keystone.conf file:

[identity]
domain_specific_drivers_enabled = True
domain_config_dir = /etc/keystone/domains

And then I added an /etc/keystone/domains/keystone.linaro.conf and populated it with the specifics from our LDAP directory. Here is our template, make sure to use ldapsearch to figure out what values are needed for your specific case:

[identity]
driver = ldap

[ldap]
url = {{ ldap_url }}
user = {{ldap_user}}
password = "{{ldap_password}}"
suffix = {{ldap_suffix}}
query_scope = sub

user_tree_dn = {{ldap_user_tree_dn}}
user_objectclass = {{ldap_user_objectclass}}
user_id_attribute = {{ldap_user_id_attribute}}

user_name_attribute = {{ldap_user_name_attribute}}
user_mail_attribute = {{ldap_user_mail_attribute}}
user_pass_attribute = {{user_pass_attribute}}
user_enabled_attribute = {{ldap_user_enabled_attribute}}

group_tree_dn = {{ldap_group_tree_dn}}
group_objectclass = {{ldap_group_objectclass}}
group_id_attribute = {{ldap_group_id_attribute}}
group_name_attribute = {{ldap_group_name_attribute}}
group_member_attribute = {{ldap_group_member_attribute}}
group_desc_attribute = {{ldap_group_desc_attribute}}

user_filter = {{ldap_user_filter}}

After this we assigned a role of ‘member’ to users from the dev-cloud-users group.

openstack role add member --group dev-cloud-users
                          --group-domain your_group_domain
			  --project your_project
			  --project-domain your_domain

After the configuration was changed, we restarted Keystone and went on to test whether we could get a token or list images. Both useful tests to figure out if the configuration is sound. To be able to use the command line, a new OS_USER_DOMAIN_NAME and OS_PROJECT_DOMAIN_NAME need to be added to the user’s rc file:

OS_PROJECT_NAME=your_project
OS_PROJECT_DOMAIN_NAME=your_domain

One last detail to be able to log into Horizon with the new domain, some changes need to be made to Horizon’s config file:

OPENSTACK_API_VERSIONS = {
    "data-processing": 1.1,
    "identity": 3,
    "volume": 2,
}
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
OPENSTACK_KEYSTONE_URL="http://your_keystone_address:5000/v3"

Note these instructions have been tested with OpenStack Newton. The following patch summarizes the changes we had to do our reference architecture ansible scripts to integrate LDAP support to it:

https://review.linaro.org/#/c/17085/

References:

  1. Steve Martinelli’s Blog Post
  2. Keystone Documentation