<a id="client-auth-with-ldap"></a>

# Configure Kafka Clients for LDAP Authentication in Confluent Platform

#### IMPORTANT
This software is available under a
[Confluent enterprise license](https://www.confluent.io/product/confluent-enterprise/). You can use
this software for a 30-day trial period without a license key. If you are a subscriber, contact
[Confluent Support](https://support.confluent.io/). Note that this license applies
to Confluent Server brokers. Kafka clients do not require a license.

<!-- end-license -->

You can use Active Directory (AD) or LDAP to configure Kafka client authentication
across all of your Confluent Platform clusters that use SASL/PLAIN. The SASL/PLAIN binding to
LDAP requires a password provided by the Kafka client.

* Confluent does not recommend using SASL/PLAIN with LDAP for interbroker
  communication because intermittent LDAP errors can cause significant broker
  performance issues. Instead, keep authentication internal to the Confluent Platform cluster
  (using mTLS, SALS/PLAIN with no Callback Handler, or other options).
* You cannot bind SASL/SCRAM to LDAP because these hashed Kafka client credentials
  cannot be sent by the Kafka client. Metadata Service (MDS) does an LDAP bind using the username and password
  provided by the Kafka client to verify the credentials provided are correct. Because SCRAM
  modifies the password, it cannot be used to login to the LDAP server.

You must set up an LDAP server (for example, AD) before starting up the Confluent Platform
cluster. The configuration that follows is based on the assumption that you have
an LDAP server at the URL `LDAPSERVER.EXAMPLE.COM:3268` that is accessible using DNS
lookup from the host where the broker is run. While the configuration expects a
Kerberos-enabled LDAP server, Kerberos is not required; you can perform a
simple bind if your LDAP supports it. These security settings must match your LDAP server configuration.

If your LDAP server authenticates Kafka clients using Kerberos, the keytab file
and principal should be updated in authorizer JAAS configuration option
`ldap.sasl.jaas.config`.

If you wish to disable LDAP group authorization you can set the flag `ldap.group.authorization.enable`
to `false`.

To configure Kafka client authentication with AD/LDAP:

1. Start the LDAP server.
2. Add the user name and password to LDAP.

   The following example shows how to add a user named `client` with the password
   `client-secret` to the LDAP server. Remember to replace the placeholders and
   example values with actual data relevant to your LDAP directory.
   ```none
   dn: dc=planetexpress,dc=com
   objectClass: top
   objectClass: dcObject
   objectClass: organization
   o: Planet Express
   dc: planetexpress

   dn: ou=people,dc=planetexpress,dc=com
   objectClass: top
   objectClass: organizationalUnit
   ou: people

   dn: uid=client,ou=people,dc=planetexpress,dc=com
   objectClass: top
   objectClass: person
   objectClass: organizationalPerson
   objectClass: inetOrgPerson
   uid: client
   cn: Client User
   sn: User
   userPassword: client-secret
   ```
3. Enable LDAP authentication for Kafka clients by adding the LDAP callback handler
   to `server.properties` in the broker.

   Add the SASL configuration:
   ```none
   listener.name.sasl_plaintext.sasl.enabled.mechanisms=PLAIN
   listener.name.sasl_plaintext.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required;

   # Use this when using LDAP authentication for interbroker communication
   listener.name.sasl_plaintext.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="kafka-secret";

   listener.name.sasl_plaintext.plain.sasl.server.callback.handler.class=
   io.confluent.security.auth.provider.ldap.LdapAuthenticateCallbackHandler
   ```

   If you want to use LDAP authentication for interbroker communication, then
   you must include the broker’s user name and password in your SASL configuration.

   Add the LDAP configuration:
   ```none
   ldap.java.naming.provider.url=ldap://openldap:389
   # Authenticate to LDAP
   ldap.java.naming.security.principal=CN=admin,DC=planetexpress,DC=com
   ldap.java.naming.security.credentials=GoodNewsEveryone
   ldap.java.naming.security.authentication=simple
   # Locate users
   ldap.user.search.base=ou=people,dc=planetexpress,dc=com
   ldap.user.name.attribute=uid
   ldap.user.object.class=user
   ```

   #### NOTE
   Only include the attribute `ldap.user.password.attribute` when your LDAP
   server does not support simple bind. Otherwise, be aware that if you include
   `ldap.user.password.attribute`, simple bind is disabled.
4. Restart the Confluent Server broker.
   ```none
   /bin/kafka-server-start etc/kafka/server.properties
   ```
5. Specify the Kafka client configuration in `producer.properties` and `consumer.properties`:
   ```none
   sasl.mechanism=PLAIN
   security.protocol=SASL_PLAINTEXT
   sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule
     required username="client" password="client-secret";
   ```

   It’s recommended that you encrypt the password in your Kafka client configuration
   using [Manage Secrets in Confluent Platform](../../compliance/secrets/overview.md#secrets). The following example shows an encrypted Kafka client
   configuration:
   ```none
   sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule
     required username="client" password=${securepass:/secretsDemo/server.properties:server.properties/sasl.jaas.config/=org.apache.kafka.common.security.plain.PlainLoginModule /password};
   ```

   #### NOTE
   Credentials are sent in PLAIN text, so be sure to use TLS with LDAP.

<a id="test-ldap-client-authentication"></a>

## Testing and Troubleshooting LDAP Client Authentication

This section provides basic troubleshooting tips to address common errors that
can occur when configuring LDAP client authentication.

Test your LDAP client configuration using the following steps.

1. Verify LDAP connectivity:
   ```text
   # Ping the LDAP host to verify connectivity
   ping ldap.hostname.com
   # Connect to the LDAP host (this command uses the default port)
   telnet ldap.hostname.com 389
   ```
2. Install the `ldapsearch` tool to conduct subsequent tests:
   ```text
   sudo yum install openldap-clients -y
   ```
3. Verify basic access without specifying any credentials:
   ```text
   ldapsearch -LLL -x -H ldap://ldap.hostname.com -s "base" -b "" supportedSASLMechanisms
   ```

   This command should return either a success response or an authentication
   error. Any other errors indicate that LDAP not set up correctly.

   A success response looks like the following:
   ```text
   ldapsearch -LLL -x -H ldap://localhost -s "base" -b "" supportedSASLMechanisms
   dn:
   supportedSASLMechanisms: GS2-IAKERB
   supportedSASLMechanisms: GS2-KRB5
   supportedSASLMechanisms: SCRAM-SHA-1
   supportedSASLMechanisms: SCRAM-SHA-256
   supportedSASLMechanisms: GSS-SPNEGO
   supportedSASLMechanisms: GSSAPI
   supportedSASLMechanisms: DIGEST-MD5
   supportedSASLMechanisms: OTP
   supportedSASLMechanisms: NTLM
   supportedSASLMechanisms: CRAM-MD5
   ```

   An authentication error looks like the following:
   ```text
   ldapsearch -LLL -x -W -H ldap://localhost -s "base" -b "" supportedSASLMechanisms
   Enter LDAP Password:
   ldap_bind: Invalid credentials (49)
   ```

   In cases where you are unable to communicate with an LDAP server, and/or the
   LDAP server is not set up correctly to accept LDAP requests, the error looks
   like the following:
   ```text
   ldapsearch -LLL -x -H ldap://localhost:8090 -s "base" -b "" supportedSASLMechanisms
   ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
   ```
4. Verify basic credential-based access using the same user specified in
   `ldap.java.naming.security.principal` in `server.properties`:
   ```text
   ldapsearch -LLL -x -H ldap://ldap.hostname.com -s "base" -b "" -D CN=kafka_user,CN=Users,DC=hostname,DC=com -w 'pa55word' supportedSASLMechanisms
   ```

   If the value of `ldap.java.naming.security.principal` points to a Kerberos
   principal, be sure to specify the corresponding user from LDAP.

If the preceding verification tests work, then [MDS](../../../kafka/configure-mds/index.md#rbac-mds-config) can
authenticate against LDAP.

When configuring Kafka to communicate over LDAPS, verify TLS connectivity to the
LDAP server as follows:

```text
# To verify the LDAP configuration
ldapsearch -LLL -x -H ldaps://ldap.hostname.com -s "base" -b "" supportedSASLMechanisms
# If using self-signed certificates from the LDAP server
LDAPTLS_CACERT=/path/to/CA.cert ldapsearch -LLL -x -H ldaps://ldap.hostname.com -s "base" -b "" supportedSASLMechanisms
```

When configuring Kafka to authenticate to LDAP using Kerberos, verify
authentication to the LDAP server as follows:

```text
# To verify the Kerberos configuration
kinit -k -t ./filename.keytab kafka_broker/kafka1.hostname.com@EXAMPLE.COM
ldapsearch -LLL -Y GSSAPI -H ldap://ldap.hostname.com -s "base" -b "" supportedSASLMechanisms
```
