Authentication with redundant ldap servers

Hey,

we are currently operating the SonarQube Developer Edition v10.5.1 deployed via ZIP with two ldap servers that are continously mirrored to enable redundant authentication and authorization.
After an outage of the primary server it was not possible to login anymore. After further testing in debug mode I got the following error messages in web.log:

web.log
2024.06.25 12:30:28 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.DefaultLdapAuthenticator] User login_user not found in server <server1>: javax.naming.CommunicationException: ldap01.server.com [Root exception is java.net.ConnectException: Connection timed out]
2024.06.25 12:30:28 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=users,dc=mycompany,dc=com, scope=subtree, request=[user request], parameters=[login_user], attributes=null}
2024.06.25 12:30:28 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=binduser,cn=technical,cn=users,dc=mycompany,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap02.server.com, java.naming.security.authentication=simple}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=login_user,cn=sop,cn=users,dc=mycompany,dc=com, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap02.server.com, java.naming.security.authentication=simple}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.DefaultLdapUsersProvider] Requesting details for user login_user
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=users,dc=mycompany,dc=com, scope=subtree, request=[user request], parameters=[login_user], attributes=[mail, displayName]}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=binduser,cn=technical,cn=users,dc=mycompany,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap02.server.com, java.naming.security.authentication=simple}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.DefaultLdapGroupsProvider] Requesting groups for user login_user
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=users,dc=mycompany,dc=com, scope=subtree, request=[user request], parameters=[login_user], attributes=[uid]}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=binduser,cn=technical,cn=users,dc=mycompany,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap02.server.com, java.naming.security.authentication=simple}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=groups,dc=mycompany,dc=com, scope=subtree, request=(&(objectClass=posixGroup)(memberUid={0})), parameters=[login_user], attributes=[cn]}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=binduser,cn=technical,cn=users,dc=mycompany,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldaps://ldap02.server.com, java.naming.security.authentication=simple}
2024.06.25 12:30:29 DEBUG web[f9219581-480d-4714-98a0-75c0b0541945][auth.event] login failure [cause|Email 'login_user@mycompany.com' is already used][method|BASIC][provider|REALM|ldap][IP|127.0.0.1|][login|login_user]

The ldap configuration of my sonar.properties looks like this:

sonar.properties
# Enable the LDAP feature
sonar.security.realm=LDAP

# Configuration for multiple ldap-servers
ldap.servers=server1,server2


# Config for server1
ldap.server1.url=ldaps://ldap01.server.com
ldap.server1.bindDn=uid=binduser,cn=technical,cn=users,dc=mycompany,dc=com
ldap.server1.bindPassword=<password>

# User configuration
ldap.server1.user.baseDn=cn=users,dc=mycompany,dc=com
ldap.server1.user.request=<user request>
ldap.server1.user.realNameAttribute=displayName
ldap.server1.user.emailAttribute=mail

# Group mapping
ldap.server1.group.baseDn=cn=groups,dc=mycompany,dc=com
ldap.server1.group.request=<group request>

# Config for server2
ldap.server2.url=ldaps://ldap02.server.com
ldap.server2.bindDn=uid=binduser,cn=technical,cn=users,dc=mycompany,dc=com
ldap.server2.bindPassword=<password>

# User configuration
ldap.server2.user.baseDn=cn=users,dc=mycompany,dc=com
ldap.server2.user.request=<user request>
ldap.server2.user.realNameAttribute=displayName
ldap.server2.user.emailAttribute=mail

# Group mapping
ldap.server2.group.baseDn=cn=groups,dc=mycompany,dc=com
ldap.server2.group.request=<group request>

Now I’m looking for answers on how to configure SonarQube properly to use the second ldap server when the first one can not be reached.

Maybe someone here has an idea.

Greetings,
Raffael

Hello @sopraf,

Thanks for the report.

SonarQube’s LDAP support is not designed to connect to multiple LDAP servers in a failover mode. Instead, the feature is designed to allow companies with different LDAP servers hosting different users to allow users of both LDAPs to connect.

For security reasons, the user provisioned via LDAP server 2 must always connect with the same LDAP server. Otherwise, this would allow people to create a matching user on LDAP server 1 and potentially impersonate the account (assuming the 2 LDAP servers are owned.

For your scenario, a possibility would be to hide your two LDAP nodes behind a reverse proxy.

I will tag internally the doc team, so that they can make it more explicit on the relevant documentation page.

Aurélien

1 Like