Skip to content

Instantly share code, notes, and snippets.

@alexmags
Created March 23, 2024 11:15
Show Gist options
  • Select an option

  • Save alexmags/565c129f40b98f69c78814852ca8230e to your computer and use it in GitHub Desktop.

Select an option

Save alexmags/565c129f40b98f69c78814852ca8230e to your computer and use it in GitHub Desktop.
PowerShell self-signed cert for LDAPs
# In a lab, or a AD domain with non-routable top level domain (.corp, .local etc...)
# Creating one self-signed cert usable across multiple domain controllers for encrypted LDAP
Import-Module ActiveDirectory
$addomain=get-addomain
$expirydate = (Get-Date).AddYears(1)
# Get all (currently existing) domain controllers to be subject alternative names (avoid cloud kerberos trust object)
$ArraySubjectAlternativeNames=(Get-ADComputer -SearchBase $addomain.DomainControllersContainer -filter * | where {$_.name -ne 'AzureADKerberos'}).dnshostname
$ArraySubjectAlternativeNames+="ldap.$($addomain.DNSRoot)" # useful as movable DNS alias or for network load balancer
# Create cert with domain name as subject and DCs and ldap.fqdn as subject alternative names.
# https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate
$mycert=New-SelfSignedCertificate -Subject $addomain.DNSRoot -DnsName $ArraySubjectAlternativeNames -CertStoreLocation cert:/LocalMachine/My -NotAfter $expirydate
$mycert | Format-list
# Export cert WITHOUT private key for import into LDAP clients
Export-Certificate -Cert $mycert -FilePath "$env:temp\$($addomain.DNSRoot)-PUBLIC.cer" # this is a text file
# Export cert WITH private key for import into other domain controllers. Protect with shared password or lock to specific IDs
# https://learn.microsoft.com/en-us/powershell/module/pki/export-pfxcertificate
Export-PfxCertificate -cert $mycert -filepath "$env:temp\$($addomain.DNSRoot)-PRIVATE.pfx" -ProtectTo $env:username
# To import certs on other domain controllers, double click to import.
# NOTE: LDAP will use cert in personal store with longest expiry. Server restart to take effect.
# Test with ldp.exe, connect with fully qualified domain name (not short NetBIOS name, not IP address) on port 636 and SSL
# Or programatically Import private key to other DCs
# import-Certificate -CertStoreLocation Cert:\LocalMachine\my -FilePath fqdn-PRIVATE.pfx
# Import public key into Trusted CAs store to any server/client that needs to validate the cert as trusted
# import-Certificate -CertStoreLocation Cert:\LocalMachine\Root -FilePath fqdn-PUBLIC.cer
@bryanmulvey
Copy link

This was incredibly useful for me. I'm very glad to have stumbled across it. I made a few tweaks for my use case:

# Creating a self-signed certificate usable across multiple domain controllers for encrypted LDAP

Import-Module ActiveDirectory
$addomain = Get-ADDomain
$expirydate = (Get-Date).AddYears(10) # Set validity period to 10 years
$desktopPath = [Environment]::GetFolderPath("Desktop") # Path to current user's Desktop

# Get all (currently existing) domain controllers to be subject alternative names (avoid cloud Kerberos trust object)
$DCs = Get-ADComputer -SearchBase $addomain.DomainControllersContainer -Filter * | Where-Object { $_.Name -ne 'AzureADKerberos' }
$ArraySubjectAlternativeNames = $DCs.DNSHostName

# Add 'ldap.fqdn' as a SAN
$ArraySubjectAlternativeNames += "ldap.$($addomain.DNSRoot)" # Useful as movable DNS alias or for network load balancer

# Add the IP addresses of the domain controllers to the SANs
foreach ($DC in $DCs) {
    $IPAddresses = (Resolve-DNSName $DC.Name).IP4Address
    $ArraySubjectAlternativeNames += $IPAddresses
}

# Create cert with domain name as subject and DCs, 'ldap.fqdn', and IP addresses as subject alternative names.
# https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate
$mycert = New-SelfSignedCertificate -Subject $addomain.DNSRoot -DnsName $ArraySubjectAlternativeNames -CertStoreLocation cert:\LocalMachine\My -NotAfter $expirydate
$mycert | Format-List


$publicKeyCertPath = "$desktopPath\$($addomain.DNSRoot)-PUBLIC.cer"
$privateKeyCertPath = "$desktopPath\$($addomain.DNSRoot)-PRIVATE.pfx"

# Export cert WITHOUT private key for import into LDAP clients
Export-Certificate -Cert $mycert -FilePath $publicKeyCertPath  # This is a text file

# Export cert WITH private key for import into other domain controllers. Protect with shared password or lock to specific IDs
# https://learn.microsoft.com/en-us/powershell/module/pki/export-pfxcertificate
# Export-PfxCertificate -Cert $mycert -FilePath $privateKeyCertPath -ProtectTo $env:USERNAME


# Import public key into Trusted CAs.
Import-Certificate -CertStoreLocation Cert:\LocalMachine\Root -FilePath $publicKeyCertPath

# NOTE: LDAP will use cert in personal store with longest expiry. Server restart may be required to take effect.
# Test with ldp.exe, connect with fully qualified domain name or IP address on port 636 and SSL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment