Signatur
Beschreibung
ldap_start_tls() initiiert das STARTTLS-Protokoll auf einer bestehenden, unverschlüsselten LDAP-Verbindung. Dabei wird innerhalb der bestehenden TCP-Verbindung auf Port 389 ein TLS-Handshake durchgeführt, ohne eine neue Verbindung aufzubauen. Dies unterscheidet STARTTLS vom klassischen LDAPS (Port 636), bei dem TLS von Anfang an besteht.
Die Funktion sollte unmittelbar nach ldap_connect() und vor ldap_bind() aufgerufen werden, damit Zugangsdaten und alle weiteren LDAP-Operationen verschlüsselt übertragen werden. Eine unverschlüsselte Übertragung von Bind-Credentials ist ein erhebliches Sicherheitsrisiko.
Damit die Funktion funktioniert, muss die OpenLDAP-Bibliothek korrekt konfiguriert sein (z. B. TLS_REQCERT in /etc/ldap/ldap.conf) und das Zertifikat des LDAP-Servers muss vertrauenswürdig sein. Mit ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER) kann die Zertifikatsprüfung deaktiviert werden, was jedoch nur in Testumgebungen akzeptabel ist.
Schlägt der TLS-Handshake fehl, gibt die Funktion false zurück und löst eine PHP-Warnung aus. Mit ldap_errno() und ldap_error() lassen sich detaillierte LDAP-Fehlercodes auslesen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $ldap Pflicht | LDAP\Connection | Eine gültige LDAP-Verbindungsressource, wie sie von ldap_connect() zurückgegeben wird. Ab PHP 8.1 ist dies ein LDAP\Connection-Objekt. |
Rückgabewert
true zurück, wenn der TLS-Handshake erfolgreich war. Bei einem Fehler (z. B. ungültiges Zertifikat, nicht unterstütztes Protokoll) wird false zurückgegeben und eine PHP-Warnung erzeugt.Beispiele
Sichere LDAP-Verbindung mit STARTTLS und anschließendem Bind
<?php
$host = 'ldap://ldap.example.com';
$dn = 'cn=admin,dc=example,dc=com';
$pass = 'geheimes_passwort';
$ldap = ldap_connect($host);
if (!$ldap) {
die('Verbindung fehlgeschlagen.');
}
// Optionen vor STARTTLS setzen
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
// TLS starten
if (!ldap_start_tls($ldap)) {
die('STARTTLS fehlgeschlagen: ' . ldap_error($ldap));
}
// Jetzt verschlüsselt binden
if (!ldap_bind($ldap, $dn, $pass)) {
die('Bind fehlgeschlagen: ' . ldap_error($ldap));
}
echo 'Erfolgreich verschlüsselt verbunden und authentifiziert.';
ldap_unbind($ldap);
STARTTLS mit deaktivierter Zertifikatsprüfung (nur für Tests)
<?php
// ACHTUNG: Nur in Entwicklungs-/Testumgebungen verwenden!
// Deaktiviert die Zertifikatsvalidierung global (vor ldap_connect)
ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
$ldap = ldap_connect('ldap://ldap-test.local');
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
if (ldap_start_tls($ldap)) {
echo 'TLS gestartet (ohne Zertifikatsprüfung).';
ldap_bind($ldap, 'cn=testuser,dc=local', 'test123');
// ... Operationen ...
ldap_unbind($ldap);
} else {
echo 'TLS-Start fehlgeschlagen.';
}
// Wichtig · Fallstricke
Sicherheitshinweis: Verwende ldap_start_tls() niemals ohne anschließende Validierung des Server-Zertifikats in Produktionsumgebungen. Das Deaktivieren der Zertifikatsprüfung (LDAP_OPT_X_TLS_NEVER) macht die Verbindung anfällig für Man-in-the-Middle-Angriffe.
Reihenfolge beachten: ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3) muss vor ldap_start_tls() gesetzt werden, da STARTTLS nur mit LDAP v3 funktioniert.
STARTTLS vs. LDAPS: STARTTLS (Port 389) und LDAPS (Port 636, via ldaps://-URI) sind zwei verschiedene Wege zur Verschlüsselung. Beide sind in modernen Umgebungen akzeptabel; LDAPS gilt bei manchen als etwas robuster, da TLS von Beginn an aktiv ist.
PHP 8.1: Ab PHP 8.1 wurde die Ressource durch das LDAP\Connection-Objekt ersetzt. Code, der noch eine alte Ressource erwartet, muss entsprechend angepasst werden.