16 September, 2022

Active Directory LDAPS certificate configuration

If you're trying to connect to an Active Directory domain with LDAPS, and you get errors like ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1) or ldap3.core.exceptions.LDAPSocketOpenError: socket ssl wrapping error: [Errno 104] Connection reset by peer, it might be because your domain controller doesn't have a certificate.

You can confirm this by looking in the System event log, and see if there are Schannel event 36886, "No suitable default server credential exists on this system. This will prevent server applications that expect to make use of the system default credentials from accepting SSL connections. An example of such an application is the directory server. Applications that manage their own credentials, such as the internet information server, are not affected by this."

You don't need to install Certificate Services (ADCS) to use LDAPS. For a simple test environment, create a self-signed certificate:

Instructions adapted from magnetikonline's GitHub Gist

$hostname = $([System.Net.Dns]::GetHostByName($env:computerName)).HostName
$domain = $(Get-ADDomain -Current LoggedOnUser).DNSRoot

# Create a new 10 year certificate
$now = Get-Date
$notafter = $now.AddYears(10)
$cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -notafter $notafter -dnsname $hostname, $domain 

# Export the cert (without private key)
Export-Certificate -Cert $cert -FilePath C:\temp\$hostname.cer

# Import the cert into trusted roots
Import-Certificate -FilePath "C:\temp\$hostname.cer" -CertStoreLocation Cert:\LocalMachine\Root

# Ask ADDS to reload the server cert

$renewservercert = @"
changetype: modify
add: renewServerCertificate
renewServerCertificate: 1
"@ -split '\n'

Set-Content "C:\temp\ldap-renewservercert.txt" $renewservercert

ldifde -i -f C:\temp\ldap-renewservercert.txt

You can test this worked by using:

LDAPTLS_REQCERT=allow ldapsearch -H ldaps://ad.invalid -x -W -D "[email protected]" -b "dc=ad,dc=invalid" "(sAMAccountName=user)"