How to Configure LDAP over SSL (LDAPS) on Windows Server 2025
By default, Active Directory accepts LDAP connections on TCP port 389 without encryption. Any LDAP bind that transmits a password in clear text — including simple binds used by countless applications — is vulnerable to interception on the network. LDAP over SSL (LDAPS) encrypts the entire LDAP session on TCP port 636 using TLS, protecting credentials and directory data in transit. Windows Server 2025 also enforces LDAP channel binding and LDAP signing by default in newer cumulative update configurations, meaning older insecure binds are actively rejected. This guide covers how to enable LDAPS through certificate enrollment, verify it is working, configure clients, and address the LDAP signing and channel binding requirements that accompany it.
Prerequisites
- Windows Server 2025 domain controller (the changes apply per-DC)
- An Active Directory Certificate Services (AD CS) deployment, or the ability to import a third-party certificate
- The certificate must have the Server Authentication Enhanced Key Usage (EKU OID
1.3.6.1.5.5.7.3.1) - The certificate’s Subject or Subject Alternative Name must match the DC’s FQDN
- The certificate must be installed in the Local Computer → Personal certificate store
- Domain Admin rights or delegated PKI enrollment permissions
- ldp.exe or OpenSSL for verification
Step 1: Understand LDAP vs LDAPS
Before configuring anything, it helps to understand the two protocols side by side:
- LDAP (port 389): Unencrypted by default. Can be upgraded to TLS with STARTTLS if the DC and client support it. Simple binds send credentials in plaintext without STARTTLS.
- LDAPS (port 636): Full TLS from the start of the connection. No STARTTLS negotiation — the session is encrypted before any LDAP messages are exchanged.
- Global Catalog LDAP (port 3268) and Global Catalog LDAPS (port 3269): Used for cross-domain GC queries; the same certificate enables LDAPS on 3269 automatically alongside 636.
LDAPS is enabled on a Windows DC automatically the moment a valid Server Authentication certificate appears in the computer’s Personal store — no service restart is required.
Step 2: Enroll a Certificate via AD CS Auto-Enrollment
If you have an enterprise CA (AD CS), domain controllers auto-enroll for the Domain Controller Authentication or Kerberos Authentication certificate template, which includes the Server Authentication EKU. Verify that this template is being issued:
# On the DC — check current certificates in the Local Computer Personal store
Get-ChildItem -Path Cert:LocalMachineMy | Where-Object {
$_.EnhancedKeyUsageList.FriendlyName -contains "Server Authentication"
} | Select-Object Subject, Issuer, NotAfter, Thumbprint
# Force certificate auto-enrollment if the certificate is missing
certutil -pulse
# Or trigger Group Policy refresh which also processes auto-enrollment
gpupdate /force
# Confirm the certificate appeared
Get-ChildItem Cert:LocalMachineMy | Where-Object {
$_.Subject -like "*$env:COMPUTERNAME*" -and
$_.EnhancedKeyUsageList.FriendlyName -contains "Server Authentication"
} | Select-Object Subject, NotAfter
Step 3: Manually Request or Import a Certificate
If auto-enrollment is not available, request a certificate manually or import one from a third-party CA:
# Create a certificate request INF file for a DC LDAPS certificate
$Inf = @"
[Version]
Signature="`$Windows NT`$"
[NewRequest]
Subject = "CN=$($env:COMPUTERNAME).$($env:USERDNSDOMAIN)"
KeySpec = 1
KeyLength = 2048
Exportable = FALSE
MachineKeySet = TRUE
SMIME = False
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
HashAlgorithm = SHA256
[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.1 ; Server Authentication
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=$($env:COMPUTERNAME).$($env:USERDNSDOMAIN)&"
_continue_ = "dns=$($env:COMPUTERNAME)&"
"@
$Inf | Out-File "C:Templdaps-dc.inf" -Encoding ascii
# Generate the certificate request
certreq -new "C:Templdaps-dc.inf" "C:Templdaps-dc.req"
# Submit to enterprise CA
certreq -submit -config "CA01.contoso.comContoso-Root-CA" `
"C:Templdaps-dc.req" "C:Templdaps-dc.cer"
# Accept and install the certificate
certreq -accept "C:Templdaps-dc.cer"
# Import a PFX from a third-party CA (if applicable)
Import-PfxCertificate -FilePath "C:Tempdc01-ldaps.pfx" `
-CertStoreLocation Cert:LocalMachineMy `
-Password (Read-Host -AsSecureString "PFX Password")
Step 4: Verify LDAPS Is Active
After the certificate is in the Personal store, LDAPS activates automatically within a few seconds (the LSASS process monitors the certificate store). Verify it is listening:
# Confirm port 636 is listening
netstat -ano | findstr ":636"
netstat -ano | findstr ":3269"
# Test LDAPS connection using ldp.exe:
# 1. Open ldp.exe
# 2. Connection -> Connect, enter DC FQDN, Port 636, check SSL checkbox
# 3. A successful connection shows "dn: (RootDSE)" in the output pane
# Test with PowerShell — check TLS handshake
$TCPClient = New-Object System.Net.Sockets.TcpClient("DC01.contoso.com", 636)
$SslStream = New-Object System.Net.Security.SslStream($TCPClient.GetStream(), $false, {
param($s,$c,$ch,$e) return $true
})
$SslStream.AuthenticateAsClient("DC01.contoso.com")
Write-Host "TLS Protocol: $($SslStream.SslProtocol)"
Write-Host "Cipher: $($SslStream.CipherAlgorithm)"
Write-Host "Certificate Subject: $($SslStream.RemoteCertificate.Subject)"
$SslStream.Close()
$TCPClient.Close()
Step 5: Troubleshoot LDAPS Issues
If LDAPS is not working after certificate installation, check the following:
# Check Event ID 1220 in the NTDS LDAP event log
# This event fires when the DC successfully binds a certificate to LDAPS
Get-WinEvent -LogName "Directory Service" -MaxEvents 50 |
Where-Object { $_.Id -eq 1220 } |
Select-Object TimeCreated, Message
# Event ID 1221 indicates the DC could NOT find a suitable certificate
Get-WinEvent -LogName "Directory Service" -MaxEvents 50 |
Where-Object { $_.Id -eq 1221 } |
Select-Object TimeCreated, Message
# Verify the certificate has the correct EKU
$cert = Get-ChildItem Cert:LocalMachineMy | Where-Object {
$_.Subject -like "*DC01*"
} | Select-Object -First 1
$cert.EnhancedKeyUsageList
# Confirm the private key is accessible to SYSTEM
certutil -verifystore My $cert.Thumbprint
# Check whether the LDAPS port is blocked by Windows Firewall
Get-NetFirewallRule -DisplayName "*LDAP*" | Select-Object DisplayName, Enabled, Direction, Action
New-NetFirewallRule -DisplayName "Allow LDAPS 636" -Direction Inbound `
-Protocol TCP -LocalPort 636 -Action Allow
Step 6: Configure LDAP Channel Binding and LDAP Signing
Windows Server 2025 and cumulative updates to earlier versions have strengthened LDAP security requirements. LDAP channel binding prevents man-in-the-middle attacks by binding the LDAP session to the TLS channel. LDAP signing prevents replay and tampering of unsigned LDAP messages. Both are controlled via Group Policy and registry settings:
# Configure LDAP signing policy via Group Policy (apply to Domain Controllers OU)
# Path: Computer Config > Windows Settings > Security Settings > Local Policies > Security Options
# Policy: "Domain controller: LDAP server signing requirements"
# Value: "Require signing"
# Set via registry directly on the DC (for testing — use GPO in production)
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesNTDSParameters" `
-Name "LDAPServerIntegrity" -Value 2 -Type DWord
# 0 = None, 1 = Negotiate signing (default before recent updates), 2 = Require signing
# Configure LDAP channel binding token requirements
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesNTDSParameters" `
-Name "LdapEnforceChannelBinding" -Value 2 -Type DWord
# 0 = Never, 1 = When supported, 2 = Always (strictest)
# Event ID 3039 is logged when a client fails channel binding requirements
Get-WinEvent -LogName "Directory Service" -MaxEvents 50 |
Where-Object { $_.Id -eq 3039 } |
Select-Object TimeCreated, Message
# Audit mode: log failures without rejecting connections (set value to 1)
Set-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetServicesNTDSParameters" `
-Name "LdapEnforceChannelBinding" -Value 1 -Type DWord
Step 7: Configure Applications to Use LDAPS
After enabling LDAPS on the DC, update application connection strings and client configurations to use port 636 with SSL. For Windows applications using .NET or ADSI:
# Test LDAPS connectivity with System.DirectoryServices in PowerShell
Add-Type -AssemblyName System.DirectoryServices.Protocols
$LdapIdentifier = New-Object System.DirectoryServices.Protocols.LdapDirectoryIdentifier(
"DC01.contoso.com", 636
)
$Credential = New-Object System.Net.NetworkCredential(
"[email protected]", "P@ssw0rd!"
)
$Connection = New-Object System.DirectoryServices.Protocols.LdapConnection(
$LdapIdentifier, $Credential,
[System.DirectoryServices.Protocols.AuthType]::Basic
)
$Connection.SessionOptions.SecureSocketLayer = $true
$Connection.SessionOptions.ProtocolVersion = 3
$Connection.Bind()
Write-Host "LDAPS connection successful"
$Connection.Dispose()
# Force clients to use LDAPS domain-wide via Group Policy
# Path: Computer Config > Admin Templates > System > LDAP Client
# "Minimum connection security for LDAP client" = Negotiate signing or Require SSL
Conclusion
Enabling LDAPS on Windows Server 2025 is one of the most impactful security improvements you can make to your Active Directory environment. The process is straightforward once a valid Server Authentication certificate is in place — the domain controller activates port 636 automatically. From there, enforcing LDAP signing and channel binding closes the remaining attack vectors against your LDAP infrastructure. The most common pitfall is failing to update legacy applications before enforcing these policies; use audit mode (channel binding value 1) to identify non-compliant clients before switching to enforcement. With LDAPS active and signing policies configured, your Active Directory LDAP interface will meet modern compliance requirements for secure directory services.