OpenSearch Security Part 5: LDAP Authentication

This article will show you how to use LDAP or Active Directory to authenticate OpenSearch users and assign security roles to control access privileges.

This article will show you how to use LDAP or Active Directory to authenticate OpenSearch users and assign security roles to control access privileges.

LDAP and Active Directory

LDAP (“Lightweight Directory Access Protocol”) and Active Directory (“AD)” are standard technologies to manage users and user groups. Many times companies already have LDAP or Active Directory servers in place. OpenSearch Security comes with LDAP and AD support built-in. So, let’s use them to authenticate users for OpenSearch.
We will set up an authentication domain in config.yml, connect to a server, and set up an LDAP query to retrieve user information from the user tree.

Enable the LDAP Authentication Domain

OpenSearch ships with an LDAP template in config.yml that we can use as a starting point. As a first step, we will enable the LDAP authentication domain, make sure it is the first one in the chain, and also enable the HTTP authenticator:
authc: 
  ...
  ldap:
    description: "Authenticate via LDAP or Active Directory"
    http_enabled: true
    order: 0
    http_authenticator:
      type: basic
      challenge: true
The http_authenticator section makes sure OpenSearch extracts the username and password from the HTTP Basic Authentication headers. The challenge flag determines what happens if no credentials are present. Since we set it to true, OpenSearch will send back a “WWW-Authenticate” header so that browsers will show a login dialogue.

Connection Settings

Next, we define the connection settings. We can specify more than one LDAP servers (“hosts”) for high availability: If one server is not reachable, OpenSearch will try the next in the list. We also turn on SSL encryption for the traffic between OpenSearch and the LDAP server and define the root CA. The latter is required for verifying the TLS certificate of the LDAP server.
Last, we define the credentials that OpenSearch uses to execute LDAP queries. In most cases, the server requires a user (“bind_dn”) and password (“password”) for running queries. Some LDAP / AD servers allow “anonymous binds”. This means anyone can connect and query the LDAP directory without authentication. In this case you can remove the corresponding configuration settings.
authentication_backend:
  type: ldap
  config:
    enable_ssl: true
    pemtrustedcas_filepath: /full/path/to/trusted_cas.pem
    hosts:
      - primary.ldap.example.com:389
      - secondary.ldap.example.com:389
    bind_dn: cn=admin,dc=example,dc=com
    password: "password"

Configuring the LDAP Query

Next, we need to tell OpenSearch a bit about the directory structure in the LDAP server and how to locate users.
LDAP organizes data in a tree structure. By specifying the userbase we tell OpenSearch in which subtree the user entries are stored. The usersearch parameter defines the actual query to locate a particular user. The variable {0} is replaced by the username extracted from the http_authenticator.
userbase: 'ou=people,dc=example,dc=com'
# Filter to search for users 
# {0} is substituted with the username
usersearch: '(sAMAccountName={0})'
If this would be an SQL server instead of an LDAP server, the query would roughly look like:
SELECT * FROM ou=people,dc=example,dc=com WHERE sAMAccountName= 'username'

What’s my Name?

If the query returns a user and the password matches the password retrieved by the http_authenticator, authentication has succeeded.
By default, OpenSearch uses the Distinguished Name (“DN”) of the user entry as username. A user entry might look like:
dn: cn=Peter Scott,ou=people,dc=example,dc=com
objectclass: inetOrgPerson
givenName: SCOTT
sn: PETER
uid: peterscott
userpassword: peterscott
mail: [email protected]
If we configure nothing else, the username would be “cn=Peter Scott,ou=people,dc=example,dc=com”. In most cases, you will want to use some other value to represent the username. For example, the uid “peterscott”. This can be configured by the username_attribute setting:
# Use this attribute from the user as username 
username_attribute: uid

Mapping LDAP Users to Roles

As described in the last article, we now need to assign security roles to the user. To do so, we add a new entry in roles_mapping.yml:
my-role-a:
  users:
    - "peterscott"

Summary

To use an LDAP or AD server for user authentication, we first activated the LDAP authentication backend in config.yml and specified the basic connection settings. Since our LDAP server requires authentication before executing a query, we defined the bind_dn and the password.
Next, we defined the location of our user entries in the LDAP tree setting the userbase parameter. We also specified the actual query that OpenSearch should use when looking for users.
When a user tries to log in, OpenSearch will retrieve the username and password from the http_authenticator. It connects to the server and executes the LDAP query, substituting the parameter {0} in the query with the username. If a user was found and the passwords match, authentication is successful.
As the last step we specified which LDAP user attribute should represent the username.

Outlook

In the following article, we will add LDAP authorization to the mix. The authorization will allow us also to retrieve the LDAP groups of a user which can then be used to implement a more flexible role mapping.
Interested? Get in touch!