OpenStack Keystone: Integrating LDAP with IPA

Overview

Keystone_logo

Keystone is the identity service in OpenStack responsible for authentication of users and services. Keystone leverages tokens which are transient in nature. In addition to authentication Keystone allows for policy management defining roles and responsibilities that govern users, services and tenants. Fine granular RBAC is also possible, Keystone allows for mapping capabilities directly to users. Finally, Keystone provides a catalog for all service endpoints within OpenStack. Most organizations will have either central AD or LDAP for managing users and services. In this article we will integrate Keystone with LDAP using central IPA server.

Setup IPA Server

A special thanks to Asaf Waizman and his team at Red Hat for providing a lot of insight on this subject. Before we configure Keystone we need to ensure a central identity management system is configured.

  • Install RHEL or CentOS 7.1
  • If using RHEL ensure subscription-manager is configured for appropriate repos
[root@ipa ~]# subscription-manager attach --pool=39482983298398232
[root@ipa ~]# subscription-manager repos --disable=* 
[root@ipa ~]# subscription-manager repos --enable=rhel-7-server-rpms 
[root@ipa ~]# subscription-manager repos --enable=rhel-7-server-aus-rpms
  • Install IPA Server
[root@ipa ~]# yum install ipa-server ipa-server-dns
  • Configure IPA Server
[root@ipa ~]# ipa-server-install

The log file for this installation can be found in /var/log/ipaserver-install.log
==============================================================================
This program will set up the IPA Server.

This includes:
 * Configure a stand-alone CA (dogtag) for certificate management
 * Configure the Network Time Daemon (ntpd)
 * Create and configure an instance of Directory Server
 * Create and configure a Kerberos Key Distribution Center (KDC)
 * Configure Apache (httpd)

To accept the default shown in brackets, press the Enter key.

Do you want to configure integrated DNS (BIND)? [no]: yes

Enter the fully qualified domain name of the computer
on which you're setting up server software. Using the form
<hostname>.<domainname>
Example: master.example.com.


Server host name [ipa.lab.com]: 

Warning: skipping DNS resolution of host ipa.lab.com
The domain name has been determined based on the host name.

Please confirm the domain name [lab.com]: 

The kerberos protocol requires a Realm name to be defined.
This is typically the domain name converted to uppercase.

Please provide a realm name [LAB.COM]: 
Certain directory server operations require an administrative user.
This user is referred to as the Directory Manager and has full access
to the Directory for system management tasks and will be added to the
instance of directory server created for IPA.
The password must be at least 8 characters long.

Directory Manager password: 
Password (confirm): 

The IPA server requires an administrative user, named 'admin'.
This user is a regular system account used for IPA server administration.

IPA admin password: 
Password (confirm): 

Existing BIND configuration detected, overwrite? [no]: yes
Do you want to configure DNS forwarders? [yes]: 
Enter an IP address for a DNS forwarder, or press Enter to skip: 192.168.122.1
DNS forwarder 192.168.122.1 added. You may add another.
Enter an IP address for a DNS forwarder, or press Enter to skip: 
Checking DNS forwarders, please wait ...
Do you want to configure the reverse zone? [yes]: 
Please specify the reverse zone name [122.168.192.in-addr.arpa.]: 
Using reverse zone(s) 122.168.192.in-addr.arpa.

The IPA Master Server will be configured with:
Hostname: ipa.lab.com
IP address(es): 192.168.122.100
Domain name: lab.com
Realm name: LAB.COM

BIND DNS server will be configured to serve IPA domain with:
Forwarders: 192.168.122.1
Reverse zone(s): 122.168.192.in-addr.arpa.

Continue to configure the system with these values? [no]: yes

The following operations may take some minutes to complete.
Please wait until the prompt is returned.

Configure Keystone Users in IPA

In this example we will configure three users in LDAP. An openstack user is needed for authentication of keystone itself within LDAP. An openstack admin user is needed to administer OpenStack and we will also create a tenant or normal OpenStack user.

  • Configure OpenStack user for Keystone authentication
[root@ipa ~]# kinit admin
[root@ipa ~]# ipa user-add openstack --first="OpenStack" --last "Ldap"
[root@ipa ~]# ipa passwd openstack
 New Password: changeme
 Enter New Password again to verify: changeme
 ----------------------------------------
 Changed password for "openstack@LAB.COM"
 ----------------------------------------
[root@ipa ~]# kinit openstack
 Password for openstack@LAB.COM:
 Password expired. You must change it now.
 Enter new password:
 Enter it again:
  • Configure OpenStack user, this will be a tenant user within OpenStack
[root@ipa ~]# kinit admin
[root@ipa ~]# ipa user-add ospuser --first="ospuser" --last "ospuser"
[root@ipa ~]# ipa passwd ospuser
 New Password:  changeme
 Enter New Password again to verify:  changeme
 --------------------------------------
 Changed password for "ospuser@LAB.COM"
 --------------------------------------
[root@ipa ~]# kinit ospuser
 Password for ospuser@LAB.COM:
 Password expired. You must change it now.
 Enter new password:
 Enter it again:
  • Configure OpenStack administrator, this will be admin within OpenStack
[root@ipa ~]# kinit admin
[root@ipa ~]# ipa user-add ospadmin --first="ospadmin" --last "ospadmin"

[root@ipa ~]# ipa passwd ospadmin 
New Password: changeme 
Enter New Password again to verify: changeme 
--------------------------------------- 
Changed password for "ospadmin@LAB.COM" 
---------------------------------------
[root@ipa ~]# kinit ospadmin
 Password for ospadmin@LAB.COM:
 Password expired. You must change it now.
 Enter new password:
 Enter it again:
  • Create LDAP group for OpenStack users
[root@ipa ~]# kinit admin
[root@ipa ~]# ipa group-add enabled_users --desc "Users who can access OpenStack"
[root@ipa ~]# ipa group-add-member enabled_users --users=ospuser
[root@ipa ~]# ipa group-add-member enabled_users --users=ospadmin
  • Enable LDAP ports in firewall
[root@ipa ~]# firewall-cmd --add-service ldap --permanent
[root@ipa ~]# firewall-cmd --reload

Configure Keystone Services in IPA

As mentioned Keystone authenticates both users and services. However in order to complete integration, we also need to authenticate OpenStack services in LDAP. A typical OpenStack deployment consists of the following services: glance, cinder, heat, neutron, nova and swift. If you are using additional OpenStack services such as manila, trove, sahara, etc you will also need to add additional accounts for those services.

[root@ipa ~]# kinit admin
[root@ipa ~]# for p in glance cinder heat neutron nova swift; do
echo "configuring service $p";
ipa user-add $p --cn=$p --first="$p" --last "$p";
ipa group-add-member enabled_users --users=$p;
ipa passwd $p;
kinit $p;
kinit admin;
done

Disabling service password expiration

Typically you don’t want Keystone passwords for services to expire. In IPA the default is 90 days for password expiration. We will set the number to something that likely won’t be reached in the lifetime of this OpenStack cloud. For production you will want to consider a better solution.

[root@ipa ~]# kinit admin
[root@ipa ~]# ipa group-add --nonposix service-accounts
[root@ipa ~]# ipa pwpolicy-add service-accounts --maxlife=20000 --minlife=0 --history=0 --maxfail=0 --priority=0
[root@ipa ~]# for user in cinder nova glance swift neutron openstack; do
ipa group-add-member service-accounts --user=$user;
done

Configure Keystone

Now that we have an LDAP server with OpenStack users and services configured it is time to enable LDAP backend within Keystone.

  • Enable LDAP backend and configure authentication
[root@osp7.lab.com ~]# vi /etc/keystone/keystone.conf
[identity]

driver = keystone.identity.backends.ldap.Identity

[assignment]
driver = keystone.assignment.backends.sql.Assignment

[ldap]
url = ldap://ipa.lab.com
user = uid=openstack,cn=users,cn=accounts,dc=lab,dc=com
password = redhat01
user_tree_dn=cn=users,cn=accounts,dc=lab,dc=com
user_id_attribute=uid
group_tree_dn=cn=groups,cn=accounts,dc=lab,dc=com
user_enabled_emulation = True
user_enabled_emulation_dn = cn=enabled_users,cn=groups,cn=accounts,dc=lab,dc=com
user_allow_create = False
user_allow_update = False
user_allow_delete = False

  • Create roles for OpenStack administrator and user. This is how you would give external users roles within OpenStack.
[root@osp7.lab.com ~]# export SERVICE_TOKEN=$(openstack-config --get /etc/keystone/keystone.conf "" admin_token)
[root@osp7.lab.com ~]# export SERVICE_ENDPOINT=http://osp7.lab.com:35357/v2.0/
[root@osp7.lab.com ~]# keystone user-role-add --user-id ospadmin --role admin --tenant admin
[root@osp7.lab.com ~]# keystone user-role-add --user-id ospuser --role _member_ --tenant Project1
  • Update the OpenStack service configuration files with LDAP user/password
[root@osp7.lab.com ~]# vi /etc/nova/nova.conf
admin_user = <service>
admin_password = <password>
admin_tenant_name = services

Service should be the name of the OpenStack service (nova, cinder, heat, neutron, swift, glance, etc). The password should be password of the service user in LDAP.

Note: You need to do this for each OpenStack service, below are a list of the files that need to be updated for standard OpenStack services.

/etc/nova/nova.conf
/etc/cinder/cinder.conf
/etc/heat/heat.conf
/etc/neutron/neutron.conf
/etc/swift/swift.conf
/etc/cinder/api-paste.ini
/etc/glance/glance-api.conf
/etc/glance/glance-cache.conf
/etc/glance/glance-registry.conf
  • Restart OpenStack Services
[root@osp7.lab.com ~]# openstack-service restart
[root@osp7.lab.com ~]# systemctl restart httpd
  • Test OpenStack and ensure things are working with LDAP backend
[root@osp7.lab.com ~]# vi ~/keystonerc_ospadmin 
export OS_USERNAME=ospadmin 
export OS_PROJECT_NAME=admin 
export OS_PASSWORD='r3dh4t1!' 
export OS_AUTH_URL=http://192.168.0.20:35357/v2.0/ 
export PS1='[\u@\h \W(keystone_ospadmin)]\$ '
[root@osp7.lab.com ~]# source ~/keystonerc_ospadmin
[root@osp7.lab.com ~]# openstack user list
+-----------+----------+
| ID        | Name     |
+-----------+----------+
| openstack | Ldap     |
| ospuser   | ospuser  |
| ospadmin  | ospadmin |
| glance    | glance   |
| cinder    | cinder   |
| heat      | heat     |
| neutron   | neutron  |
| nova      | nova     |
| swift     | swift    |
+-----------+----------+

Summary

In this article we have seen how to integrate LDAP (IPA) as a backend in Keystone. We have discussed that Keystone not only handles user but also service authentication within OpenStack providing a catalog for all service endpoints. Beyond these capabilities, Keystone is an integral part of any OpenStack architecture and one of the most crucial integration points with existing infrastructure. As always hopefully this article was helpful, all feedback is greatly appreciated!

Happy OpenStacking!

(c) 2016 Keith Tenzer

6 thoughts on “OpenStack Keystone: Integrating LDAP with IPA

    • Hi Wolfram,

      Absolutely, ideally we would run an infrastructure system for things like ansible, ldap and other shared services then everything could authenticate against ldap…this would make things a lot simpler for user management perspective 🙂

      Like

  1. Hey Keith, great stuff. As an alternative, a stacked approach might be good.
    – Use SQL for service accounts, roles and tennants
    – Authenticate normal users against LDAP/AD
    – Assign normal users Roles – mapped using Groups (AD)
    ’cause Openstack admins are not AD/LDAP admins.
    https://wiki.openstack.org/wiki/Domains
    Will keystone v2 support this kind of setup ?

    Like

    • Hi Yogi,

      Great feedback, I agree the stack approach is definitely a nice option, especially because you might not want to manage accounts that dont have password expiration (services). Nevertheless it depends on policies and governance models that exist. As for keystone v2 support, I did test using keystone command, which as you know is depricated and that uses v2 APIs so from that perspective it seems to work fine. Let me know if you have issues w/v2 API?

      [root@osp7 ~(keystone_ospadmin)]# keystone user-list
      /usr/lib/python2.7/site-packages/keystoneclient/shell.py:65: DeprecationWarning: The keystone CLI is deprecated in favor of python-openstackclient. For a Python library, continue using python-keystoneclient.
      ‘python-keystoneclient.’, DeprecationWarning)
      +————+————+———+——————–+
      | id | name | enabled | email |
      +————+————+———+——————–+
      | openstack | Ldap | False | openstack@lab.com |
      | ceilometer | ceilometer | True | ceilometer@lab.com |
      | cinder | cinder | True | cinder@lab.com |
      | glance | glance | True | glance@lab.com |
      | heat | heat | True | heat@lab.com |
      | heat-cfn | heat-cfn | True | heat-cfn@lab.com |
      | neutron | neutron | True | neutron@lab.com |
      | nova | nova | True | nova@lab.com |
      | ospadmin | ospadmin | True | ospadmin@lab.com |
      | sahara | sahara | True | sahara@lab.com |
      | swift | swift | True | swift@lab.com |
      | trove | trove | True | trove@lab.com |
      +————+————+———+——————–+

      Like

  2. Hi Keith,

    Nice explanation, I was struggling with how to add all the services as system accounts. I’m trying to scripts this, but as you kinit every service user, a bit troublesome.

    But…lol, being a little bit of a ldap noob, why us the only user that is not in the enabled_users group is the user “openstack Ldap” the (keystone admin/system user)? Can you elaborate as to why? Can service users like “glance” just not only belong to the systems-accounts group?

    Btw using packstack, rdo-mitaka, keystone v3 (well trying lol) multiple domains approach, fedora 23 (yes, doing it the hard way, selinux enabled and other fun stuff), and freeipa 4.2 of course. All in vm’s of course.

    Thanks,

    Sjors

    Like

    • Hi,

      My LDAP example is very basic and simple. There are two groups because services like keystone, glance, etc you want to disable password expiration where as normal users that is ok.

      Regards,

      Keith

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s