AD LDS Zertifikate für LDAPS
Diese Seite ist das Ergebnis einer Troubleshooting-Session eines Exchange Edge Server, wo der AD LDS aus unserer Sicht immer das falsche Zertifikat genutzt hat. Daher habe ich analysiert, wie AD LDS das Zertifikat bindet.
Achtung:
Sie können dem AD LDS kein Zertifikat statisch zuordnen. Er hat sein eigene Auswahl und wenn Sie neue Zertifikate
auf einem Server mit AD LDS installieren, kann sich die Bindung ändern.
Das kann insbesondere bei Exchange Edge Servern die Funktion
"EdgeSync" stören.
Testfeld vorbereiten
Ich habe dazu einen Windows 2019 (1809) als VM gestartet und AD LDS als Service addiert und eine einfache Konfiguration gestartet. Da es ein Member-Server war, hätte sich AD LDS auf Port 389/636 gebunden. Das habe ich auf folgende Ports umgestellt.
Mein Testserver war nicht Mitglied einer Domain und konnte daher auch nicht per AutoEnrollment ein Computerzertifikat bekommen. Er hatte erst einmal gar keine Zertifikate in seinem Speicher
Get-Childitem Cert:\LocalMachine\My\ | fl subject,NotAfter,NotBefore,HasPrivateKey,EnhancedKeyUsageList
Insofern war nach dem Start klar, dass ein Zugriff per LDP nur unverschlüsselt auf den Port 50389 möglich war. Passend dazu gab e auch ein Eventlog-Eintrag:
Log Name: ADAM (instance1) Source: ADAM [instance1] LDAP Event ID: 1220 Task Category: LDAP Interface Level: Warning Keywords: Classic User: N/A Computer: SV01.UCLABOR.DE Description: LDAP over Secure Sockets Layer (SSL) will be unavailable at this time because the server was unable to obtain a certificate. Additional Data Error value: 8009030e No credentials are available in the security package
Interessanterweise hat der Prozess DSAMAIN dennoch den Port schon belegt.
Eine TCP-Verbindung ist prinzipiell sogar möglich und mit einem Test-NetConnection können Sie die TCP-Erreichbarkeit prüfen.
Solange der ADLDS oder ADDS kein passendes Zertifikat hat, kann natürlich kein TLS-Handshake gestartet werden.
Wenn Sie nicht nur TCP sondern auch TLS testen wollen, dann können Sie die mit Get-TCPCert oder OpenSSL testen
Zertifikatsanforderungen
Aus verschiedenen Quellen und schon allein aus der Funktionsweise ergeben sich folgende Anforderungen:
- Subject:<Computer FQDN>
Der AD LDS-Server nutzt den FQDN des Servers, um damit nach möglichen Zertifikaten zu suchen - Enhanced Key Usage: Server Authentication (1.3.6.1.5.5.7.3.1)
Das Zertifikat muss die Nutzung als Serverzertifikat enthalten - Trusted Root
Das Zertifikat muss auf dem Computer vertrauenswürdig sein, d.h. entweder ist die RootCA im "Trusted Root Certification Authorities" des Computers oder bei der Nutzung von selbstsignierten Zertifikaten müssen Sie das Zertifikat in den Root-Store addieren
Eigentlich sind das nur grundlegende Anforderungen, die jedes Computer-Zertifikat erfüllen sollte. Wenn Sie natürlich den Server noch unter einem Alias, z.B. "ldap.<domain>" erreichen wollen, dann sollten Sie ein SAN-Zertifikat mit den zusätzlichen Namen generieren. Dennoch hatte ich bei einem Kunden auch die Herausforderung, dass auf einem Exchange Edge Server ein "öffentliche Zertifikat" für die SMTP-Kommunikation eingerichtet wurde und der ebenfalls vorhandene AD LDS-Server immer dieses "falsche" Zertifikat genutzt hat. Falsch daher, weil das genutzte Zertifikat auch in die Edge-Subscription einbezogen wird und ein Wechsel die Funktion stört.
Dieses Ticket war letztlich auch der Grund das Thema zu analysieren und die Ergebnisse als MSXFAQ-Artikel zu beschreiben.
SelfSignedZertifikat
Zuerst habe ich ein "SelfSigned"-Zertifikat angelegt. Das geht in einer administrativen PowerShell sehr einfach:
# Zertifikat anlegen $Certificate = New-SelfSignedCertificate ` -Subject sv01.uclabor.de ` -DNSName "sv01.uclabor.de","sv01" ` -CertStoreLocation Cert:\LocalMachine\My ` -KeyExportPolicy Exportable
Es landet auch direkt im Computerspeicher:
PS C:\> get-childitem Cert:\LocalMachine\My\ | fl subject,NotAfter,NotBefore,HasPrivateKey,EnhancedKeyUsageList Subject : CN=sv01.uclabor.de NotAfter : 12.01.2025 12:01:36 NotBefore : 12.01.2024 11:41:36 HasPrivateKey : True EnhancedKeyUsageList : {Client Authentication (1.3.6.1.5.5.7.3.2), Server Authentication (1.3.6.1.5.5.7.3.1)}
Trusted RootCA
Allerdings hat der AD LDS-Service auch nach einem Neustart das Zertifikate noch nicht genutzt. ein Doppelklick auf das Zertifikat im Computerspeicher hat aber angezeigt, dass es nicht von einer "Trusted Root" sei.
Ich habe es dann noch einmal in "Trusted Root Certification Authorities" des Computers kopiert aber auch hier hat AD LDS weder dynamisch noch nach einem Neustart eine TLS-Verbindung erlaubt oder den Port 50636 geöffnet. Interessanterweise ist aber auch die Eventlog-Meldung 1220 nicht mehr sichtbar, die auf ein fehlendes Zertifikat hinweist.
Wenn Sie ein Zertifikat einer öffentlichen
PKI nutzen, dann stellen Sie bitte sicher, dass das RootCA
und die IntermediateCAs ebenfalls im Computerstore korrekt
importiert wurden.
Wenn Sie eine EnterpriseCA ihrer Firma nutzen, dann sollten
auf DomainComputern dies die Gruppenrichtlinien und
AD-Defaults schon erledigt haben.
- SelfSSL
- New-SelfSignedCertificate
https://learn.microsoft.com/de-de/powershell/module/pki/new-selfsignedcertificate?view=windowsserver2019-ps - How to Create Self-signed Certificate using PowerShell
https://blog.admindroid.com/how-to-create-self-signed-certificate-using-powershell/
Service Zertifikatspeicher
In einigen Artikeln gibt es den Hinweis, dass das Zertifikat für den ADLDS-Server nicht im Zertifikatsspeicher von "LocalMachine" sondern des Service Accounts abgelegt werden muss. Das war auf meinem Windows 2019 Server nicht erforderlich.
An diesen Speicher kommen Sie, wenn Sie die MMC starten, das Snapin für Zertifikat addieren und dann "Service Account" auswählen:
Hier war natürlich erst einmal kein Zertifikat enthalten. Hier können Sie das vorher exportierte SelfSigned-Zertifikat aus dem Computerspeicher als PFX-Datei in den Speicher des Dienstkontos importieren.
Das Zertifikat muss hier aber nicht mehr in den "Trusted Root Certification Authorities"-Speicher. Es ist im Computerspeicher besser aufgehoben.
Private Key Rechte
Nun kommt das Problem mit den Berechtigungen auf den privaten Schlüssel. "AD LDS" läuft ja nicht mit einem Dienstkonto oder sogar als "LocalSystem", sondern mit minimalen Berechtigungen als "NETWORK SERVICE". Aus Sicherheitsgründen ist es immer eine gute Idee mit den minimalen Berechtigungen zu arbeiten.
- Security Identifiers: S-1-5-20
Netzwerkdienst
https://learn.microsoft.com/de-de/windows-server/identity/ad-ds/manage/understand-security-identifiers
Dummerweise kann AD LDS damit aber eventuell nicht an den privaten Schlüssel. In meiner Demo/Testumgebung liegt das Zertifikat im Computerstore mit der "klassischen Keyspeicherung". Dort kann ich die Rechte sehr einfach über die MMC prüfen:
Hier ist zu sehen, dass auch "NETWORK SERVICE" ausreichend Berechtigungen auf den privaten Schlüssel hat.
Kontrollieren Sie diesen Eintrag. Je nach Erstellung und Import ist "NETWORK SERVICE" nicht eingeschlossen
Ein guter Hinweis auf fehlende Berechtigungen ist der folgende Eventlogeintrag:
Log Name: ADAM (instance1) Source: ADAM [instance1] LDAP Date: 12.01.2024 17:58:54 Event ID: 1220 Task Category: LDAP Interface Level: Warning Keywords: Classic User: N/A Computer: SV01.UCLABOR.DE Description: LDAP over Secure Sockets Layer (SSL) will be unavailable at this time because the server was unable to obtain a certificate. Additional Data Error value: 8009030d The credentials supplied to the package were not recognized
Es kann aber auch sein, dass die Rechte auf den privaten Schlüssel hier nicht einsehbar sind.
Die Steuerung der Berechtigungen hängt davon ab, wo die privaten Schlüssel gespeichert sind und wird bei der Generierung des Zertifikats durch den CSP (Cryptographic Service Provider) vorgegeben. Das kann eine Datei, ein "protected Store", das TPM-Modul oder eine Smartcard sein.
Dann kann es sein, dass die privaten Schlüssel im Dateisystem des Servers abgelegt wurden.
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
Hier finden Sie für jedes Zertifikat eine ca. 3kB große Datei:
Dann müssen Sie hier die Berechtigungen prüfen. Dazu müssen wir natürlich wissen, welche Datei zu welchem Zertifikat gehört. Wenn Sie das neue Zertifikat gerade erst angelegt haben, dann können Sie einfach die Datei anhand des Modified-Datum als Kriterium erkennen. Folgendes Skript gibt den "UniqueKeyContainerName" zum passenden PrivateKey der Zertifikate aus, welcher mit dem Dateinamen übereinstimmt.
$CertStores = (Get-ChildItem Cert:\CurrentUser) + (Get-ChildItem Cert:\localmachine) Foreach ($Store in $CertStores) { $path = "Cert:\$($store.location)\$($store.Name)" Foreach ($cert in (Get-ChildItem $path)) { $UniqueKey = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName if (![string]::IsNullOrWhitespace($UniqueKey)){ [pscustomobject] @{ Thumbprint = $cert.thumbprint UniqueKey = $UniqueKey Subject = $cert.subject } } } }
Bitte löschen Sie keine Dateien, wenn Sie in der Liste nicht erscheinen. Das Skript liest nur LocalComputer und CurrentUser. Interessanterweise habe ich Zertifikate gefunden, die in der MMC mit privatem Schlüssel angezeigt werden aber dennoch keine Datei vorhanden war. Hier war aber auch der "UniqueKeyContainerName" leer. Wenn Sie ein Zertifikat löschen, wird der private Schlüssel nicht zwingend weggeräumt.
Konsistenzfehler in diesem Verzeichnis können Sie mit "CERTUTIL -Repairstore" ggfls. korrigieren. Ich musste das bislang noch nicht machen.
- about_Certificate_Provider
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/about/about_certificate_provider?view=powershell-7.4 - Grant NETWORK SERVICE access to the
certificate's private key
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-tutorial-dotnet-app-enable-https-endpoint#grant-network-service-access-to-the-certificates-private-key - SetCertificatePermissions.ps1
https://gist.github.com/pharring/991ad7ace955ff455796a6c1009cbca5 - Certutil
https://learn.microsoft.com/de-de/windows-server/administration/windows-commands/certutil - Zuweisen eines privaten Schlüssels zu
einem neuen Zertifikat nach dem Löschen des
ursprünglichen Zertifikats in IIS
https://learn.microsoft.com/de-de/troubleshoot/developer/webapps/iis/development/assign-certificate-private-key
LDAPS
In meinem Fall war es einfach, da nach der Ausstellung und Installation des Zertifikats in den Computerstore des Servers der "AD LDS"-Service nach einem Neustart direkt eine TLS-Verbindung erlaubt hat. Das konnte ich mit Get-TCPCert sehr einfach kontrollieren:
Im Eventlog war aber in der Standardeinstellung nichts zu sehen. Zum Test habe einmal mehrere Zertifikate installiert und dabei festgestellt:
- Zertifikate, deren Subject-Name bzw. DNS-Name nicht passt, werden ignoriert
- Zertifikate, zu denen es keine passende RootCA gibt, werden ignoriert
Das bedeutet aber auch, dass "SelfSigned"-Zertifikat zusätzlich in den Speicher für Trusted Roots addiert werden muss. - Abgelaufene Zertifikate werden ignoriert
Das ist anders als bei Exchange. Exchange nimmt notfalls auch abgelaufene oder sonst ungültige Zertifikate, wenn es um opportunistisches TLS bei SMTP geht. - Länger gültige Zertifikate werden kürzer gültigen Zertifikaten vorgezogen.
Es zählt hier das "NotAfter"-Datum und nicht das "NotBefore"-Datum - Kann zum ausgewählten Zertifikat kein Key gefunden werden, wird TLS nicht
angeboten!
Bei der Auswahl des Zertifikats wird also nicht vorab geprüft, ob ein Zugriff auf den Schlüssel möglich ist. - Wird nachträglich ein gültiges Zertifikat addiert, nutzt AD LDS es sofort
Es ist kein Neustart erforderlich. Ich habe testweise ein SelfSigned Zertifikat addiert und sobald ich es auch in den Root-Store addiert habe, wurde es genutzt - Ein Server mit einem zum FQDN des Servers passenden Subject wird einem
Wildcard vorgezogen
Ich habe dazu extra nach allen anderen Zertifikaten noch neuere und länger gültige Wildcards addiert, die aber nicht zum Zuge gekommen sind. - Eine explizite Konfiguration eines Zertifikats über einen Thumbprint o.ä.
ist nicht erforderlich
Das macht natürlich spätere Zertifikatswechsel einfach - Zertifikatsänderungen/Rollover
Eine Änderung der Zertifikate im Zertifikatsspeicher triggern anscheinend eine Neuauswahl.
Wenn ich zu einem bestehenden aktiven Zertifikat ein neues Zertifikat addiere, dann wird das bessere Zertifikat mit einem Dienstneustart sofort genutzt. Wenn ich den Dienst aber nicht neu starte und das alte Zertifikat ungültig wird, dann wechselt "AD LDS" alleine das Zertifikat - Keine Ablauf-Warnmeldung
Allerdings meldet AD LDS im Eventlog nicht wenn ein Zertifikat bald abläuft. Hier müssen Sie dann entweder auf der PKI oder dem Zertifikatsspeicher eine Überwachung einrichten.
Einen Test mit einer IntermediateCA
habe ich nicht gemacht
Aber ich gehe davon aus, dass ein Zertifikat nur gültig ist,
wenn auf dem Server neben der RootCA auch die
Intermediate-Zertifikate installiert sind.
Es muss also ein gültiges Zertifikat gefunden werden. Ansonsten bietet AD LDS keinen TLS-Zugang ein. Aufgrund der Nähe von Active Directory Domain Controller Diensten und AD LDS gehe ich davon aus, dass auch LDAPS auf einem Windows Domain Controller die gleichen Voraussetzungen erfüllen muss.
Damit die LDAPS-Funktion zuverlässig gegeben ist, sollten Sie eine "saubere" Zertifikatskonfiguration mit nur den benötigten und korrekt berechtigten Zertifikaten nutzen.
Erkenntnisse
Wenn man weiß, worauf man zu achten hat, dann ist die Einrichtung von LDAPS auf einem "AD LDS" Server und analog auf einem Domain Controller einfach und schnell erfolgt. Sobald Sie eine AD-integrierte PKI aufgesetzt haben, bekommen ihre Domain Controller ein passendes Zertifikat und mit wenige Aufwand können Sie jedem Domaincomputer per AutoEnrollment auch ein Computer-Zertifikat geben. "AD LDS" kümmert sich alleine darum, ein neues gültiges Zertifikat zu nutzen, wenn das bisher genutzte Zertifikat nicht mehr gültig ist. Sie können durch einen Neustart des Dienstes oder entfernen des bisherigen Zertifikats den Zertifikatswechsel auch beschleunigen.
Allerdings dürfen Sie nicht die Berechtigungen auf den privaten Schlüssel falsch setzen, da "AD LDS" diesen Fehler nicht erkennt und eventuell ein Zertifikat auswählt, welches er am Ende nicht nutzen kann. Dann ist LDAPS nicht verfügbar, bis Sie diesen Konfigurationsfehler korrigiert haben.
Wenn Sie kein Autoenrollment nutzen, dann sollten Sie daran denken, eine Überwachung oder Erinnerung zu aktivieren, damit Sie rechtzeitig vor dem Ablauf des Zertifikats dieses verlängern oder tauschen.
Weitere Link
- AD LDS-Server
- Exchange Edge Zertifikattausch
- SelfSSL
- Grundlagen Verschlüsselung
- LDAP Security
- Appendix A: Configuring LDAP over SSL
Requirements for AD LDS
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc725767(v=ws.10) - Aktivieren von LDAP über SSL mit einer
Fremdanbieter-Zertifizierungsstelle
https://docs.microsoft.com/de-de/troubleshoot/windows-server/identity/enable-ldap-over-ssl-3rd-certification-authority - How do I set up LDAP SSL and
Certificates in AD LDS (formerly ADAM)?
https://www.dirwiz.com/kb/345 - Troubleshoot LDAP over SSL connection
problems
https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/ldap-over-ssl-connection-issues - AD LDS WITH SSL AND SOME TROUBELSHOOTING
https://gsecse.wordpress.com/2014/08/23/ad-lds-with-ssl-and-some-troubelshooting/