PingCastle’s “A LDAP authentication without signature enforcement was allowed” means a domain controller accepts unsigned LDAP binds, which lets an attacker relay or tamper with LDAP sessions. To enforce LDAP signing, log unsigned binds with Event 2889, fix those clients, change any GPO that sets client signing to None, and set “Domain controller: LDAP server signing requirements” to Require signing.
The setting is a single dropdown. The real work is finding what still binds without signing before the DCs start rejecting it.
What the scanner is actually detecting
Two PingCastle rules usually appear together, plus a matching Microsoft Defender for Identity recommendation.
| Source | Finding text | How it is detected |
|---|---|---|
| PingCastle A-DCLdapSign | A LDAP authentication without signature enforcement was allowed | PingCastle authenticates to each DC over LDAP with and without requesting integrity. If the unsigned bind succeeds, the DC is listed. Local policy on the scanning machine is ignored. |
| PingCastle A-LDAPSigningDisabled | At least one GPO disables explicitly LDAP client signature | PingCastle reads GPO security settings and flags any enabled, linked GPO that sets Network security: LDAP client signing requirements to None (LDAPClientIntegrity = 0). |
| Defender for Identity | Resolve unsecure domain configurations | Secure Score recommended action: Enforce LDAP Signing policy to “Require signing”. |
Both PingCastle rules sit in the Anomalies category and add 5 points each. The first covers the server side (DCs accepting unsigned binds), the second the client side (a GPO telling Windows machines not to request signing).
Real-world risk, stated honestly
LDAP on port 389 carries directory reads and writes. If the DC does not require signing, a SASL bind (Negotiate, Kerberos, NTLM or Digest) can proceed without integrity protection, and a simple bind sends the password in clear text. Microsoft describes two consequences: replay of captured authentication, and man-in-the-middle modification of LDAP requests so the DC acts on forged data.
In practice the concern is relay. An attacker who can intercept or coerce an authentication from a privileged user or computer account relays it to the DC’s LDAP service and makes changes as that identity. PingCastle’s example is adding a user to an admin group, and Microsoft’s Defender for Identity guidance links unenforced LDAP signing to the KrbRelayUp privilege escalation technique.
The limits: the attacker needs a foothold inside the network and an authentication to relay, and this is not remote code execution by itself. It is a privilege escalation path. Reducing NTLM usage across the domain shrinks the relay surface further. LDAP signing does not protect LDAPS on port 636; that is the job of LDAP channel binding, a separate PingCastle rule.
Defaults matter here. On Windows Server 2022 and earlier, DCs accept unsigned binds unless you configure otherwise. New Windows Server 2025 Active Directory deployments require signing by default, but DCs upgraded in place keep their existing policy.
How to confirm it on the host
On each domain controller, in an elevated PowerShell session:
# 1 = None, 2 = Require signing (no value = policy not defined)
Get-ItemProperty -Path 'HKLM:SYSTEMCurrentControlSetServicesNTDSParameters' -Name LDAPServerIntegrity -ErrorAction SilentlyContinue
# Daily summaries: 2886 = signing not required, 2887 = unsigned binds accepted, 2888 = unsigned binds rejected
Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2886,2887,2888} -MaxEvents 10 -ErrorAction SilentlyContinue |
Format-List TimeCreated, Id, Message
Event 2887 gives you two counts for the previous 24 hours: simple binds without SSL/TLS and SASL binds without signing. It does not tell you who made them.
On a Windows client or member server, check what the machine asks for:
# 0 = None, 1 = Negotiate signing (default), 2 = Require signing
Get-ItemProperty -Path 'HKLM:SYSTEMCurrentControlSetServicesLDAP' -Name LDAPClientIntegrity
gpresult /scope computer /h C:Temprsop.html
To find every GPO that defines the client setting (run on a machine with the GroupPolicy module):
Get-GPO -All | ForEach-Object {
if ((Get-GPOReport -Guid $_.Id -ReportType Xml) -match 'LDAPClientIntegrity') { $_.DisplayName }
}
Open each GPO it returns and check the value; the one named in the PingCastle detail sets None.
How to fix it
Step 1: identify clients making unsigned binds
Turn on LDAP interface diagnostics on every DC. Microsoft notes this is not a performance concern, but it does increase the number of Directory Service events:
reg add HKLMSYSTEMCurrentControlSetServicesNTDSDiagnostics /v "16 LDAP Interface Events" /t REG_DWORD /d 2
Each unsigned bind now logs Event 2889 with the client IP and port, the identity used, and a binding type. Collect a full business cycle, including month-end jobs, then summarize:
Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2889} -ErrorAction SilentlyContinue |
ForEach-Object {
[PSCustomObject]@{
ClientIP = $_.Properties[0].Value -replace ':d+$', ''
Identity = $_.Properties[1].Value
BindingType = $_.Properties[2].Value # 0 = SASL without signing, 1 = simple bind without TLS
}
} | Sort-Object ClientIP, Identity, BindingType -Unique |
Export-Csv C:Tempunsigned-ldap-binds.csv -NoTypeInformation
Run it on every DC, because each one logs only the binds it received.
Step 2: fix the clients
- Binding type 0 (SASL without signing): Windows machines request signing by default, so a Windows host here usually has LDAPClientIntegrity set to 0 by policy (step 3). Non-Windows systems need signing enabled in their own LDAP client configuration, per the vendor’s documentation.
- Binding type 1 (simple bind without TLS): the password is crossing the network in clear text. Move the application to LDAPS on port 636 or StartTLS on 389. Both need a certificate on the DCs, and the change is made in each application’s own settings.
Step 3: remove “None” from client GPOs (A-LDAPSigningDisabled)
In the GPO named in the PingCastle detail, go to Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options > Network security: LDAP client signing requirements and set it explicitly to Negotiate signing or Require signing. Do this before step 4: Microsoft warns that a DC requiring signing loses clients that are not configured for it.
Step 4: require signing on domain controllers (A-DCLdapSign)
Windows Server 2022 and earlier: edit the Default Domain Controllers Policy, go to Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options, open Domain controller: LDAP server signing requirements, tick Define this policy setting and select Require signing. This writes LDAPServerIntegrity = 2. Run gpupdate /force on the DCs; no restart is required.
Windows Server 2025: the same folder also contains Domain controller: LDAP server signing requirements enforcement, which overrides the older policy. Enabled enforces signing regardless of the older policy, Disabled hands control back to it, and Not configured has the same effect as Enabled on new deployments. In a mixed-version domain, set the older policy to Require signing so every DC enforces it.
AD LDS instances are configured per instance in the registry: create the DWORD LDAPServerIntegrity with value 2 under HKLMSYSTEMCurrentControlSetServices<InstanceName>Parameters. It takes effect immediately.
How to verify the fix and rescan
- On each DC, LDAPServerIntegrity should read 2. If one DC still shows 1, check that it sits in the Domain Controllers OU and is receiving the policy.
- From a machine with the AD DS admin tools, open ldp.exe, connect to the DC on port 389, choose Connection > Bind, select Simple bind and enter credentials. The expected result is Ldap_simple_bind_s() failed: Strong Authentication Required.
- Watch for the daily Event 2888. Non-zero counts mean clients are now being rejected and need attention.
- Rerun PingCastle from a domain member that is not a DC (PingCastle does not test the DC it runs on): PingCastle.exe –healthcheck –server contoso.local. In Defender for Identity, allow up to 24 hours for the recommendation status to update.
When the audit is finished, set “16 LDAP Interface Events” back to 0, the default.
What can break and how to roll back
- Applications using simple binds on 389: they fail with a strong authentication error until moved to LDAPS or StartTLS.
- Devices doing unsigned SASL binds: non-Windows systems integrated with the domain that never request signing.
- Windows hosts under a “None” GPO: any machine still receiving that setting cannot bind to a DC that requires signing, which can affect Group Policy processing and directory lookups.
- Load balancers doing TLS offload: traffic from the balancer to the DC may arrive as plain LDAP.
Roll back by setting Domain controller: LDAP server signing requirements to None in the Default Domain Controllers Policy (LDAPServerIntegrity = 1) and running gpupdate /force on the DCs. On Windows Server 2025 DCs, also set the enforcement policy to Disabled, because Not configured can behave as Enabled. No restart is needed, so fix the broken client and re-enable quickly.
Common false positive reasons
- A-LDAPSigningDisabled on a GPO that loses precedence. The rule reads GPO contents, not each host’s effective value. A linked GPO setting None is reported even if a higher-precedence GPO overrides it everywhere. Confirm with gpresult and review how GPO precedence decides the winning setting, then remove the stale setting anyway.
- One DC is not receiving the policy. A-DCLdapSign lists DCs individually, so a DC outside the Domain Controllers OU or with SYSVOL replication problems stays flagged while the others pass.
- Scanner coverage gaps. PingCastle skips the DC it runs on, so a clean result from a DC-based scan proves nothing about that DC.
- Timing. The scan ran before the GPO refreshed, or Defender for Identity has not finished its daily update.
FAQ
Does requiring LDAP signing break LDAPS?
No. The server signing requirement does not apply to LDAP over SSL/TLS on port 636, so simple binds over TLS are still accepted.
Is LDAP channel binding the same fix?
No. Channel binding ties authentication to the TLS session on LDAPS and is configured with the LdapEnforceChannelBinding registry value. PingCastle reports it separately as A-DCLdapsChannelBinding.
Do the domain controllers need a reboot?
No. Microsoft documents that both the server and client signing policies take effect without a restart once Group Policy applies.
Should every Windows client be set to Require signing?
Negotiate signing, the default, is enough for DC enforcement. Microsoft recommends Require signing on both sides, but a client set to Require can fail against LDAP servers that do not require signing. Roll it out as part of your Windows Server hardening checklist after you know which LDAP servers your clients use.
Tracking this finding across many hosts
Across several domains, the hard part is tracking which DCs, GPOs and clients are still outstanding. If you use SITEY, it imports findings from 16 scanners and merges duplicates per scanner (not across scanners), its AI triage suggests false positives with evidence for a human to decide, and AI-written remediation scripts run only after human approval through SITEY agents on Windows endpoints. Per-finding retest covers Nessus, Acunetix and Burp only, so confirm closure for other sources with a fresh scan such as a PingCastle healthcheck.
Sources
- Microsoft Learn: How to enable LDAP signing in Windows Server
- Microsoft Learn: Manage LDAP signing using Group Policy
- Microsoft Tech Community: Active Directory Hardening Series, Part 3, Enforcing LDAP Signing
- Microsoft Learn: Defender for Identity identity infrastructure assessments
- PingCastle rule descriptions (A-DCLdapSign, A-LDAPSigningDisabled)