Wednesday, October 30, 2019

Hunting bad LDAP queries on your DC

This is a quick guide to find bad LDAP queries running against your Domain Controller.

To get the needed events on your DC, set the following registry settings using PowerShell:

Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Diagnostics' -Name '15 Field Engineering' -Value "5"
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Parameters' -Name 'Expensive Search Results Threshold' -Value "0"
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Parameters' -Name 'Inefficient Search Results Threshold' -Value "0"
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Parameters' -Name 'Search Time Threshold (msecs)' -Value "120"

Your DC is now logging event 1644, with information about the LDAP queries.

If you are using this cmds any LDAP Query that´s taking over 120ms(Search Time Threshold (msecs)) will be logged.

The Log Level is set to 5 ('15 Field Engineering' -Value "5") that means it logs all events, including debug strings and configuration changes. Also a complete log of the service is recorded.

Expensive LDAP search reults, are the searches those visit large number of entries. The default threshold for expensive search is 10000. We can set it using Expensive Search Results Threshold reg key, in this case we set it to 0 to get all queries.

Inefficient Search Results Threshold, are the searches those return less than 10% of visited entries. The default visited entries threshold limit for inefficient query is 1000 which means if a query visit less than 1000 entries then it will not be consider inefficient query even though if it return no entry. So we set it to 0 to get all queries.

So now you can open the Event Viewer, go to Directory Services log and depending of the number of "bad" LDAP queries, you will see a lot of 1644 events. In this events you will get information like User,Filter,Client and the attribute that preventing Optimization. So with this values you can identify the source and fix it.

Find attached an example event:

Internal event: A client issued a search operation with the following options. 
Starting node:
( |  (uid=Jon.Doe)  (sAMAccountName=Jon.Doe) )  
Search scope:
Attribute selection:
Server controls:
Visited entries:
Returned entries:

Used indexes:
Pages referenced:
Pages read from disk:

Pages preread from disk:

Clean pages modified:

Dirty pages modified:

Search time (ms):
Attributes Preventing Optimization:

In this case you can contact the responsible admin for Client and modify the query to use a better filter. For example if you don´t use the uid field in AD, you can remove it from the LDAP query and just search for teh samaccountname.

If you have enough logs collected, you can revert your changes using the following commands:

Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Diagnostics' -Name '15 Field Engineering' -Value "0"
Remove-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Parameters' -Name 'Expensive Search Results Threshold'
Remove-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Parameters' -Name 'Inefficient Search Results Threshold'
Remove-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Services\NTDS\Parameters' -Name 'Search Time Threshold (msecs)'

1 comment:

  1. Just followed the instructions here and noticed that values for new registry entries specified in double quotes will result them being of type REG_SZ, which is unwanted in these cases as they should be of type DWORD. BTW: Changing an existing entry with a quoted numerical value does not change its type.