Secure your 7.x clusters with LDAP

These steps show how you can secure your 7.x Elasticsearch clusters and Kibana instances with the Lightweight Directory Access Protocol (LDAP) using an LDAP server.

Note

For version 5.x and 6.x, see Secure your 5.x and 6.x clusters with LDAP.

Before you begin

To learn more about how securing Elasticsearch clusters with LDAP works, see LDAP User Authentication.

Note

The LDAP credentials are valid against the deployment, not the ECE platform. You can configure role-based access control for the platform separately.

Configure authentication with LDAP

You can configure the deployment to authenticate users by communicating with an LDAP server. To integrate with LDAP, you need to configure an ldap realm and map LDAP groups to user roles in Elasticsearch.

  1. Determine which mode you want to use. The ldap realm supports two modes of operation, a user search mode and and a mode with specific templates for user DNs.

    LDAP user search is the most common mode of operation. In this mode, a specific user with permission to search the LDAP directory is used to search for the DN of the authenticating user based on the provided username and an LDAP attribute. Once found, the user is authenticated by attempting to bind to the LDAP server using the found DN and the provided password.

    If your LDAP environment uses a few specific standard naming conditions for users, you can use user DN templates to configure the realm. The advantage of this method is that a search does not have to be performed to find the user DN. However, multiple bind operations might be needed to find the correct user DN.

  2. To configure an LDAP realm with user search, add your user settings for the ldap realm as follows:

    xpack:
      security:
        authc:
          realms:
            ldap:
              ldap1:
                order: 2 
                url: "ldap://ldap.example.com:389" 
                bind_dn: "cn=ldapuser, ou=users, o=services, dc=example, dc=com" 
                user_search:
                  base_dn: "ou=users, o=services, dc=example, dc=com" 
                  filter: "(cn={0})" 
                group_search:
                  base_dn: ou=groups, o=services, dc=example, dc=com" 

    The order in which the LDAP realm will be consulted during an authentication attempt.

    The LDAP URL pointing to the LDAP server that should handle authentication. If your LDAP server is configured to use LDAP over TLS and it uses a self-signed certificate or a certificate that is signed by your organization’s CA, see below for configuration instructions

    The DN of the bind user.

    The base DN under which your users are located in LDAP.

    Optionally specify an additional LDAP filter used to search the directory in attempts to match an entry with the username provided by the user. Defaults to (uid={0}). {0} is substituted with the username provided by the user for authentication.

    The base DN under which groups are located in LDAP.

  3. The password for the bind_dn user should be configured by adding the appropriate secure_bind_password setting to the Elasticsearch keystore.

    1. From the Deployments page, select your deployment.

      Narrow the list by name, ID, or choose from several other filters. To further define the list, use a combination of filters.

    2. From your deployment menu, select Security.
    3. Under the Elasticsearch Keystore section, click Create settings.
    4. On the Create setting window, select the secret Type to be Secret String.
    5. Set the Setting name` to xpack.security.authc.realms.ldap.ldap1.secure_bind_password and add the password for the bind_dn user in the secret field.

      Note

      After you configure secure_bind_password, any attempt to restart the deployment will fail until you complete the rest of the configuration steps. If you wish to rollback the LDAP realm related configuration effort, you need to remove the xpack.security.authc.realms.ldap.ldap1.secure_bind_password that was just added by clicking on the "remove" button by the setting name under Existing Keystores.

  4. Alternatively, to configure an LDAP realm with user user DN templates, add your user settings for the ldap realm as follows:

    xpack:
      security:
        authc:
          realms:
            ldap:
              ldap1:
                order: 2 
                url: "ldap://ldap.example.com:389" 
                user_dn_templates: 
                group_search:
                  base_dn: ou=groups, o=services, dc=example, dc=com" 

    The order in which the LDAP realm will be consulted during an authentication attempt.

    The LDAP URL pointing to the LDAP server that should handle authentication. If your LDAP server is configured to use LDAP over TLS and it uses a self-signed certificate or a certificate that is signed by your organization’s CA, see below see below for configuration instructions

    The templates that should be tried for constructing the user DN and authenticating to LDAP. If a user attempts to authenticate with username user1 and password password1, authentication will be attempted with the DN uid=user1, ou=users, o=engineering, dc=example, dc=com and if not successful, also with uid=user1, ou=users, o=marketing, dc=example, dc=com and the given password. If authentication with one of the constructed DNs is successful, all subsequent LDAP operations are run with this user.

    The base DN under which groups are located in LDAP.

  5. (Optional) Encrypt communications between the deployment and the LDAP Server. If your LDAP server uses a self-signed certificate or a certificate that is signed by your organization’s CA, you need to enable the deployment to trust this certificate.

    1. Prepare a custom bundle as a ZIP file that contains the CA certificate file (for example ca.crt) inside of a cacerts folder` in the same way that you would on Elastic Cloud.
    2. Update your plan in the advanced configuration editor so that it uses the bundle you prepared in the previous step. You need to modify the user_bundles JSON attribute similar to the following example:

      {
      "cluster_name": "REPLACE_WITH_YOUR_CLUSTER_NAME",
      "plan": {
      
          ...
      
          "elasticsearch": {
            "version": "7.*",
            "user_bundles": [
              {
                "name": "ldap-cert",
                "url": "https://www.myurl.com/ldapcert.zip",
                "elasticsearch_version": "7.*"
              }
            ]
          }
        }
      Note

      The URL that point to ldapcert.zip must be accessible to the cluster. Also, when you * a minor versions bundles are compatible with any Elasticsearch major version to avoid a need to re-upload a new bundle with minor versions upgrade. In this example the bundle is compatible with any Elasticsearch 7.* version.

    3. Custom bundles get unzipped under the path /app/config/BUNDLE_DIRECTORY_STRUCTURE, where BUNDLE_DIRECTORY_STRUCTURE is the directory structure within the bundle ZIP file itself. For example:

      $ tree .
      .
      └── cacerts
            └── ca.crt

      So in our example, the unzipped keystore file gets placed under /app/config/cacerts/ca.crt

    4. Update your user settings for the ldap realm as follows

      xpack:
        security:
          authc:
            realms:
              ldap:
                ldap1:
                  order: 2
                  url: "ldaps://ldap.example.com:636" 
                  bind_dn: "cn=ldapuser, ou=users, o=services, dc=example, dc=com"
                  user_search:
                    base_dn: "ou=users, o=services, dc=example, dc=com"
                  group_search:
                    base_dn: ou=groups, o=services, dc=example, dc=com"
                  ssl:
                    verification_mode: certificate 
                    certificate_authorities: ["/app/config/cacerts/ca.crt"]

      The ldaps URL pointing to the LDAP server.

      (Optional) By default, when you configure Elasticsearch to connect to an LDAP server using SSL/TLS, it attempts to verify the hostname or IP address specified with the url attribute in the realm configuration with the values in the certificate. If the values in the certificate and realm configuration do not match, Elasticsearch does not allow a connection to the LDAP server. This is done to protect against man-in-the-middle attacks. If necessary, you can disable this behavior by setting the ssl.verification_mode property to certificate.

Note

If your CA certificate is available as a JKS or PKCS#12 keystore, you can upload that file in the ZIP bundle ( for example create a ZIP archive from a truststore folder that contains a file named ca.jks) and then reference it in the user settings with xpack.security.authc.realms.ldap.ldap1.ssl.truststore.path: "/app/config/truststore/ca.jks". If the keystore is also password protected ( which is unusual for keystores that contain only CA certificates ), you can also provide the password for the keystore by adding xpack.security.authc.realms.ldap.ldap1.ssl.truststore.password: password in the user settings.

Mapping LDAP groups to roles

You have two ways of mapping LDAP groups to roles for your users. The preferred one is to use the Role Mapping API. If for some reason this is not possible, you can use a role mapping file to specify the mappings instead.

Using the Role Mapping API

Let’s assume that you want all your users that authenticate via LDAP to have read only access to a certain index my-index and the LDAP users that are members of the `cn=administrators, ou=groups, o=services, dc=example, dc=com" group in LDAP, to become superusers in your deployment:

  1. Create the read-only role

    POST /_security/role/read-only-my-index 
    {
      "indices": [
        {
          "names": [ "my-index" ],
          "privileges": [ "read" ]
        }
      ]
    }

    The name of the role.

  2. Create the relevant role mapping rule for read only users

    POST /_security/role_mapping/ldap-read-only 
    {
      "enabled": true,
      "roles": [ "read-only-my-index" ], 
      "rules": {
        "field": { "realm.name": "ldap1" } 
        },
      "metadata": { "version": 1 }
    }

    The name of the role mapping.

    The name of the role we created above.

    The name of our LDAP realm.

  3. Create the relevant role mapping rule for superusers

    POST /_security/role_mapping/ldap-superuser 
    {
      "enabled": true,
      "roles": [ "superuser" ], 
      "rules": {
        "all" : [
          { "field": { "realm.name": "ldap1" } },
          { "field": { "groups": "cn=administrators, ou=groups, o=services, dc=example, dc=com" } }
        ]
      },
      "metadata": { "version": 1 }
    }

    The name of the role mapping.

    The name of the role we want to assign, in this case superuser.

    The name of our LDAP realm.

    The DN of the LDAP group whose members should get the superuser role in the deployment.

Using the Role Mapping files

Let’s assume that you want all your users that authenticate via LDAP and are members of the cn=my-users, ou=groups, o=services, dc=example, dc=com group in LDAP to have read only access to a certain index my-index and only the users `cn=Senior Manager, ou=users, o=services, dc=example, dc=com" and `cn=Senior Admin, ou=users, o=services, dc=example, dc=com" to become superusers in your deployment:

  1. Create a file name named role-mappings.yml with the following contents

    superuser:
      - cn=Senior Manager, ou=users, o=services, dc=example, dc=com
      - cn=Senior Admin, ou=users, o=services, dc=example, dc=com
    read-only-user:
      - cn=my-users, ou=groups, o=services, dc=example, dc=com
  2. Prepare a custom bundle as a ZIP file that contains the role-mappings.yml file inside of a mappings folder` in the same way that you would on Elastic Cloud.
  3. Update your plan in the advanced configuration editor so that it uses the bundle you prepared in the previous step. You need to modify the user_bundles JSON attribute similar to the following example:

    {
    "cluster_name": "REPLACE_WITH_YOUR_CLUSTER_NAME",
    "plan": {
    
        ...
    
        "elasticsearch": {
          "version": "7.*",
          "user_bundles": [
            {
              "name": "role-mappings",
              "url": "https://www.myurl.com/mappings.zip",
              "elasticsearch_version": "7.*"
            }
          ]
        }
      }
    Note

    The URL that point to mappings.zip must be accessible to the cluster. Also, when you * a minor versions bundles are compatible with any Elasticsearch major version to avoid a need to re-upload a new bundle with minor versions upgrade. In this example the bundle is compatible with any Elasticsearch 7.* version.

    1. Custom bundles get unzipped under the path /app/config/BUNDLE_DIRECTORY_STRUCTURE, where BUNDLE_DIRECTORY_STRUCTURE is the directory structure within the bundle ZIP file itself. For example:

      $ tree .
      .
      └── mappings
            └── role-mappings.yml

      So in our example, the unzipped role mappings file gets placed under /app/config/mappings/role-mappings.yml

    2. Update your user settings for the ldap realm as follows (building from previous examples)

      xpack:
        security:
          authc:
            realms:
              ldap:
                ldap1:
                  order: 2
                  url: "ldaps://ldap.example.com:636"
                  bind_dn: "cn=ldapuser, ou=users, o=services, dc=example, dc=com"
                  user_search:
                    base_dn: "ou=users, o=services, dc=example, dc=com"
                  group_search:
                    base_dn: ou=groups, o=services, dc=example, dc=com"
                  ssl:
                    verification_mode: certificate
                    certificate_authorities: ["/app/config/cacerts/ca.crt"]
                  files:
                    role_mapping: "/app/config/mappings/role-mappings.yml" 

      The path where our role mappings file got unzipped.