Es ist wirklich viel darüber geschrieben worden, wie man auf Domain Controllern eines Active Directory-Forests LDAP über TLS-Verbindungen, also LDAPS, aktiviert. Einige, darunter auch namhafte, Autoren verwechseln dabei Signierung (die heutzutage wirklich jeder erzwungen haben sollte) mit Verschlüsselung, aber im Großen und Ganzen ist das Thema ausreichend beschrieben. Interessanter wird es, wenn Administratoren, nachdem sie nach Anleitung Zertifikate erstellt und auf ihre DCs ausgerollt haben, sich der nächsten Frage zuwenden:
Was ist damit eigentlich machbar?
meistens gefolgt von der Frage
Kann ich dann Port 389 (und 3268) inbound auf DCs endlich zumachen?
Und hier wird der eine dann enttäuscht und der andere verwirrt. Ersteren können wir nicht helfen, für die zweiteren ist dieser Post gedacht.
DC macht weiter munter LDAP ohne S
Wer erwartet hat, dass der LDAP-Listener des DC nach Einbindung eines Zertifikats automagisch von Port 389/3268 auf 636/3269 springt, wird enttäuscht: es passiert nichts dergleichen. Die LDAPS-Ports werden zwar aktiv, aber an der Funktion der LDAP-Ports ändert sich nichts. Jeder, der möchte, kann weiterhin LDAP-Anfragen auf Port 389 gegen den DC absetzen.
Das Auswahlverfahren bei mehreren möglichen Zertifikaten ist übrigens nichts für schwache Nerven – @awakecoding hat es mal aufgedröselt.
SRV Records für LDAPS sind wertlos
Nun sind einige so schlau, die SRV Records für LDAP (_ldap._tcp.domain.com und weitere für Sites und Global Catalog)
- entweder durch _ldaps._tcp.domain.com zu ergänzen,
- oder die Portnummer in dem Service von 389 auf 636 zu verbiegen,
- oder (das sind die ganz harten) die LDAP-Records durch LDAPS-Records zu ersetzen.
Fall 3 macht alles kaputt, denn niemand sucht nach LDAPS in DNS, es gibt dazu auch in den RFCs nichts. Es steht jeder Anwendung zwar frei, dies umzusetzen, aber niemand macht es und es gibt keinen Standard dafür.
Fall 1 ändert genau deshalb nichts am Verhalten – alle suchen nur den _ldap Record, finden ihn und verfahren entsprechend.
Interessant ist Fall 2: Domain Member funktionieren nach wie vor, andere Anwendungen sind teilweise gestört (das sind meistens die, welche beliebige LDAP-Verzeichnisse unterstützen und nicht ausschließlich Active Directory) und teilweise funktionieren sie weiter wie gehabt – nutzen dabei jedoch keineswegs TLS!
Diese Feststellung bringt uns zu der wichtigsten Aussage dieses Posts:
Port 389 auf der Firewall blockieren ist nicht zielführend!
In der typischen Consultant-Manier wollen wir diese Aussage auch gleich etwas relativieren: Wenn Multifunktionsdrucker oder andere Anwendungen LDAPS auf Port 636 unterstützen, kann man sie auf LDAPS umstellen und dann die Ports 389 und 3268 aus diesen Netzen zu den DCs sehr wohl zumachen. Das hehre Ziel, Port 389 auf der Windows-Firewall der DCs eingehend für alle zu blockieren, wird jedoch nie erreicht, denn
Windows nutzt im AD-Betrieb ausschließlich LDAP ohne S auf Port 389/3268!
Das ist hartkodiert in Windows selbst, daher macht das Verbiegen der Portnummer im DNS die AD-Kommunikation auch nicht kaputt. Und genau deshalb müssen Domain-Mitglieder ihre DCs weiterhin auf Port 389 erreichen können – auch wenn die DCs selbst längst LDAPS auf Port 636 sprechen. Das ist dann halt für Nicht-Mitglieder, die das können und wollen, denn wie bei jeder Client-/Server-Kommunikation entscheidet auch hier der Client, welches Protokoll gesprochen wird.
Übrigens: Neben dem bekannten LDAP auf Port 389/tcp nutzt Windows auch noch LDAP auf Port 389/UDP – dies jedoch nur für rootDSE-Abfragen zu Beginn der Kommunikation!
Warum ist LDAP zwischen AD-Mitgliedern und DCs nicht so schlimm?
Bevor wir jetzt aufgrund dieser Feststellung wieder anfangen, Windows und AD als „inhärent unsicher“ zu verteufeln, sollten wir uns fragen, warum wir denn unbedingt LDAPS machen wollen. Klar, die Anfragen, die an DCs gestellt werden, und deren Ergebnisse sind für einen Angreifer nicht ganz uninteressant (wir reden hier allerdings von einem Angreifer, der bereits so weit vorgedrungen ist, dass er die Netzwerk-Kommunikation im Transit abhören kann), aber primär geht es doch um den Schutz der Credentials. Im Simple Bind (Multifunktionsdrucker) sind die Anmeldedaten im Klartext enthalten, daher ist dort die Transportverschlüsselung auch sehr wichtig.
Der Bind eines AD-Mitglieds hingegen ist mit GSS-SPNEGO authentifiziert, somit sind im LDAP-Payload keine direkt als Name und Kennwort auswertbaren Anmeldeinformationen enthalten. Der Authentifizierungsteil könnte höchstens für Relay oder Replay verwendet werden (und wurde von Angreifern auch so verwendet!).
Dagegen schützen recht wirkungsvoll…
Signierung und Channel Binding
Das ist wiederum etwas, womit sich jeder AD-Admin zwingend, und lieber vorgestern statt gestern, beschäftigen sollte. Dem Evergreen-Monster-Post von Microsoft ist nichts hinzuzufügen. Wenn also das nächste Mal einer „Microsoft erzwingt demnächst LDAPS!“ schreit, einfach darauf verweisen. Was Microsoft allerdings zu verbieten sucht, ist Simple Bind mit Credentials im Klartext über unverschlüsselte LDAP-Verbindungen. Gewarnt im Event Log wird darüber bereits seit Jahren.
Zwischen „Member“ und „Nicht-Member“ unterscheiden
Theoretisch ist es möglich, mit IPSec und Windows Firewall Policies dafür zu sorgen, dass Domain-Mitgliedern (die diese IPSec-Verbindung aufbauen können) keine Port-Einschränkungen auferlegt werden und alle anderen ausschließlich auf die LDAPS-Ports zugreifen dürfen. Natürlich birgt dieser Ansatz die Gefahr, dass eine superwichtige Applikation, die 20 Jahre alt ist und nur LDAP kann, aber nicht auf Windows läuft, dann keine LDAP-Abfragen mehr durchführen kann. Aber dieser Grenzfall wird ohnehin irgendwann nicht mehr funktionieren, wenn ein Simple Bind eben nur über LDAPS zugelassen wird!
Ein Wort der Warnung: Validierung
LDAP-Clientanwendungen validieren das vom Server präsentierte Zertifikat in der Regel recht genau, daher haben diese Geräte oft das Häkchen „Server-Zertifikat bedingungslos vertrauen“ in ihrer LDAPS-Konfiguration. Allerdings ist die „recht genaue Prüfung“ auf die Merkmale begrenzt, die das Zertifikat auch bietet:
- Das Ablaufdatum wird immer geprüft. Allerdings prüft der DC dieses auch beim Binden, so dass es sehr unwahrscheinlich ist, dass ein LDAP-Client ein abgelaufenes Zertifikat von einem DC vorgelegt bekommt
- Der Name im Zertifikat muss dem Namen entsprechen, unter dem der DC angesprochen wird
- Hat das Zertifikat keine CDP-Erweiterung (bei selbstsignierten Zertifikaten immer, bei fremdsignierten manchmal der Fall), dann wird der Client das Zertifikat in der Regel auch ohne Revocation-Prüfung akzeptieren
- Ist eine CDP-Erweiterung vorhanden, dann wird CRL oder OCSP auch abgefragt
Auch hier gilt: Die Client-Anwendung allein bestimmt darüber, wie hart die Überprüfung am Ende sein wird, es gibt keinen feststehenden Standard dafür. Wer allerdings Zertifikate mit befüllter CDP-Erweiterung an LDAP bindet, sollte auch darauf achten, dass CDP/OCSP erreichbar ist: mindestens ein HTTP-basierter CDP und Port 80 zum CDP oder OCSP neben Port 636 zum LDAPS und 3269 für GC/SSL) auf der Firewall freigegeben. Auch DNS spielt hier eine Rolle – sowohl der DC als auch der CDP muss über den FQDN auflösbar sein, was insbesondere in DMZ-Szenarien nicht immer verfügbar ist.
Happy LDAPSing!