PRACTITIONER GUIDE | ACTIVE DIRECTORY SECURITY
Practitioner GuideUpdated 12 min read

LDAP Signing and Channel Binding: How to Enforce Secure LDAP on Domain Controllers Without Breaking AD-Integrated Applications

Event 2889
is generated in the Directory Service event log when a client performs an unsigned LDAP bind -- the primary tool for identifying non-compliant clients
None
LDAP signing level (the default) allows unsigned LDAP -- Require signing blocks unsigned binds entirely
389
standard LDAP port (unencrypted) -- channel binding only applies to LDAPS (636) because it requires a TLS connection to bind to
30 days
recommended audit period before enabling LDAP signing enforcement, to capture all LDAP client applications including those that authenticate infrequently

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

Unsigned LDAP allows a man-in-the-middle attacker to modify directory queries and responses in transit, manipulate authentication outcomes, and replay authentication tokens. Despite this, unsigned LDAP has been the default on Windows domain controllers for decades because enforcing signing breaks older applications. The audit-first approach resolves this: generate Event ID 2889 for 30 days to identify every client making unsigned LDAP binds, then remediate those clients or accept the loss of their LDAP functionality before enabling enforcement.

Enabling the LDAP Diagnostic Event Log to Find Unsigned Binders

The LDAP diagnostic event log is disabled by default. Enable it on domain controllers to generate Event ID 2889 for every unsigned LDAP bind:

# Enable LDAP diagnostics for unsigned bind detection on all DCs
$DCs = Get-ADDomainController -Filter * | Select-Object -ExpandProperty HostName

foreach ($DC in $DCs) {
    Invoke-Command -ComputerName $DC -ScriptBlock {
        # Set LDAP Interface Events diagnostic level to 2 (verbose) for signing detection
        $ldapDiagPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics"
        Set-ItemProperty -Path $ldapDiagPath -Name "16 LDAP Interface Events" -Value 2
        Write-Output "LDAP diagnostics enabled on $env:COMPUTERNAME"
    }
}

After enabling, unsigned LDAP bind attempts generate Event ID 2889 in the Directory Services event log on the DC that processed the bind. The event contains:

  • The client's IP address
  • The distinguished name (DN) of the account used for the bind
  • The LDAP bind type (Simple / SASL without signing)

Collect Event 2889 from all DCs over 30 days:

# Collect Event 2889 across all DCs
$results = foreach ($DC in $DCs) {
    Get-WinEvent -ComputerName $DC -FilterHashtable @{
        LogName = 'Directory Service'
        Id = 2889
        StartTime = (Get-Date).AddDays(-30)
    } -ErrorAction SilentlyContinue | ForEach-Object {
        $xml = [xml]$_.ToXml()
        [PSCustomObject]@{
            DC = $DC
            Time = $_.TimeCreated
            ClientIP = $xml.Event.EventData.Data[0].'#text'
            Account = $xml.Event.EventData.Data[1].'#text'
            BindType = $xml.Event.EventData.Data[2].'#text'
        }
    }
}
$results | Export-Csv -Path "unsigned_ldap_binders.csv" -NoTypeInformation

Identifying and Categorizing Unsigned LDAP Sources

After collecting 2889 events, group the client IPs into categories to prioritize remediation:

# Summarize unsigned LDAP sources by client IP and account
Import-Csv -Path "unsigned_ldap_binders.csv" |
    Group-Object ClientIP |
    Select-Object @{N='ClientIP';E={$_.Name}},
                  @{N='EventCount';E={$_.Count}},
                  @{N='Accounts';E={($_.Group.Account | Sort-Object -Unique) -join '; '}} |
    Sort-Object EventCount -Descending |
    Format-Table -AutoSize

Common unsigned LDAP source categories:

Network devices (switches, printers, firewalls): These use LDAP for authentication (802.1X, LDAP-based login). Most cannot be upgraded to support signing. Solution: migrate these to LDAPS (port 636) with a valid DC certificate, or use a separate read-only DC for LDAP authentication from legacy devices with a limited credential scope.

Monitoring and backup systems: SNMP-based monitoring tools, backup agents, and ITSM integrations often use LDAP for user lookups. Most modern versions support LDAPS. Update to the current version and configure the LDAPS endpoint.

Legacy applications: On-premises applications with hardcoded LDAP endpoints. Solution: configure the application to use LDAPS (port 636) with certificate validation, or move authentication to SAML/OIDC via ADFS/Entra ID.

Automation scripts: PowerShell or Python scripts using the DirectorySearcher or ldap3 library with unsigned binds. Update the script to use LDAPS or SASL signing.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Configuring LDAPS on Domain Controllers

LDAPS requires each DC to have a valid server certificate. In environments with an internal PKI, deploy certificates automatically via autoenrollment:

# Verify DCs have certificates with Server Authentication OID (1.3.6.1.5.5.7.3.1)
foreach ($DC in $DCs) {
    $cert = Invoke-Command -ComputerName $DC -ScriptBlock {
        Get-ChildItem Cert:\LocalMachine\My | 
        Where-Object { $_.EnhancedKeyUsageList.ObjectId -contains '1.3.6.1.5.5.7.3.1' } |
        Select-Object Subject, NotAfter, Thumbprint | Select-Object -First 1
    }
    Write-Output "$DC - Certificate: $($cert.Subject), Expires: $($cert.NotAfter)"
}

If DCs do not have suitable certificates:

  1. Create a certificate template for Kerberos Authentication or Domain Controller Authentication in your CA
  2. Configure autoenrollment via GPO: Computer Configuration > Windows Settings > Security Settings > Public Key Policies > Certificate Services Client - Auto-Enrollment
  3. Force enrollment: certutil -pulse or gpupdate /force

Verify LDAPS is functional after certificate deployment:

# Test LDAPS connectivity from a client (Linux)
ldapsearch -H ldaps://dc01.domain.com -x -b "DC=domain,DC=com" -D "svc-ldap@domain.com" -W "(objectClass=domain)" -LLL

# Test from Windows
ldp.exe # Connect to DC on port 636 using SSL

Enabling LDAP Signing and Channel Binding via GPO

After remediating or documenting all unsigned LDAP clients, enable signing and channel binding on domain controllers:

LDAP Signing Policy (Domain Controller-side requirement):

GPO: Default Domain Controllers Policy (or a DC-specific GPO)
Path: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options
Setting: Domain controller: LDAP server signing requirements
Value: Require signing

LDAP Channel Binding (requires Windows Server 2019 or later with the March 2020 patch):

Path: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options
Setting: Domain controller: LDAP server channel binding token requirements
Value: Always (most secure) or When supported

Set to When supported initially, which only enforces channel binding for clients that advertise channel binding support. Move to Always after confirming all clients are compatible.

Client-side setting (enforce on all domain-joined clients as well):

GPO: Default Domain Policy or workstation/server OU GPO
Path: Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options
Setting: Network security: LDAP client signing requirements
Value: Require signing

Deploy in this sequence:

  1. Enable DC diagnostic (Event 2889) and collect for 30 days
  2. Remediate unsigned LDAP clients
  3. Set DC signing requirement to Negotiate signing (allows signed or unsigned, but logs violations)
  4. Monitor for new Event 2889 events
  5. After 2 weeks of zero 2889 events, set DC signing requirement to Require signing

Common Application Compatibility Breaks After Enforcement

Despite thorough pre-enforcement auditing, some applications surface only after enforcement because they perform LDAP binds infrequently (password reset workflows, quarterly report generation, emergency access scenarios).

Diagnosing post-enforcement breaks: When an application fails after LDAP signing enforcement, check:

  1. The application's error log for LDAP authentication errors (LDAP error code 52 = Unavailable, 49 = Invalid credentials after signing failure)
  2. The DC Directory Services event log for Event 2889 (if any remain after enabling enforcement, the diagnostic level must be rechecked)
  3. Network capture from the application server to verify whether it is connecting to port 389 (unsigned) or 636 (LDAPS)

Common break scenarios and fixes:

Application TypeBreak CauseFix
Cisco ISE, Aruba ClearPassLDAP auth on port 389Configure LDAPS endpoint
Splunk LDAP authSigning negotiation failureUpgrade to current Splunk; enable SSL in LDAP settings
VMware vCenterSimple bind on port 389Configure identity source to use LDAPS
Legacy IBM/Oracle appsHardcoded DirectorySearcherUpdate app config to LDAPS or abstract via ADFS SAML
Ansible playbooksldap3 library without TLSAdd use_ssl=True, use_server_side_sasl=False to ldap3 connection

The bottom line

LDAP signing and channel binding enforcement is a meaningful security control that requires audit-before-enforcement discipline. Enable Event ID 2889 on all domain controllers for 30 days before touching any signing GPO. Collect, categorize, and remediate all unsigned LDAP clients. Migrate devices and applications to LDAPS (port 636) wherever possible. Deploy the DC signing requirement in stages: Negotiate, then Require, with monitoring between stages. The process is operationally complex but closes a man-in-the-middle attack surface that has been exploited in real-world domain compromise scenarios.

Frequently asked questions

Does LDAP signing protect against NTLM relay attacks?

Partially. LDAP signing prevents tampering with LDAP requests in transit and prevents simple LDAP relay (where an attacker relays an unsigned LDAP authentication to a DC). However, NTLM relay attacks that relay authentication to LDAP specifically target unsigned LDAP. Enabling LDAP signing eliminates this relay attack vector. For comprehensive NTLM relay protection, also disable NTLM where possible, enable SMB signing, enable Extended Protection for Authentication (EPA), and deploy Windows Defender Credential Guard.

What is the difference between LDAP signing and LDAPS?

LDAP signing adds a cryptographic signature to LDAP protocol messages to detect tampering, but traffic is not necessarily encrypted. LDAPS (LDAP over SSL/TLS on port 636) encrypts the entire LDAP session. LDAPS provides both confidentiality (encryption) and integrity (tampering detection). LDAP signing on port 389 provides integrity only, without confidentiality. For maximum security, use LDAPS (port 636) plus LDAP signing. Channel binding adds the additional protection of tying the LDAP session to the specific TLS connection, preventing TLS stripping attacks.

Can I force LDAP signing without affecting Kerberos authentication?

Yes. LDAP signing and channel binding apply only to LDAP protocol traffic. Kerberos authentication (which is the default and preferred authentication protocol for domain-joined Windows clients) is not affected. Kerberos does not use LDAP port 389 or 636 for authentication -- it uses the Kerberos ports (88/UDP and 88/TCP). LDAP signing enforcement will not break Kerberos-authenticated resources.

How do I handle network printers that cannot use LDAPS?

Network printers that only support unsigned LDAP on port 389 cannot be made to work with LDAP signing enforcement. Options: (1) Migrate to cloud print solutions (Universal Print in Microsoft 365) that eliminate LDAP-based print authentication, (2) Use a dedicated read-only domain controller (RODC) or LDAP proxy (such as OpenLDAP with SASL signing) that sits between the printers and production DCs, (3) Accept the printers as a documented exception and network-isolate them so their unsigned LDAP traffic is limited to the print management VLAN only.

Does enabling LDAP channel binding break LDAPS connections?

No. LDAP channel binding applies to LDAP sessions that use SASL authentication (Negotiate/Kerberos/NTLM) on standard port 389. LDAPS (port 636) establishes a TLS tunnel first, and SASL authentication occurs inside the TLS session. Channel binding on LDAPS is different from the domain controller's CBT (Channel Binding Token) enforcement for port 389. Enabling LDAP channel binding on the domain controller does not affect LDAPS connections from clients that use LDAPS correctly. The concern with channel binding is applications that use port 389 SASL without CBT support, not applications using LDAPS.

How do I identify which applications in my environment do not support LDAP signing?

Enable LDAP diagnostic logging on domain controllers to capture unsigned and unencrypted LDAP binds. Set the registry value HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics\16 LDAP Interface Events to 2 (Basic). This causes Event ID 2886 (unsigned LDAP bind warning) and Event ID 2887 (unsigned LDAP connection statistics) to appear in the Directory Service event log. After 24 hours, review Event 2887 for the count of unsigned binds and the source IP addresses and application names performing them. Microsoft also provides a script (Get-LDAPClientSettings.ps1) that enumerates which machines are making unsigned LDAP connections. Address each application before setting the domain LDAP signing requirement to Required, as setting Required blocks unsigned clients immediately.

Sources & references

  1. Microsoft: 2020 LDAP channel binding and LDAP signing requirements
  2. CISA: Securing Active Directory: LDAP Signing and Channel Binding
  3. Microsoft: How to enable LDAP signing in Windows Server

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.