Jenkins LDAP Configuration Troubleshooting

Article ID:235438387
5 minute readKnowledge base

Symptoms

  • I am not able to log-in to Jenkins using LDAP

  • LDAP groups are not recognized by Jenkins

  • In /whoAmI LDAP groups do not appear

  • I attempted to Configure the LDAP Plugin and I’m locked out of Jenkins

  • I am receiving a UnknownHostException: DomainDnsZones error

Diagnosis/Treatment

  • Pre-conditions:

  • When configuring the LDAP Plugin for the first time the login does not work.

  • During testing, you should set the Authorization schema to: Anyone can do anything. Otherwise, an incorrect configuration can prevent you from login. See Disable Security.

Minimum Configuration Setup

Ideally, you will want to begin with a simple scenario for CloudBees Jenkins and your LDAP Server for testing purposes

When working with the LDAP plugin for the first time, you should only configure the fields represented in the image below. Notice that an incorrect setting in the User filter field might prevent the user from login.

The only options which should be filled are (red are mandatory and orange optional):

  • a - Server as ldap(s)://<IP_ADDRESS>[:<PORT>] Note: Default TCP and UDP are 389 for ldap and 636 for ldaps. Use :<PORT> if the service is exposed in a different port than defaults ones.

  • b - rootDN ( or <searchbase>)

  • c - User search filter : Depending on your LDAP Server configuration, there might be three different options which might work - if you don’t know how your LDAP tree is configured, then you might want to test all of them, or consult your Directory Services Administrator.

  • cn={0}

  • uid={0}

  • sAMAccountName={0} (For configuring the LDAP Plugin with an AD server)

  • d - In the case that the LDAP server(s) do NOT allow Anonymous binding Manager DN & password (or <binddn> & <passwd>) may be needed.

ldap_validation.png

Validate the LDAP Plugin configuration

After configuring the minimum settings, click on Test LDAP Settings.

ldap_validation.png

Once your configuration is validated, log-in with a "UserX" and browse to https://<JENKINS_URL>/whoAmI/ then validate that the groups for "UserX" are correctly retrieved.

ldap-whoami.png

If The Configuration Does Not Work…​

Check your connection values with a LDAP Client

LDAP client tools, such as JExplorer, might be useful to validate minimum configuration used to integrate LDAP in Jenkins.

On the other hand, this tool can be used, amongst other things, for validating groups members or for validating specific fields like <binddn> (manager DN). In the following example, for "exampleUser" as "uid=colin=people,dc=example,dc=com".

ldap_validation.png

Use ldapsearch

Validate if you can connect to the LDAP Server from the Jenkins Servers with the help of the ldapsearch command line tool:

ldapsearch -LLL -H ldap://<IP_ADDRESS>:<PORT> -M -b "<searchbase>" -D "<binddn>" -w "<passwd>" "(uid=<userid>)"

NOTE:

  • For testing purposes you will need to install ldapsearch on the same server running Jenkins. For linux, ldapsearch is included within the ldap-utils package.

  • Take care to escape special character with \ in case it is necessary.

  • For the following commands, in the case you want to mask your password, -w "<passwd>" can be replaced by:

  • -W, which will prompt you to enter your password.

  • -y ./pass.txt, so that /pass.txt contains your credentials.

Examples
Retrieve a full organization
ldapsearch -LLL -H ldap://ldap.example.com:389 -M -D "ou=people,dc=example,dc=com" -b "dc=example,dc=com" -w "pass"
Retrieve one user
ldapsearch -LLL -H ldap://ldap.example.com:389 -M -D "ou=people,dc=example,dc=com" -b "dc=example,dc=com" -w "pass" uid="exampleUser"

Logging

After configuring minimum set-up for the plugin, to troubleshoot specific issues you could create a LDAP dedicated logs including the following packages:

Version 1.26 or newer

  • org.springframework.ldap = ALL

  • org.springframework.security.ldap = ALL

Before 1.26

  • org.acegisecurity.ldap = ALL

  • org.acegisecurity.providers.ldap = ALL

UnknownHostException: DomainDnsZones Error

2019-03-27 09:08:04.661+0000 [id=2298737]   WARNING h.s.LDAPSecurityRealm$LDAPAuthenticationManager#authenticate: Failed communication with ldap server.
java.net.UnknownHostException: DomainDnsZones

Why the error is thrown:

Active Directory servers are integrated with DNS, and modify entries in the DNS server. They refer to themselves in the root of their LDAP tree. If the Jenkins server is pointed to the root of the LDAP tree, and follow referrals is turned on (which is the default in the LDAP Plugin, then the following takes place:

  • The application will search for users.

  • AD server will respond with users and the referral that’s in the root of the LDAP tree, because there could be more users over there.

  • The application will follow the referral.

This will result in:

  • A DNS lookup of the base DN ( dc=example,dc=com means a lookup for example.com)

  • A connection to port 389 or 636 at example.com, which is back to the same server.

  • The application will continue and read the rest of the objects in the domain as normal.

Problems like this are most commonly caused by the server that the Jenkins application is running on not having the same DNS server as the Active Directory server.

Login fails with HTTP 504 Gateway Timeout

In case you try to login and it never ends producing a HTTP 504 Gateway Timeout screen, then it is suggested to reduce the LDAP timeout values. By default, this plugin injects limits com.sun.jndi.ldap.connect.timeout to 30 seconds and com.sun.jndi.ldap.read.timeout to 60 seconds. It might happen that the HTTP session times out even before this happens, so it is suggested to reduce those values significantly. Something between 20 and 30 seconds might be a good start.

com.sun.jndi.ldap.read.timeout and com.sun.jndi.ldap.connect.timeout can be customized in the LDAP configuration under Manage Jenkins -> Configure Global Security -> Authentication -> Security Realm -> LDAP [Environment Properties]

Name: com.sun.jndi.ldap.connect.timeout
Values: 20000  //limit to 20 seconds
Name: com.sun.jndi.ldap.read.timeout
Values: 20000 //limit to 20 seconds

This issue produces the following logs in Jenkins where we can see that nothing is exposed after Searching for user. The issue tipically happens in Active Directory environments where the LDAP catalog is used (ports 389 or 636). It seems that there might be a bug in the JDK library which handles the connectivity under certain unknown conditions. The ldap library in Java keeps waiting for more groups that the user is a member of, when the server already provided all the groups. The timeout limitation might expose this issue.

The underlaying issue will only be totally fixed in case you switch from LDAP catalog to Global Catalog (ports 3268 or 3269).

Creating InitialDirContext with environment {java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.referral=follow, java.naming.security.principal=CN=user,OU=Service Accounts,OU=Misc,OU=Common,DC=example,DC=com, com.sun.jndi.ldap.connect.timeout=30000, com.sun.jndi.ldap.connect.pool=true, com.sun.jndi.ldap.read.timeout=60000, java.naming.provider.url=ldaps://ldap-aws-example.com:636/DC=example,DC=com, java.naming.security.authentication=simple, java.naming.security.credentials=******}
Sep 09, 2020 3:36:55 PM INFO org.acegisecurity.ldap.DefaultInitialDirContextFactory setProviderUrl
 URL 'ldaps://ldap.example.com:636/DC=example,DC=com', root DN is 'DC=example,DC=com'
Sep 09, 2020 3:37:17 PM FINE org.acegisecurity.ldap.search.FilterBasedLdapUserSearch searchForUser
Searching for user 'user', with user search [ searchFilter: 'sAMAccountName={0}', searchBase: 'DC=example,DC=com', scope: subtreesearchTimeLimit: 0derefLinkFlag: false ]
Sep 09, 2020 3:37:17 PM FINE org.acegisecurity.ldap.DefaultInitialDirContextFactory connect

Diagnostic Steps

  • Change the port number you are attempting to connect with. If you were using port 389 change it to 3268 If you were using port 636 change it to 3269. This may work because a global catalog server returns referrals on 389 to refer to the greater AD "forest", but acts like a regular LDAP server on 3268 (and 3269 for LDAPS).

Configure the server that the Jenkins application is running on to use the DNS server that the Active Directory server is integrated with.

Double check if the DNS server address has been changed recently. Since DNS server record the Jenkins applications information, please delete the Jenkins application address information from the DNS server to resolve the issue.

If this is not possible, disable Follow Referrals by not using the LDAP Plugin and instead using the Active Directory Plugin where this is a system configurable property: -Dhudson.plugins.active_directory.referral.ignore=true

Further Troubleshooting

The Troubleshooting Steps on the LDAP Plugin Wiki are incredibly valuable and in most cases can resolve your issue. If you are still experiencing an issue, please contact support@cloudbees.com to submit a support request.

The latest update of this article has been tested with: