Nexus ldap issue

I am using Sonatype Nexus Repository ManagerOSS 3.37.3-02.
I can establish the connection with the LDAP server, and I can verify the user mapping as well.
I am able to login with LDAP users, but sometimes, it throws an error, authentication failed
A number of users face the same issue, very often. After a couple of tries, again it authenticates.
Here, I am attaching the nexus logs for reference.


2022-02-03 02:33:45,193+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.realms.EnterpriseLdapManager - Ldap User: helm.user@example.com not found in cache.
2022-02-03 02:33:45,194+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.connector.FailoverLdapConnector - isOriginalConnectorValid=TRUE 1643830583243+300000 < 1643855625194
2022-02-03 02:33:45,194+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.realms.DefaultLdapContextFactory - Initializing LDAP context using URL [ldaps://ldap.us.onelogin.com:636/dc=example,dc=onelogin,dc=com] and username [cn=pie-nexus@example.com,ou=users,dc=example,dc=onelogin,dc=com] with pooling [enabled] and environment {java.naming.referral=follow, com.sun.jndi.ldap.connect.timeout=90000, java.naming.security.principal=cn=pie-nexus@example.com,ou=users,dc=example,dc=onelogin,dc=com, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.connect.pool=true, java.naming.security.sasl.realm=, java.naming.
vider.url=ldaps://ldap.us.onelogin.com:636/dc=example,dc=onelogin,dc=com, java.naming.security.credentials=***, java.naming.security.authentication=simple}
2022-02-03 02:33:45,194+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.connector.dao.DefaultLdapUserDAO - Searching for user: helm.user@example.com
2022-02-03 02:33:45,195+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.connector.dao.DefaultLdapUserDAO - Specific filter rule: ""
2022-02-03 02:33:45,195+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.connector.dao.DefaultLdapUserDAO - Searching for users with filter: '(&(objectClass=inetOrgPerson)(uid=helm.user@example.com))'
2022-02-03 02:33:45,262+0000 WARN  [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.connector.FailoverLdapConnector - Problem connecting to LDAP server:  Caused by: javax.naming.NamingException: LDAP connection has been closed; remaining name ''
org.sonatype.nexus.ldap.internal.connector.dao.LdapDAOException: Failed to retrieve information for user: helm.user@example.com
	at org.sonatype.nexus.ldap.internal.connector.dao.DefaultLdapUserDAO.getUser(DefaultLdapUserDAO.java:135)
	at org.sonatype.nexus.ldap.internal.connector.DefaultLdapConnector.getUser(DefaultLdapConnector.java:132)
	at org.sonatype.nexus.ldap.internal.connector.FailoverLdapConnector.getUser(FailoverLdapConnector.java:153)
	at org.sonatype.nexus.ldap.internal.realms.EnterpriseLdapManager.authenticateUser(EnterpriseLdapManager.java:139)
	at org.sonatype.nexus.ldap.internal.LdapRealm.queryForAuthenticationInfo(LdapRealm.java:101)
	at org.apache.shiro.realm.ldap.AbstractLdapRealm.doGetAuthenticationInfo(AbstractLdapRealm.java:200)
	at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:571)
	at org.sonatype.nexus.security.authc.FirstSuccessfulModularRealmAuthenticator.doMultiRealmAuthentication(FirstSuccessfulModularRealmAuthenticator.java:59)
	at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:275)
	at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
	at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
	at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275)
	at org.apache.shiro.nexus.NexusWebSecurityManager.login(NexusWebSecurityManager.java:84)
	at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
	at org.apache.shiro.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:53)
	at org.apache.shiro.web.filter.authc.HttpAuthenticationFilter.onAccessDenied(HttpAuthenticationFilter.java:230)
	at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133)
	at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
	at org.sonatype.nexus.security.authc.NexusBasicHttpAuthenticationFilter.onPreHandle(NexusBasicHttpAuthenticationFilter.java:86)
	at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:223)
	at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:198)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:450)
	at org.sonatype.nexus.security.SecurityFilter.executeChain(SecurityFilter.java:96)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.sonatype.nexus.security.SecurityFilter.doFilterInternal(SecurityFilter.java:112)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.repository.httpbridge.internal.ExhaustRequestFilter.doFilter(ExhaustRequestFilter.java:80)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.sonatype.nexus.licensing.internal.LicensingRedirectFilter.doFilter(LicensingRedirectFilter.java:116)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:112)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.internal.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:79)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.internal.web.EnvironmentFilter.doFilter(EnvironmentFilter.java:101)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at org.sonatype.nexus.internal.web.HeaderPatternFilter.doFilter(HeaderPatternFilter.java:98)
	at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
	at com.google.inject.servlet.DynamicFilterPipeline.dispatch(DynamicFilterPipeline.java:104)
	at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:133)
	at org.sonatype.nexus.bootstrap.osgi.DelegatingFilter.doFilter(DelegatingFilter.java:73)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:201)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:239)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.lang.Thread.run(Thread.java:748)
Caused by: javax.naming.NamingException: LDAP connection has been closed
	at com.sun.jndi.ldap.LdapRequest.getReplyBer(LdapRequest.java:133)
	at com.sun.jndi.ldap.Connection.readReply(Connection.java:469)
	at com.sun.jndi.ldap.LdapClient.getSearchReply(LdapClient.java:638)
	at com.sun.jndi.ldap.LdapClient.search(LdapClient.java:561)
	at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:2013)
	at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1872)
	at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1797)
	at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392)
	at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358)
	at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:341)
	at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)
	at org.sonatype.nexus.ldap.internal.connector.dao.DefaultLdapUserDAO.searchUsers(DefaultLdapUserDAO.java:74)
	at org.sonatype.nexus.ldap.internal.connector.dao.DefaultLdapUserDAO.getUser(DefaultLdapUserDAO.java:119)
	... 79 common frames omitted
2022-02-03 02:33:45,262+0000 DEBUG [qtp1045754506-9146]  *UNKNOWN org.sonatype.nexus.ldap.internal.realms.EnterpriseLdapManager - Failed to find user: helm.user@example.com
org.sonatype.nexus.ldap.internal.connector.dao.LdapDAOException: Failed to retrieve information for user: helm.user@example.com



Your log says the LDAP connection was closed. Probably you should compare your LDAP server settings, and the settings you configured in Nexus. Or things between nexus and LDAP that may terminate the connection.

Does nexus oss have any default cache support?
I see in the very beginning of logs, due to cache information was not found, it was not able to find LDAP user.

For reference, I am attaching my nexus realms configuration

We were having similar issues after our LDAP was relocated to another cloud service. :face_with_diagonal_mouth:

What I think was happening for us is that all the LDAP connections in the pool are closed due to inactivity after a while. Then if Nexus tries to use such a connection it will throw the exception for each connection in the pool (causing retries to fail as well). We’ve seen similar issues for HTTP connection pooling in our own code. :wink:

You can tweak the LDAP connection pool using some system properties as listed here:

https://docs.oracle.com/javase/jndi/tutorial/ldap/connect/config.html

What seems to work for us is to remove idle connections after 5 minutes from the pool instead of the default behavior of keeping them forever.

I.e. add the -Dcom.sun.jndi.ldap.connect.pool.timeout=300000 system property.

If you run Nexus using a Docker container :whale: this can be done by adding this property to the default INSTALL4J_ADD_VM_PARAMS as described in the container documentation:

E.g. when using Docker Compose you can add the following to the container config:

    environment:
     - INSTALL4J_ADD_VM_PARAMS=-Xms2703m -Xmx2703m -XX:MaxDirectMemorySize=2703m -Djava.util.prefs.userRoot=/nexus-data/javaprefs -Dcom.sun.jndi.ldap.connect.pool.timeout=300000

What file did you add that parameter to?

I launch Nexus using Docker Compose so I updated my docker-compose.yml file.