How to troubleshoot LDAP configuration
Overview
When having issues with LDAP authentication we need to look up the actual LDAP queries executed byJFrog PlatformorJFrog Artifactoryand a corresponding response returned by LDAP directory. In this article, we will show how to capture the network traffic with tcpdump, then use the advantage of WireShark UI to analyze, filter, and troubleshoot LDAP transactions.
tcpdump– is a command-line network packet analyzer that will help us to gather the information that cannot be found in the logs. tcpdump is a standard package in most Linux distributions, and you can get it here:https://www.tcpdump.org/.
WireShark– is an open-source network packet analyzer with user-interface which is helpful in troubleshooting and analyzing LDAP connectivity. For more information about the tool and download links, refer tohttps://www.wireshark.org/.
The examples in this article use the following configuration:
JFrog Platform:10.132.0.88
LDAP Server:10.132.0.2
LDAP Port:389
LDAP Settings:
LDAP Group Settings:
The LDAP tree:
Instructions
1. Run tcpdump and start capturing network traffic from the JFrog Platform / Artifactory server host.
We will use the following command options:
-i →Listen on interface. If unspecified, tcpdump searches the system interface list for the lowest numbered, configured up interface. An interface argument of “any” can be used to capture packets from all interfaces.
-n →Don't convert addresses (i.e., host addresses, port numbers, etc.) to names.
-wfile→Write the raw packets to file rather than parsing and printing them out.
host →
port →
Example:$ tcpdump -i any -n -w /var/opt/jfrog/artifactory/log/ldap.pcap host 10.166.0.2 and port 389
2. While tcpdump is running, perform one of the following LDAP transactions:
Attempt to log in to JFrog Platform / Artifactory that is using LDAP authentication
Make a test connection from the LDAP Settings
Attempt to import LDAP Groups in the LDAP Group Settings
3.
4. Open the tcpdump capture file (ldap.pcap) in Wireshark.
You may now take the advantage of Wireshark to filter the traffic while viewing, eg. filter by LDAP/TCP protocol (Display Filters).
Analyzing LDAP connectivity
Now we can analyze the tcpdump capture file (ldap.pcap) to determine if JFrog Platform / Artifactory is able to connect to the LDAP server.
1. The following TCP sequence (a TCP 3-way handshake) is seen when the TCP connection to the LDAP server established successfully. If you just see the SYN going and no SYN, ACK returning then the LDAP server is not reachable from the JFrog Platform / Artifactory host.
1 10.132.0.88 10.166.0.2 TCP 76 43114 → 389 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=3831820 TSecr=0 WS=128
2 10.166.0.2 10.132.0.88 TCP 76 389 → 43114 [SYN, ACK] Seq=0 Ack=1 Win=28160 Len=0 MSS=1420 SACK_PERM=1 TSval=958410 TSecr=3831820 WS=128
3 10.132.0.88 10.166.0.2 TCP 68 43114 → 389 [ACK] Seq=1 Ack=1 Win=28416 Len=0 TSval=3831852 TSecr=958410
2. In the example below, we may see the SYN request is being retransmitted and no SYN, ACK returning. If you see this, verify that your LDAP server is UP, the LDAP URL you configured is valid, and network configuration (proxy, firewall, router, etc) is allowing the traffic to reach the LDAP server.1 10.132.0.88 10.166.0.2 TCP 76 47692 → 389 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=4991787 TSecr=0 WS=128
2 10.132.0.88 10.166.0.2 TCP 76 [TCP Retransmission] 47692 → 389 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=4992788 TSecr=0 WS=128
3 10.132.0.88 10.166.0.2 TCP 76 [TCP Retransmission] 47692 → 389 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=4994792 TSecr=0 WS=128
4 10.132.0.88 10.166.0.2 TCP 76 [TCP Retransmission] 47692 → 389 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=4998800 TSecr=0 WS=128
LDAP User Search
The JFrog Platform / Artifactory performs a search to find the user and obtain the user's DN. The search request is built according to the provided configuration in the LDAP Settings.
1. From the following output, you can see that LDAP User Search returned with 1 result since the user is present in Active Directory. In packet number 2 we see the user DN.1 10.132.0.88 10.166.0.2 LDAP 134 searchRequest(16) "ou=Users,dc=test,dc=com" wholeSubtree
2 10.166.0.2 10.132.0.88 LDAP 398 searchResEntry(16) "cn=Valeriy Petrov,ou=Users,dc=test,dc=com"
3 10.166.0.2 10.132.0.88 LDAP 82 searchResDone(16) success [1 result]
User Search request for “valeriyp” in WireShark (Packet 1):
User Search response (Packet 2):
2. The following example shows a search that did not match any user in Active Directory.
User Search request for “test”, the user “test” is not found in AD, returned “0 results”:1 10.132.0.88 10.166.0.2 LDAP 130 searchRequest(7) "ou=Users,dc=test,dc=com" wholeSubtree
2 10.166.0.2 10.132.0.88 LDAP 82 searchResDone(7) success [0 results]
Request (Packet 1):
Response (Packet 2):
LDAP User authentication
1. The example below shows a bind request and the successful bind response from the LDAP service.1 10.132.0.88 10.166.0.2 LDAP 131 bindRequest(1) "cn=Valeriy Petrov,ou=Users,dc=test,dc=com" simple
2 10.166.0.2 10.132.0.88 LDAP 82 bindResponse(1) success
The user DN found in the LDAP search will be sent in the bindRequest. WireShark masks the password replacing it with the word ”simple”. If we inspect the packet we could see the password in the clear text, “password” in the example below.
2. The example below shows invalidCredentials error in the bindResponse. It may happen if the entered password is not valid.1 10.132.0.88 10.166.0.2 LDAP 129 bindRequest(1) "cn=Valeriy Petrov,ou=Users,dc=test,dc=com" simple
2 10.166.0.2 10.132.0.88 LDAP 82 bindResponse(1) invalidCredentials
In Wireshark:
Analyzing LDAP Group search
1. In the example below, we see a successful search for groups in Active Directory. Note that searchRequest queries the LDAP server and applies the Filter defined in the LDAP Group Settings, starting at the DN defined in the Search Base.1 0.000000 10.132.0.88 10.166.0.2 LDAP 351 searchRequest(22) "ou=Groups,dc=test,dc=com" wholeSubtree
2 0.035339 10.166.0.2 10.132.0.88 LDAP 207 searchResEntry(22) "cn=developers,ou=Groups,dc=test,dc=com"
3 0.035377 10.166.0.2 10.132.0.88 LDAP 222 searchResEntry(22) "cn=users,ou=Groups,dc=test,dc=com"
4 0.035382 10.166.0.2 10.132.0.88 LDAP 197 searchResEntry(22) "cn=support,ou=Groups,dc=test,dc=com"
5 0.035385 10.166.0.2 10.132.0.88 LDAP 224 searchResEntry(22) "cn=admins,ou=Groups,dc=test,dc=com"
6 0.035389 10.166.0.2 10.132.0.88 LDAP 246 searchResEntry(22) "cn=service,ou=nested,ou=appgroups,ou=Groups,dc=test,dc=com"
12 0.035482 10.166.0.2 10.132.0.88 LDAP 119 searchResDone(22) success [5 results]
2. The following example shows the LDAP error noSuchObject in the Group search request when no Group objects were found, therefore “0 results” returned. If you encounter such error, check the Search Base and Filter configured properly.1 0.000951 10.132.0.88 10.166.0.2 LDAP 360 searchRequest(2) "ou=IncorrectGroups,dc=test,dc=com" wholeSubtree
2 0.034433 10.166.0.2 10.132.0.88 LDAP 96 searchResDone(2) noSuchObject [0 results]
Example of a successful login and group association
1. In this example, the user “valeriyp” is the member of the group “support” logs in to the JFrog Platform.
The flow in Wireshark UI:
In this example we can see:
1. Successful user searchRequest that returned “valeriyp” user DN1 0.000000 10.132.0.88 10.166.0.2 LDAP 134 searchRequest(13) "ou=Users,dc=test,dc=com" wholeSubtree
2 0.035437 10.166.0.2 10.132.0.88 LDAP 398 searchResEntry(13) "cn=Valeriy Petrov,ou=Users,dc=test,dc=com"
2. Successful user bindRequest withcn=Valeriy Petrov,ou=Users,dc=test,dc=comand “simple” (masked password). To reveal the password, inspect the raw data of this packet, in Wireshark UI.
9 0.073018 10.132.0.88 10.166.0.2 LDAP 131 bindRequest(1) "cn=Valeriy Petrov,ou=Users,dc=test,dc=com" simple
11 0.105634 10.166.0.2 10.132.0.88 LDAP 82 bindResponse(1) success
3. Successful group searchRequest
15 0.129357 10.132.0.88 10.166.0.2 LDAP 435 searchRequest(14) "ou=Groups,dc=test,dc=com" wholeSubtree
19 0.162667 10.166.0.2 10.132.0.88 LDAP 224 searchResEntry(14) "cn=support,ou=Groups,dc=test,dc=com"
Finding LDAP Response Time
LDAP响应时间计算和显示in the LDAP section. Following all the searchResultReference and SearchResultEntry responses, the LDAP server returns a searchResultDone response, which contains an indication of success or details any errors that have occurred. In the packet details window, expand the LDAP section. In this section, we may find the field with the LDAP server response time.

过滤长LDAP响应时间
Now when we know how to check the LDAP response time, we might want to create a filter based on that response time and display only the LDAP responses that take more than, or less than a set time.
This is especially helpful in case authentication against Artifactory becomes slow and we want to know if this is due to the LDAP server.
In this example, we are using the filter syntax below to display only the responses that take more than 30 ms.ldap.time >= 0.03
For further reading:
LDAP Debugging Guide
//m.si-fil.com/knowledge-base/ldap-debugging-guide/
How does LDAP/AD group sync/mapping work?
//m.si-fil.com/knowledge-base/how-does-ldap-ad-group-sync-mapping-work/
