Configuring an LDAP Realm

A secure Elasticsearch cluster can authenticate users from a Lightweight Directory Access Protocol (LDAP) directory. With LDAP Authentication, you can assign roles to LDAP groups. When a user authenticates with LDAP, the privileges for that user are the union of all privileges defined by the roles assigned to the set of groups that the user belongs to.

This section discusses configuration for an LDAP Realm.

LDAP Overview

LDAP stores users and groups hierarchically, similar to the way folders are grouped in a file system. The path to any entry is a Distinguished Name, or DN. A DN uniquely identifies a user or group. User and group names typically use attributes such as common name (cn) or unique ID (uid). An LDAP directory’s hierarchy is built from containers such as the organizational unit (ou), organization (o), or domain controller (dc).

LDAP ignores white space in a DN definition. The following two DNs are equivalent:

"cn=admin,dc=example,dc=com"
"cn =admin ,dc= example , dc = com"

Although optional, connections to the LDAP server should use the Secure Sockets Layer (SSL/TLS) protocol to protect passwords. Clients and nodes that connect via SSL/TLS to the LDAP server require the certificate or the root CA for the server. These certificates should be put into each node’s keystore/truststore.

LDAP Realm Settings

Like all realms, the ldap realm is configured under the shield.authc.realms settings namespace in the elasticsearch.yml file. The LDAP realm supports two modes of operation, a user search mode and a mode with specific templates for user DNs.

LDAP Realm with User Search [1.1.0] Added in 1.1.0.

A LDAP user search is the most common mode of operation. In this mode, a specific user with permission to search the LDAP is used to seach for the user DN based on the username and a LDAP attribute. The following snippet shows an example of such configuration:

Example LDAP Realm Configuration with User Search. 

shield:
  authc:
    realms:
      ldap1:
        type: ldap
        order: 0
        url: "ldaps://ldap.example.com:636"
        bind_dn: "cn=ldapuser, ou=users, o=services, dc=example, dc=com"
        bind_password: changeme
        user_search:
          base_dn: "dc=example,dc=com"
          attribute: cn
        group_search:
          base_dn: "dc=example,dc=com"
        files:
          role_mapping: "/mnt/elasticsearch/group_to_role_mapping.yml"
        unmapped_groups_as_roles: false

LDAP Realm with User DN Templates

User DN templates can be specified if your LDAP environment uses a few specific standard naming conditions for users. The advantage of this method is that a search is not needed to find the user DN; conversely the disadvantage is multiple bind operations may be needed to find the right user DN. The following snippet shows an example of such configuration:

Example LDAP Realm Configuration with User DN Templates. 

shield:
  authc:
    realms:
      ldap1:
        type: ldap
        order: 0
        url: "ldaps://ldap.example.com:636"
        user_dn_templates:
          - "cn={0}, ou=users, o=marketing, dc=example, dc=com"
          - "cn={0}, ou=users, o=engineering, dc=example, dc=com"
        group_search:
          base_dn: "dc=example,dc=com"
        files:
          role_mapping: "/mnt/elasticsearch/group_to_role_mapping.yml"
        unmapped_groups_as_roles: false

Table 2. Common LDAP Realm Settings

Setting

Required

Description

type

yes

Indicates the realm type. Must be set to ldap.

order

no

Indicates the priority of this realm within the realm chain. Realms with a lower order are consulted first. Although not required, we recommend explicitly setting this value when you configure multiple realms. Defaults to Integer.MAX_VALUE.

enabled

no

Indicates whether this realm is enabled or disabled. Enables you to disable a realm without removing its configuration. Defaults to true.

url

yes

Specifies an LDAP URL of the form of ldap[s]://<server>:<port>. Shield attempts to authenticate against this URL.

user_group_attribute

no

Specifies the attribute to examine on the user for group membership. The default is memberOf. This setting will be ignored if any group_search settings are specified.

group_search.base_dn

no

Specifies a container DN to search for groups in which the user has membership. When this element is absent, Shield searches for the attribute specified by user_group_attribute set on the user to determine group membership.

group_search.scope

no

Specifies whether the group search should be sub_tree, one_level or base. one_level only searches objects directly contained within the base_dn. The default sub_tree searches all objects contained under base_dn. base specifies that the base_dn is a group object, and that it is the only group considered.

group_search.filter

no

Specifies a filter to use to lookup a group. If not set, the realm searches for group, groupOfNames, or groupOfUniqueNames, with the attributes member or memberOf. Any instance of {0} in the filter is replaced by the user attribute defined in group_search.user_attribute

group_search.user_attribute

no

Specifies the user attribute that is fetched and provided as a parameter to the filter. If not set, the user DN is passed to the filter.

unmapped_groups_as_roles

no

Specifies whether the names of any unmapped LDAP groups should be used as role names and assigned to the user. Defaults to false.

connect_timeout

no

Specifies the timeout period for establishing an LDAP connection. An s at the end indicates seconds, ms indicates milliseconds. Defaults to 5s (5 seconds).

read_timeout

no

The timeout period for an LDAP operation. An s at the end indicates seconds, ms indicates milliseconds. Defaults to 5s (5 seconds).

files.role_mapping

no

Specifies the path and file name for the YAML role mapping configuration file. Defaults to ES_HOME/config/shield/role_mapping.yml.

follow_referrals

no

Specifies whether Shield should follow referrals returned by the LDAP server. Referrals are URLs returned by the server that are to be used to continue the LDAP operation (e.g. search). Defaults to true.

hostname_verification

no

Specifies whether hostname verification is performed when connecting to an LDAP server. When true, the hostname or IP address used in the url must match one of the names in the certificate or the connection will not be allowed. Due to its potential security impact, hostname_verification is not exposed via the nodes info API. Defaults to true.

cache.ttl

no

Specifies the time-to-live for cached user entries. A user’s credentials are cached for this period of time. Specify the time period using the standard Elasticsearch time units. Defaults to 20m.

cache.max_users

no

Specifies the maximum number of user entries that can be stored in the cache at one time. Defaults to 100,000.

cache.hash_algo

no

Specifies the hashing algorithm that is used for the cached user credentials. See Cache hash algorithms for the possible values. (Expert Setting)


Table 3. User Template LDAP Realm Settings

Setting

Required

Description

user_dn_templates

yes

Specifies the DN template that replaces the user name with the string {0}. This element is multivalued, allowing for multiple user contexts.


Table 4. User Search LDAP Realm Settings [1.1.0] Added in 1.1.0.

Setting

Required

Description

bind_dn

no

The DN of the user that will be used to bind to the LDAP and perform searches. If this is not specified, an anonymous bind will be attempted.

bind_password

no

The password for the user that will be used to bind to the LDAP.

user_search.base_dn

yes

Specifies a container DN to search for users.

user_search.scope

no

The scope of the user search. Valid values are sub_tree, one_level or base. one_level only searches objects directly contained within the base_dn. The default sub_tree searches all objects contained under base_dn. base specifies that the base_dn is the user object, and that it is the only user considered.

user_search.attribute

no

The attribute to match with the username presented to Shield. The default attribute is uid

user_search.pool.size

no

The maximum number of connections to the LDAP server to allow in the connection pool. Default is 20.

user_search.pool.initial_size

no

The initial number of connections to create to the LDAP server on startup. Default is 5.

user_search.pool.health_check.enabled

no

Flag to enable or disable a health check on LDAP connections in the connection pool. Connections will be checked in the background at the specified interval. Default is true

user_search.pool.health_check.dn

no

The distinguished name to be retrieved as part of the health check. Default is the value of bind_dn. If bind_dn is not specified, a value must be specified.

user_search.pool.health_check.interval

no

The interval to perform background checks of connections in the pool. Default is 60s.


Note

If any settings starting with user_search are specified the user_dn_templates setting is ignored.

Note

bind_dn, bind_password and hostname_verification are considered to be senstivie settings and therefore are not exposed via nodes info API.

Adding an LDAP server certificate

To use SSL/TLS to access your LDAP server over an URL with the ldaps protocol, make sure the LDAP client used by Shield can access the certificate of the CA that signed the LDAP server’s certificate. This enables Shield’s LDAP client to authenticate the LDAP server before sending any passwords to it.

To do this, first obtain a certificate for the LDAP servers or a CA certificate that has signed the LDAP certificate. You can use the openssl command to fetch the certificate and add the certificate to the ldap.crt file, as in the following Unix example:

echo | openssl s_client -connect ldap.example.com:636 2>/dev/null | openssl x509 > ldap.crt
Note

Older versions of openssl might not have the -connect option. Instead use the -host and -port options.

This certificate needs to be stored in the node keystore/truststore. Import the certificate into the truststore with the following command, providing the password for the keystore when prompted.

keytool -import -keystore node01.jks -file ldap.crt

If not already configured, add the path of the keystore/truststore to elasticsearch.yml as described in Securing Communications with Encryption and IP Filtering. By default, Shield will attempt to verify the hostname or IP address used in the url with the values in the certificate. If the values in the certificate do not match, Shield will not allow a connection to the LDAP server. This behavior can be disabled by setting the hostname_verification property.

Restart Elasticsearch to pick up the changes to elasticsearch.yml.

Note

hostname_verification is considered to be a senstivie setting and therefore is not exposed via nodes info API.

User Cache

To avoid connecting to the LDAP server for every incoming request, the users and their credentials are cached locally on each node. This is a common practice when authenticating against remote servers and as can be seen in the table above, the characteristics of this cache are configurable.

The cached user credentials are hashed in memory, and there are several hash algorithms to choose from:

Table 5. Cache hash algorithms

Algorithm

Description

ssha256

Uses a salted SHA-256 algorithm (default).

md5

Uses MD5 algorithm.

sha1

Uses SHA1 algorithm.

bcrypt

Uses bcrypt algorithm with salt generated in 10 rounds.

bcrypt4

Uses bcrypt algorithm with salt generated in 4 rounds.

bcrypt5

Uses bcrypt algorithm with salt generated in 5 rounds.

bcrypt6

Uses bcrypt algorithm with salt generated in 6 rounds.

bcrypt7

Uses bcrypt algorithm with salt generated in 7 rounds.

bcrypt8

Uses bcrypt algorithm with salt generated in 8 rounds.

bcrypt9

Uses bcrypt algorithm with salt generated in 9 rounds.

sha2

Uses SHA2 algorithm.

apr1

Uses apr1 algorithm (md5 crypt).

noop,clear_text

Doesn’t hash the credentials and keeps it in clear text in memory. CAUTION: keeping clear text is considered insecure and can be compromised at the OS level (e.g. memory dumps and ptrace).


Cache Eviction API

Shield exposes an API to force cached user eviction. The following example, evicts all users from the ldap1 realm:

$ curl -XPOST 'http://localhost:9200/_shield/realm/ldap1/_cache/clear'

It is also possible to evict specific users:

$ curl -XPOST 'http://localhost:9200/_shield/realm/ldap1/_cache/clear?usernames=rdeniro,alpacino'

Multiple realms can also be specified using comma-delimited list:

$ curl -XPOST 'http://localhost:9200/_shield/realm/ldap1,ldap2/_cache/clear'