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.

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.

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.

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