Consolidate LDAP documentation into admin-guide

This commit merges two documents that were both attempting to
document integrating keystone with LDAP. Instead, we should have a
single document so that it's easier to operators to understand and
find.

Change-Id: I1b1927b498d93f39d57a03b60384de22f07ad2f2
This commit is contained in:
Lance Bragstad 2017-06-27 15:57:07 +00:00
parent bcae07ebdc
commit c1e9c97d33
2 changed files with 107 additions and 375 deletions

View File

@ -12,7 +12,8 @@ for use with Keystone <https://wiki.openstack.org/wiki/OpenLDAP>`__.
When the OpenStack Identity service is configured to use LDAP back ends,
you can split authentication (using the *identity* feature) and
authorization (using the *assignment* feature).
authorization (using the *assignment* feature). OpenStack Identity only
supports read-only LDAP integration.
The *identity* feature enables administrators to manage users and groups
by each domain or the OpenStack Identity service entirely.
@ -21,6 +22,15 @@ The *assignment* feature enables administrators to manage project role
authorization using the OpenStack Identity service SQL database, while
providing user authentication through the LDAP directory.
.. NOTE::
It is possible to isolate identity related information to LDAP in a
deployment and keep resource information in a separate datastore. It is not
possible to do the opposite, where resource information is stored in LDAP
and identity information is stored in SQL. If the resource or assignment
back ends are integrated with LDAP, the identity back end must also be
integrated with LDAP.
.. _identity_ldap_server_setup:
Identity LDAP server set up
@ -47,8 +57,7 @@ examples. Modify these examples as needed.
**To define the destination LDAP server**
#. Define the destination LDAP server in the
``/etc/keystone/keystone.conf`` file:
Define the destination LDAP server in the ``/etc/keystone/keystone.conf`` file:
.. code-block:: ini
@ -58,6 +67,16 @@ examples. Modify these examples as needed.
password = samplepassword
suffix = dc=example,dc=org
Multiple LDAP servers can be supplied to ``url`` to provide high-availability
support for a single LDAP backend. To specify multiple LDAP servers, simply
change the ``url`` option in the ``[ldap]`` section to be a list, separated by
commas:
.. code-block:: ini
url = "ldap://localhost,ldap://backup.localhost"
**Additional LDAP integration settings**
Set these options in the ``/etc/keystone/keystone.conf`` file for a
@ -94,15 +113,25 @@ A value of zero means that debugging is not enabled.
.. code-block:: ini
[ldap]
debug_level = 0
debug_level = 4095
.. warning::
This setting sets ``OPT_DEBUG_LEVEL`` in the underlying python library. This
field is a bit mask (integer), and the possible flags are documented in the
OpenLDAP manpages. Commonly used values include 255 and 4095, with 4095 being
more verbose and 0 being disabled. We recommend consulting the documentation
for your LDAP back end when using this option.
This value is a bitmask, consult your LDAP documentation for
possible values.
.. WARNING::
Enabling ``debug_level`` will negatively impact performance.
**Connection pooling**
Various LDAP back ends use a common LDAP module to interact with LDAP data. By
default, a new connection is established for each LDAP operation. This is
expensive when TLS support is enabled, which is a likely configuration in an
enterprise setup. Reusing connections from a connection pool drastically
reduces overhead of initiating a new connection for every LDAP operation.
Use ``use_pool`` to enable LDAP connection pooling. Configure the
connection pool size, maximum retry, reconnect trials, timeout (-1
indicates indefinite wait) and lifetime in seconds.
@ -119,9 +148,16 @@ indicates indefinite wait) and lifetime in seconds.
**Connection pooling for end user authentication**
LDAP user authentication is performed via an LDAP bind operation. In large
deployments, user authentication can use up all available connections in a
connection pool. OpenStack Identity provides a separate connection pool
specifically for user authentication.
Use ``use_auth_pool`` to enable LDAP connection pooling for end user
authentication. Configure the connection pool size and lifetime in
seconds.
authentication. Configure the connection pool size and lifetime in seconds.
Both ``use_pool`` and ``use_auth_pool`` must be enabled to pool connections for
user authentication.
.. code-block:: ini
@ -188,21 +224,6 @@ administrators to use users and groups in LDAP.
user_objectclass = person
#. A read-only implementation is recommended for LDAP integration. These
permissions are applied to object types in the
``/etc/keystone/keystone.conf`` file:
.. code-block:: ini
[ldap]
user_allow_create = False
user_allow_update = False
user_allow_delete = False
group_allow_create = False
group_allow_update = False
group_allow_delete = False
Restart the OpenStack Identity service.
.. warning::
@ -290,21 +311,6 @@ administrators to use users and groups in LDAP.
user_objectclass = person
#. A read-only implementation is recommended for LDAP integration. These
permissions are applied to object types in the
``/etc/keystone/domains/keystone.DOMAIN_NAME.conf`` file:
.. code-block:: ini
[ldap]
user_allow_create = False
user_allow_update = False
user_allow_delete = False
group_allow_create = False
group_allow_update = False
group_allow_delete = False
#. Restart the OpenStack Identity service.
.. warning::
@ -359,18 +365,57 @@ Identity attribute mapping
group_desc_attribute = description
group_additional_attribute_mapping =
Enabled emulation
An alternative method to determine if a user is enabled or not is by
checking if that user is a member of the emulation group.
Use DN of the group entry to hold enabled user when using enabled
emulation.
It is possible to model more complex LDAP schemas. For example, in the user
object, the objectClass posixAccount from `RFC2307 <https://tools.ietf.org/html/rfc2307>`_
is very common. If this is the underlying objectClass, then the ``uid``
field should probably be ``uidNumber`` and the ``username`` field should be
either ``uid`` or ``cn``. The following illustrates the configuration:
.. code-block:: ini
[ldap]
user_enabled_emulation = false
user_enabled_emulation_dn = false
user_id_attribute = uidNumber
user_name_attribute = cn
Enabled emulation
OpenStack Identity supports emulation for integrating with LDAP servers that
do not provide an ``enabled`` attribute for users. This allows OpenStack
Identity to advertise ``enabled`` attributes when the user entity in LDAP
does not. The ``user_enabled_emulation`` option must be enabled and the
``user_enabled_emulation_dn`` option must be a valid LDAP group. Users in
the group specified by ``user_enabled_emulation_dn`` will be marked as
``enabled``. For example, the following will mark any user who is a member
of the ``enabled_users`` group as enabled:
.. code-block:: ini
[ldap]
user_enabled_emulation = True
user_enabled_emulation_dn = cn=enabled_users,cn=groups,dc=openstack,dc=org
If the directory server has an enabled attribute, but it is not a boolean
type, a mask can be used to convert it. This is useful when the enabled
attribute is an integer value. The following configuration highlights the
usage:
.. code-block:: ini
[ldap]
user_enabled_attribute = userAccountControl
user_enabled_mask = 2
user_enabled_default = 512
In this case, the attribute is an integer and the enabled attribute is
listed in bit 1. If the mask configured ``user_enabled_mask`` is different
from 0, it retrieves the attribute from ``user_enabled_attribute`` and
performs an add operation with the ``user_enabled_mask``. If the sum of the
operation matches the mask, then the account is disabled.
The value of ``user_enabled_attribute`` is also saved before applying the
add operation in ``enabled_nomask``. This is done in case the user needs to
be enabled or disabled. Lastly, setting ``user_enabled_default`` is needed
in order to create a default value on the integer attribute (512 = NORMAL
ACCOUNT in Active Directory).
When you have finished configuration, restart the OpenStack Identity
service.
@ -383,10 +428,11 @@ service.
Secure the OpenStack Identity service connection to an LDAP back end
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Identity service supports the use of TLS to encrypt LDAP traffic.
Before configuring this, you must first verify where your certificate
authority file is located. For more information, see the
`OpenStack Security Guide SSL introduction <https://docs.openstack.org/
We recommend securing all connections between OpenStack Identity and LDAP. The
Identity service supports the use of TLS to encrypt LDAP traffic. Before
configuring this, you must first verify where your certificate authority file
is located. For more information, see the `OpenStack Security Guide SSL
introduction <https://docs.openstack.org/
security-guide/secure-communication/introduction-to-ssl-and-tls.html>`_.
Once you verify the location of your certificate authority file:
@ -431,6 +477,16 @@ Once you verify the location of your certificate authority file:
normal.
* ``never`` - A certificate will never be requested.
When you have finished configuration, restart the OpenStack Identity
service.
.. NOTE::
If you are unable to connect to LDAP via OpenStack Identity, or observe a
*SERVER DOWN* error, set the ``TLS_CACERT`` in ``/etc/ldap/ldap.conf`` to
the same value specified in the ``[ldap] tls_certificate`` section of
``keystone.conf``.
On distributions that include openstack-config, you can configure TLS
encryption on LDAP traffic by running the following commands instead.

View File

@ -1508,330 +1508,6 @@ can be invoked as follows:
$ openstack --os-username=admin --os-password=secret --os-project-name=admin --os-auth-url=http://localhost:35357/v2.0 project create demo
Using an LDAP server
====================
As an alternative to the SQL Database backing store, keystone can use a
directory server to provide the Identity service. An example schema for
OpenStack would look like this::
dn: dc=openstack,dc=org
dc: openstack
objectClass: dcObject
objectClass: organizationalUnit
ou: openstack
dn: ou=Groups,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: groups
dn: ou=Users,dc=openstack,dc=org
objectClass: top
objectClass: organizationalUnit
ou: users
The corresponding entries in the keystone configuration file are:
.. code-block:: ini
[ldap]
url = ldap://localhost
user = dc=Manager,dc=openstack,dc=org
password = badpassword
suffix = dc=openstack,dc=org
user_tree_dn = ou=Users,dc=openstack,dc=org
user_objectclass = inetOrgPerson
The default object classes and attributes are intentionally simplistic. They
reflect the common standard objects according to the LDAP RFCs. However, in a
live deployment, the correct attributes can be overridden to support a
preexisting, more complex schema. For example, in the user object, the
objectClass posixAccount from RFC2307 is very common. If this is the underlying
objectclass, then the *uid* field should probably be *uidNumber* and *username*
field either *uid* or *cn*. To change these two fields, the corresponding
entries in the keystone configuration file are:
.. code-block:: ini
[ldap]
user_id_attribute = uidNumber
user_name_attribute = cn
There are some configuration options for filtering users, tenants and roles, if
the backend is providing too much output, in such case the configuration will
look like:
.. code-block:: ini
[ldap]
user_filter = (memberof=CN=openstack-users,OU=workgroups,DC=openstack,DC=org)
In case that the directory server does not have an attribute enabled of type
boolean for the user, there is several configuration parameters that can be
used to extract the value from an integer attribute like in Active Directory:
.. code-block:: ini
[ldap]
user_enabled_attribute = userAccountControl
user_enabled_mask = 2
user_enabled_default = 512
In this case the attribute is an integer and the enabled attribute is listed in
bit 1, so the if the mask configured *user_enabled_mask* is different from 0,
it gets the value from the field *user_enabled_attribute* and it makes an ADD
operation with the value indicated on *user_enabled_mask* and if the value
matches the mask then the account is disabled.
It also saves the value without mask to the user identity in the attribute
*enabled_nomask*. This is needed in order to set it back in case that we need
to change it to enable/disable a user because it contains more information than
the status like password expiration. Last setting *user_enabled_mask* is needed
in order to create a default value on the integer attribute (512 = NORMAL
ACCOUNT on AD)
In case of Active Directory the classes and attributes could not match the
specified classes in the LDAP module so you can configure them like:
.. code-block:: ini
[ldap]
user_objectclass = person
user_id_attribute = cn
user_name_attribute = cn
user_description_attribute = displayName
user_mail_attribute = mail
user_enabled_attribute = userAccountControl
user_enabled_mask = 2
user_enabled_default = 512
user_attribute_ignore = tenant_id,tenants
Debugging LDAP
--------------
For additional information on LDAP connections, performance (such as slow
response time), or field mappings, setting ``debug_level`` in the [ldap]
section is used to enable debugging:
.. code-block:: ini
debug_level = 4095
This setting in turn sets OPT_DEBUG_LEVEL in the underlying python library.
This field is a bit mask (integer), and the possible flags are documented in
the OpenLDAP manpages. Commonly used values include 255 and 4095, with 4095
being more verbose.
.. WARNING::
Enabling ``debug_level`` will negatively impact performance.
Enabled Emulation
-----------------
Some directory servers do not provide any enabled attribute. For these servers,
the ``user_enabled_emulation`` attribute has been created. It is enabled by
setting the respective flags to True. Then the attribute
``user_enabled_emulation_dn`` may be set to specify how the enabled users are
selected. This attribute works by using a ``groupOfNames`` entry and adding
whichever users or that you want enabled to the respective group with the
``member`` attribute. For example, this will mark any user who is a member of
``enabled_users`` as enabled:
.. code-block:: ini
[ldap]
user_enabled_emulation = True
user_enabled_emulation_dn = cn=enabled_users,cn=groups,dc=openstack,dc=org
The default values for user enabled emulation DN is
``cn=enabled_users,$user_tree_dn``.
If a different LDAP schema is used for group membership, it is possible to use
the ``group_objectclass`` and ``group_member_attribute`` attributes to
determine membership in the enabled emulation group by setting the
``user_enabled_emulation_use_group_config`` attribute to True.
Secure Connection
-----------------
If you are using a directory server to provide the Identity service, it is
strongly recommended that you utilize a secure connection from keystone to the
directory server. In addition to supporting LDAP, keystone also provides
Transport Layer Security (TLS) support. There are some basic configuration
options for enabling TLS, identifying a single file or directory that contains
certificates for all the Certificate Authorities that the keystone LDAP client
will recognize, and declaring what checks the client should perform on server
certificates. This functionality can easily be configured as follows:
.. code-block:: ini
[ldap]
use_tls = True
tls_cacertfile = /etc/keystone/ssl/certs/cacert.pem
tls_cacertdir = /etc/keystone/ssl/certs/
tls_req_cert = demand
A few points worth mentioning regarding the above options. If both
``tls_cacertfile`` and ``tls_cacertdir`` are set then tls_cacertfile will be
used and ``tls_cacertdir`` is ignored. Furthermore, valid options for
``tls_req_cert`` are ``demand``, ``never``, and ``allow``. These correspond to
the standard options permitted by the ``TLS_REQCERT`` TLS option.
.. NOTE::
If unable to connect to LDAP via keystone (more specifically, if a
*SERVER DOWN* error is seen), set the ``TLS_CACERT`` in
``/etc/ldap/ldap.conf`` to the same value specified in the
``[ldap] tls_certificate`` section of ``keystone.conf``.
Read Only LDAP
--------------
Many environments typically have user and group information in directories that
are accessible by LDAP. This information is for read-only use in a wide array
of applications. Prior to the Havana release, we could not deploy keystone with
read-only directories as backends because keystone also needed to store
information such as projects, roles, domains and role assignments into the
directories in conjunction with reading user and group information.
Keystone now provides an option whereby these read-only directories can be
easily integrated as it now enables its identity entities (which comprises
users, groups, and group memberships) to be served out of directories while
resource (which comprises projects and domains), assignment and role
entities are to be served from different keystone backends (i.e. SQL). To
enable this option, you must have the following ``keystone.conf`` options set:
.. code-block:: ini
[identity]
driver = ldap
[resource]
driver = sql
[assignment]
driver = sql
[role]
driver = sql
With the above configuration, keystone will only lookup identity related
information such users, groups, and group membership from the directory, while
resources, roles and assignment related information will be provided by the SQL
backend. Also note that if there is an LDAP Identity, and no resource,
assignment or role backend is specified, they will default to LDAP. Although
this may seem counter intuitive, it is provided for backwards compatibility.
Nonetheless, the explicit option will always override the implicit option, so
specifying the options as shown above will always be correct.
.. NOTE::
While having identity related information backed by LDAP while other
information is backed by SQL is a supported configuration, as shown above;
the opposite is not true. If either resource or assignment drivers are
configured for LDAP, then Identity must also be configured for LDAP.
Connection Pooling
------------------
Various LDAP backends in keystone use a common LDAP module to interact with
LDAP data. By default, a new connection is established for each LDAP operation.
This can become highly expensive when TLS support is enabled, which is a likely
configuration in an enterprise setup. Reuse of connectors from a connection
pool drastically reduces overhead of initiating a new connection for every LDAP
operation.
Keystone provides connection pool support via configuration. This will keep
LDAP connectors alive and reused for subsequent LDAP operations. The connection
lifespan is configurable as other pooling specific attributes.
In the LDAP identity driver, keystone authenticates end users via an LDAP bind
with the user's DN and provided password. This kind of authentication bind
can fill up the pool pretty quickly, so a separate pool is provided for end
user authentication bind calls. If a deployment does not want to use a pool for
those binds, then it can disable pooling selectively by setting
``use_auth_pool`` to false. If a deployment wants to use a pool for those
authentication binds, then ``use_auth_pool`` needs to be set to true. For the
authentication pool, a different pool size (``auth_pool_size``) and connection
lifetime (``auth_pool_connection_lifetime``) can be specified. With an enabled
authentication pool, its connection lifetime should be kept short so that the
pool frequently re-binds the connection with the provided credentials and works
reliably in the end user password change case. When ``use_pool`` is false
(disabled), then the authentication pool configuration is also not used.
Connection pool configuration is part of the ``[ldap]`` configuration section:
.. code-block:: ini
[ldap]
# Enable LDAP connection pooling for queries to the LDAP server. There is
# typically no reason to disable this. (boolean value)
use_pool = true
# The size of the LDAP connection pool. This option has no effect unless
# `[ldap] use_pool` is also enabled. (integer value)
# Minimum value: 1
pool_size = 10
# The maximum number of times to attempt reconnecting to the LDAP server before
# aborting. A value of zero prevents retries. This option has no effect unless
# `[ldap] use_pool` is also enabled. (integer value)
# Minimum value: 0
pool_retry_max = 3
# The number of seconds to wait before attempting to reconnect to the LDAP
# server. This option has no effect unless `[ldap] use_pool` is also enabled.
# (floating point value)
pool_retry_delay = 0.1
# The connection timeout to use with the LDAP server. A value of `-1` means
# that connections will never timeout. This option has no effect unless `[ldap]
# use_pool` is also enabled. (integer value)
# Minimum value: -1
pool_connection_timeout = -1
# The maximum connection lifetime to the LDAP server in seconds. When this
# lifetime is exceeded, the connection will be unbound and removed from the
# connection pool. This option has no effect unless `[ldap] use_pool` is also
# enabled. (integer value)
# Minimum value: 1
pool_connection_lifetime = 600
# Enable LDAP connection pooling for end user authentication. There is
# typically no reason to disable this. (boolean value)
use_auth_pool = true
# The size of the connection pool to use for end user authentication. This
# option has no effect unless `[ldap] use_auth_pool` is also enabled. (integer
# value)
# Minimum value: 1
auth_pool_size = 100
# The maximum end user authentication connection lifetime to the LDAP server in
# seconds. When this lifetime is exceeded, the connection will be unbound and
# removed from the connection pool. This option has no effect unless `[ldap]
# use_auth_pool` is also enabled. (integer value)
# Minimum value: 1
auth_pool_connection_lifetime = 60
Specifying Multiple LDAP servers
--------------------------------
Multiple LDAP server URLs can be provided to keystone to provide
high-availability support for a single LDAP backend. To specify multiple LDAP
servers, simply change the ``url`` option in the ``[ldap]`` section. The new
option should list the different servers, each separated by a comma. For
example:
.. code-block:: ini
[ldap]
url = "ldap://localhost,ldap://backup.localhost"
Credential Encryption
=====================