LDAP Not Working

Versions : 3.0

Describe the issue: LDAP Configuration still not working

Configuration :

      ldap:
        description: "Authenticate via LDAP or Active Directory"
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
          type: basic
          challenge: true
        authentication_backend:
          # LDAP authentication backend (authenticate users against a LDAP or Active Directory)
          type: ldap
          config:
            # enable ldaps
            enable_ssl: true
            # enable start tls, enable_ssl should be false
            enable_start_tls: false
            # send client certificate
            enable_ssl_client_auth: false
            # verify ldap hostname
            verify_hostnames: true
            pemtrustedcas_filepath: "/etc/opensearch/certs/chain.pem"
            hosts:
            - xxxxxxxxxxxx:636
            bind_dn: "CN=xx,OU=xx,OU=xx,DC=xx,DC=xx,DC=xx,DC=com"
            password: "---------"
            userbase:
              - "OU=xx,OU=xx,DC=xx,DC=xx,DC=xx,DC=com"
              - "CN=xx,DC=xx,DC=xx,DC=xx,DC=com"
            # Filter to search for users (currently in the whole subtree beneath userbase)
            # {0} is substituted with the username
            usersearch: '(sAMAccountName={0})'
            # Use this attribute from the user as username (if not set then DN is used)
            username_attribute: 'sAMAccountName'
            skip_users:
              - admin
              - kibanaserver
    authz:
      roles_from_myldap:
        description: "Authorize via LDAP or Active Directory"
        http_enabled: true
        transport_enabled: true
        authorization_backend:
          # LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)
          type: ldap
          config:
            # enable ldaps
            enable_ssl: true
            # enable start tls, enable_ssl should be false
            enable_start_tls: false
            # send client certificate
            enable_ssl_client_auth: false
            # verify ldap hostname
            verify_hostnames: true
            pemtrustedcas_filepath: "/etc/opensearch/certs/chain.pem"
            hosts:
            - xxxxxxxxx:636
            bind_dn: "CN=xx,OU=xx,OU=xx,DC=xx,DC=xx,DC=xx,DC=com"
            password: "xxxxxxx"
            rolebase:
              - "CN=xx,DC=xx,DC=xx,DC=xx,DC=com"
              - "OU=xx,OU=xx,DC=xx,DC=xx,DC=xx,DC=com"
            # Filter to search for roles (currently in the whole subtree beneath rolebase)
            # {0} is substituted with the DN of the user
            # {1} is substituted with the username
            # {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute
            rolesearch: '(member={0})'
            # Specify the name of the attribute which value should be substituted with {2} above
            userroleattribute: null
            # Roles as an attribute of the user entry
            #userrolename: disabled
            #userrolename: memberOf
            # The attribute in a role entry containing the name of that role, Default is "name".
            # Can also be "dn" to use the full DN as rolename.
            rolename: cn
            # Resolve nested roles transitive (roles which are members of other roles and so on ...)
            resolve_nested_roles: true

This is a part of my config.yaml (opensearch-security). I run the ./securityplugin to get my changes. And this are my opensearch log.

[2025-05-29T10:50:35,240][ERROR][o.o.s.a.BackendRegistry  ] [opensearch-master-01] Cannot retrieve roles for User [name=admin, backend_roles=[admin], requestedTenant=null] from ldap due to OpenSearchSecurityException[[org.ldaptive.LdapException@1049556574::resultCode=NO_SUCH_OBJECT, matchedDn=null, responseControls=null, referralURLs=null, messageId=-1, message=javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]; remaining name '', providerException=javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]; remaining name '']]; nested: LdapException[javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]; remaining name '']; nested: NameNotFoundException[[LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]];
org.opensearch.OpenSearchSecurityException: [org.ldaptive.LdapException@1049556574::resultCode=NO_SUCH_OBJECT, matchedDn=null, responseControls=null, referralURLs=null, messageId=-1, message=javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]; remaining name '', providerException=javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]; remaining name '']
        at org.opensearch.security.auth.ldap.backend.LDAPAuthorizationBackend.fillRoles(LDAPAuthorizationBackend.java:1009) ~[?:?]
        at org.opensearch.security.auth.BackendRegistry.authz(BackendRegistry.java:557) ~[?:?]
        at org.opensearch.security.auth.BackendRegistry$5.call(BackendRegistry.java:603) ~[?:?]
        at org.opensearch.security.auth.BackendRegistry$5.call(BackendRegistry.java:592) ~[?:?]
        at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4860) ~[?:?]
        at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3551) ~[?:?]
        at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2302) ~[?:?]
        at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2177) ~[?:?]
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2068) ~[?:?]
        at com.google.common.cache.LocalCache.get(LocalCache.java:3986) ~[?:?]
        at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4855) ~[?:?]
        at org.opensearch.security.auth.BackendRegistry.authcz(BackendRegistry.java:592) ~[?:?]
        at org.opensearch.security.auth.BackendRegistry.authenticate(BackendRegistry.java:345) ~[?:?]
        at org.opensearch.security.filter.SecurityRestFilter.checkAndAuthenticateRequest(SecurityRestFilter.java:306) ~[?:?]
        at org.opensearch.security.ssl.http.netty.Netty4HttpRequestHeaderVerifier.channelRead0(Netty4HttpRequestHeaderVerifier.java:90) ~[?:?]
        at org.opensearch.security.ssl.http.netty.Netty4HttpRequestHeaderVerifier.channelRead0(Netty4HttpRequestHeaderVerifier.java:37) ~[?:?]
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[?:?]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:107) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1515) ~[?:?]
        at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1378) ~[?:?]
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1427) ~[?:?]
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530) ~[?:?]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) ~[?:?]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[?:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868) ~[?:?]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[?:?]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:796) ~[?:?]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:697) ~[?:?]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:660) ~[?:?]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[?:?]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[?:?]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[?:?]
        at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
Caused by: org.ldaptive.LdapException: javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]; remaining name ''
        at org.ldaptive.provider.ProviderUtils.throwOperationException(ProviderUtils.java:55) ~[?:?]
        at org.ldaptive.provider.jndi.JndiConnection.processNamingException(JndiConnection.java:619) ~[?:?]
        at org.ldaptive.provider.jndi.JndiConnection$JndiSearchIterator.initialize(JndiConnection.java:741) ~[?:?]
        at org.ldaptive.provider.jndi.JndiConnection.search(JndiConnection.java:463) ~[?:?]
        at org.ldaptive.SearchOperation.executeSearch(SearchOperation.java:103) ~[?:?]
        at org.ldaptive.SearchOperation.invoke(SearchOperation.java:85) ~[?:?]
        at org.ldaptive.SearchOperation.invoke(SearchOperation.java:15) ~[?:?]
        at org.ldaptive.AbstractOperation.execute(AbstractOperation.java:126) ~[?:?]
        at org.opensearch.security.auth.ldap.util.LdapHelper$1.run(LdapHelper.java:74) ~[?:?]
        at org.opensearch.security.auth.ldap.util.LdapHelper$1.run(LdapHelper.java:58) ~[?:?]
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:571) ~[?:?]
        at org.opensearch.security.auth.ldap.util.LdapHelper.search(LdapHelper.java:58) ~[?:?]
        at org.opensearch.security.auth.ldap.backend.LDAPAuthenticationBackend.existsSearchingUntilFirstHit(LDAPAuthenticationBackend.java:257) ~[?:?]
        at org.opensearch.security.auth.ldap.backend.LDAPAuthenticationBackend.exists(LDAPAuthenticationBackend.java:235) ~[?:?]
        at org.opensearch.security.auth.ldap.backend.LDAPAuthorizationBackend.fillRoles(LDAPAuthorizationBackend.java:782) ~[?:?]
        ... 53 more
Caused by: javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310021F, problem 2001 (NO_OBJECT), data 0, best match of:
        ''
]
        at java.naming/com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3285) ~[?:?]
        at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3206) ~[?:?]
        at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2997) ~[?:?]
        at java.naming/com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1876) ~[?:?]
        at java.naming/com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1799) ~[?:?]
        at java.naming/com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392) ~[?:?]
        at java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358) ~[?:?]
        at java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:341) ~[?:?]
        at org.ldaptive.provider.jndi.JndiConnection$JndiSearchIterator.search(JndiConnection.java:807) ~[?:?]
        at org.ldaptive.provider.jndi.JndiConnection$JndiSearchIterator.initialize(JndiConnection.java:735) ~[?:?]
        at org.ldaptive.provider.jndi.JndiConnection.search(JndiConnection.java:463) ~[?:?]
        at org.ldaptive.SearchOperation.executeSearch(SearchOperation.java:103) ~[?:?]
        at org.ldaptive.SearchOperation.invoke(SearchOperation.java:85) ~[?:?]
        at org.ldaptive.SearchOperation.invoke(SearchOperation.java:15) ~[?:?]
        at org.ldaptive.AbstractOperation.execute(AbstractOperation.java:126) ~[?:?]
        at org.opensearch.security.auth.ldap.util.LdapHelper$1.run(LdapHelper.java:74) ~[?:?]
        at org.opensearch.security.auth.ldap.util.LdapHelper$1.run(LdapHelper.java:58) ~[?:?]
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:571) ~[?:?]
        at org.opensearch.security.auth.ldap.util.LdapHelper.search(LdapHelper.java:58) ~[?:?]
        at org.opensearch.security.auth.ldap.backend.LDAPAuthenticationBackend.existsSearchingUntilFirstHit(LDAPAuthenticationBackend.java:257) ~[?:?]
        at org.opensearch.security.auth.ldap.backend.LDAPAuthenticationBackend.exists(LDAPAuthenticationBackend.java:235) ~[?:?]
        at org.opensearch.security.auth.ldap.backend.LDAPAuthorizationBackend.fillRoles(LDAPAuthorizationBackend.java:782) ~[?:?]

I don’t understand why is lookign for “admin” user even though I skipped it in the ldap configuration. I don’t get any more error logs but still my login doesn’t work.

I’ve already verified that the “host , bind_dn, userbase , rolebase” are correct. The settings already run on a Splunk infrastructure and use the same information and working fine.

Any suggest?

@pablo Hi Pablo, do you have any suggest for me?

@abarocco As per OpenSearch documentation, the skip_users is part of the LDAP authorization config.

In this case, it makes sense to exclude the OpenSearch Dashboards server user from the LDAP authorization because we already know that there is no corresponding entry. You can use the skip_users configuration setting to define which users should be skipped. Wildcards and regular expressions are supported:

Could you try moving it to the authz section and testing it?

Does your LDAP and basicauth work? I mean, can you access the resources of OpenSearch?
If not, please share the output of the following command.

curl --insecure -u <ldapuser>:<password> -XGET https://<OpenSearch_node_FQDN_or_IP>:9200/_plugins/_security/authinfo?pretty

Hi @pablo sorry for the late reply.

I’ve tested the skip_users in the auth section and work fine. But LDAP still not working.

i’ve tried to authenticate on opensearch dashboards using my LDAP username to run a curl and i receive “Unauthorized”.

Same output for this :
curl --insecure -u <ldapuser>:<password> -XGET https://<OpenSearch_node_FQDN_or_IP>:9200/_plugins/_security/authinfo?pretty

In the opensearch log file i dont have any error. I see just this WARN
[2025-06-02T13:09:40,546][WARN ][o.o.s.a.BackendRegistry ] [opensearch-master-01] Authentication finally failed for U0B274 from 10.174.110.129:60116

U0B274 is my LDAP user and I have already verified that my user is correctly registered.

@abarocco Did you remove basicauth in your config? Could you share the full config.yml.
Your basicauth should work as it is not related to LDAP authentication.

Please run ldapsearch tool against the groups defined in the rolebase.

i.e.

ldapsearch -H ldaps://ldaps.2lb.systest.spi.com:636   -D "CN=UNIXAD,OU=Utentidiservizio,OU=SPI,DC=syssede,DC=systest,DC=spi,DC=com"   -w '------------'   -b "CN=YA2W56Gr,CN=Abilitazioni,OU=Profili di Sicurezza,OU=SPI,DC=syssede,DC=systest,DC=spi,DC=com"

Hi @pablo i resolve the issue.

In the config.yaml

userbase:
       - "OU=xx,OU=xx,DC=xx,DC=xx,DC=xx,DC=com"
       - "CN=xx,DC=xx,DC=xx,DC=xx,DC=com"

Userbase and rolebase not accept value like an array.
The correct method is :

      users:
          primary-userbase:
             base: 'ou=people,dc=example,dc=com'
             search: '(uid={0})'
          secondary-userbase:
             base: 'cn=users,dc=example,dc=com'
             search: '(uid={0})'

@abarocco Thank you for sharing your solution. That is correct as per the OpenSearch documentation.

I also checked the logs, and the security plugin doesn’t complain during the startup or at the failed login when that array approach is used.

However, I’m still able to log in with basic authentication (internal user) as it is not related to LDAP by default.