How to diagnose LDAP integration problems?

Issue

  • You are trying to activate the authentication to an LDAP service and you don’t succeed.
  • Authentication via LDAP is set in Jenkins, but certain users cannot log in (“UserX”).
  • LDAP integration troubleshooting.

Environment

  • Jenkins
  • CloudBees Jenkins Enterprise (CJE)
  • CloudBees Jenkins Operations Center (CJOC)
  • LDAP plugin

Resolution

Troubleshooting

I. Only configure Security as Security Realm : LDAP, keeping Authorisations to anyone can administrate Jenkins. This will allow you to update the Security configuration and try to login without loosing your administrator access

II. Create/Update a dedicated Logs recorder ( LDAP) as explained in Jenkins Logging including the following list:

  • hudson.security = ALL
  • jenkins.security = ALL
  • org.acegisecurity.ldap = ALL
  • org.acegisecurity.providers.ldap = ALL

Having done that, first test your AD settings and then try to log in with a LDAP user (“UserX”).

III. Review the troubleshooting part of the LDAP plugin documentation and try to launch the groovy script in $JENKINS_URL/script.

IV. With the help of ldapsearch command validate your LDAP settings in Jenkins, which makes use those LDAP attributes by the Java Naming and Directory InterfaceTM (JNDI) for accessing to naming and directory services

Note: The following commands works for under ldap:// connections (not ldaps://)

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

Mapping ldapsearch - Jenkins LDAP plugin configuration: The above ldapsearch fields should match with the following fields in the below LDAP plugin configuration:

Under $JenkinsURL/configureSecurity/ > Security Realm > LDAP setting

ldap_config

  • <IP_ADDRESS>:<PORT> -> Server

  • <searchbase> -> rootDN

  • <binddn> & <passwd> -> Manager DN and password - Optional, in the case your LDAP server doesn’t support anonymous binding.

On the other hand, in $JenkinsURL/login/, <userid> is the user you would like to authenticated in Jenkins. It can be the managerDN itself or for a different user on the tree.

Jenkins will bind as the manager to do the user lookup. Then, it will rebind as the user to check its password and get the user information

Notes:

  1. Execute the following commands in the Jenkins Server side, ldapsearch is included in ldap-utils for Linux based System. Please, for testing purposes, install ldap-utils in the same server as Jenkins.
  2. Take care to escape special character with \ in case it is necessary.
  3. Use ldaps just for TLS end-points ( ldaps://<IP_ADDRESS>:<PORT>).
  4. Regarding TCP and UDP ports by default ldap is on 389, or on port 636 for ldaps.
  5. For the following commands, in case you want to avoid your password to get discovered, -w "<passwd>" can be replaced by:
    • -W, which it will ask you for the password.
    • -y ./pass.txt, so /pass.txt contains your credentials.

V. Ensure the <binddn> is correct. For this task, graphical tools such as JExplorer might be helpful to understand the forest of your LDAP service.

VI. (Optional) In case you have set a group search filter. Ensure the filter was set-up correctly.

Group search filter is relative to the Group search base, if Group search base is left blank then root DN would be taken as default.

VII. Attach to the ticket results from the steps II, III, IV and V (*binddn* path)

EXAMPLE/SCENARIO

Connect Jenkins with a LDAP (‘example.com’) running on a Linux Server

Check II for example.com

Saving your LDAP setting

After testing successfully and saving your setting, a similar output like this would be expected:

...

Oct 07, 2016 1:19:41 PM INFO org.acegisecurity.ldap.DefaultInitialDirContextFactory setProviderUrl
 URL 'ldap://ldap.example.com:389 /dc=example,dc=com', root DN is 'dc=example,dc=com'
Oct 07, 2016 1:19:41 PM INFO org.acegisecurity.ldap.search.FilterBasedLdapUserSearch 
SearchBase not set. Searches will be performed from the root: dc=example,dc=com
Oct 07, 2016 1:19:41 PM INFO org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator setGroupSearchBase
groupSearchBase is empty. Searches will be performed from the root: dc=example,dc=com
Oct 07, 2016 1:19:41 PM FINER hudson.security.SecurityRealm createFilter
ENTRY
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: hudson.security.HttpSessionContextIntegrationFilter2@6d12caad
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: jenkins.security.BasicHeaderProcessor@3fcda161
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: hudson.security.AuthenticationProcessingFilter2@121a1c7f
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: org.acegisecurity.ui.rememberme.RememberMeProcessingFilter@5df2ee2d
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: org.acegisecurity.providers.anonymous.AnonymousProcessingFilter@26ce009c
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: jenkins.security.ExceptionTranslationFilter@745a6b8d
Oct 07, 2016 1:19:41 PM FINEST hudson.security.ChainedServletFilter init
ChainedServletFilter contains: hudson.security.UnwrapSecurityExceptionFilter@36e1789d
Oct 07, 2016 1:19:43 PM FINE hudson.security.GlobalSecurityConfiguration doConfigure
security saved: true
Oct 07, 2016 1:19:43 PM FINER jenkins.security.ExceptionTranslationFilter doFilter
Chain processed normally
Oct 07, 2016 1:19:43 PM FINER hudson.security.HudsonFilter doFilter
ENTRY
Oct 07, 2016 1:19:43 PM FINER hudson.security.ChainedServletFilter doFilter
ENTRY

...

Logging with a user

LDAP logging

After logging successfully with a user (“exampleUser”), a similar output like this would be expected:


Searching for roles for user 'exampleUser', DN = 'ou=people,dc=example,dc=com', with filter (| (member={0}) (uniqueMember={0}) (memberUid={1})) in search base '' Sep 28, 2016 9:16:07 AM FINE org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator getGroupMembershipRoles Roles from search: [] Sep 28, 2016 9:16:07 AM FINE org.acegisecurity.context.HttpSessionContextIntegrationFilter storeSecurityContextInSession SecurityContext stored to HttpSession: 'jenkins.security.NonSerializableSecurityContext@7d7ba608: Authentication: org.acegisecurity.providers.UsernamePasswordAuthenticationToken@7d7ba608: Username: org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl@a02f3a2; Password: [PROTECTED]; Authenticated: true; Details: org.acegisecurity.ui.WebAuthenticationDetails@0: RemoteIpAddress: xxx.xx.xx.xxx; SessionId: 1y1bv76m3xcvs1ln8270d5tmtj; Granted Authorities: authenticated'

Check III for example.com

Setting String[] names = ["exampleUser"] a expected console output would look like this:

It is a USER: org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl@96e3122 
Has groups/authorities: [authenticated]

Check IV for example.com

Examples:

1) ldapsearch -LLL -H ldap://ldap.example.com:389 -M -D "ou=people,dc=example,dc=com" -b "dc=example,dc=com" -w "pass".

This will retrieve the full organization.

2) 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"

A expected output would look like this:

dn: people,dc=example,dc=com 
uid: exampleUser 
...
displayName: Example User 
cn: Example User
mail: exampleUser@example.com
...

Check V for example.com

From the below image, it can be seen taken the <binddn> ( manager DN) for “exampleUser” as “uid=colin=people,dc=example,dc=com”

LDAP on jexplorer

References

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.