Как решить ldap_start_tls() "Невозможно запустить TLS: ошибка подключения" в PHP?
Я собираюсь:
Предупреждение: ldap_start_tls() [function.ldap-start-tls]: невозможно запустить TLS: ошибка подключения в /var/www/X.php в строке Y
/etc/ldap/ldap.conf:
TLS_CACERT /etc/ssl/certs/ca.crt
ca.crt
является центром сертификации, подписавшим сертификат сервера LDAP. Срок действия сертификата на сервере LDAP истек, и я не могу его изменить.
6 ответов
Вы можете игнорировать действительность в Windows, выполнив
putenv('LDAPTLS_REQCERT=never');
в вашем PHP-коде. В *nix вам нужно отредактировать ваш /etc/ldap.conf
содержать
TLS_REQCERT never
Еще одна вещь, о которой нужно знать, это то, что она требует версии 3 (версия 2 по умолчанию в php):
//$hostnameSSL example would be "ldaps://just.example.com:636" , just make sure it has ldaps://
$con = ldap_connect($hostnameSSL);
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
Чтобы лучше понять, что происходит, вы можете включить ведение журнала отладки:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
Это можно сделать до ldap_connect
происходит.
Конкретный сценарий, представленный в вопросе - с просроченным сертификатом, который нельзя изменить - похоже, требует отключения проверки сертификата на клиенте LDAP.
Однако я подозреваю, что многие люди, такие как я, обращаются к этой странице, чтобы узнать о других основных причинах получения непрозрачных ошибок TLS LDAP, когда отключение проверки сертификатов TLS не является подходящим ответом.
В моем случае - с использованием расширения LDAP Authentication для Mediawiki на сервере Ubuntu 18.04 LTS и аутентификации в Active Directory на сервере Windows Server 2012 - аутентификация перестала работать в январе / феврале 2020 года. Сертификат сервера и сертификат CA все еще оставались как действительные, так и openssl s_client -verify 2 -connect <AD server>:636
с сервера Mediawiki прошло нормально.
В конце концов я заметил, что алгоритм подписи в сертификате SSL, обслуживаемом AD/LDAP, был SHA1, который, как я вспомнил, недавно пострадал от первого известного эксплойта коллизии с выбранным префиксом. Это побудило меня исследовать журнал изменений для пакетов, которые недавно были обновлены в системе, где 8 января 2020 года в журнале изменений gnutls28 было указано "Пометить SHA1 как небезопасный для подписи сертификатов". (Цепочка зависимостей из пакета php-ldap в Ubuntu 18.04 переходит в php7.2-ldap -> libldap-2.4-2 -> libgnutls30, исходный пакет которого - gnutls28.)
Я выполнил некоторые инструкции по обновлению центра сертификации Windows для использования SHA256, а затем выборочно выполнил инструкции по обновлению сертификата AD/LDAP, установил новый сертификат CA на моем сервере Mediawiki, и проблема была решена! Вкратце, эти шаги включали:
- В административной оболочке PowerShell на сервере AD запустите
certutil -setreg ca\csp\CNGHashAlgorithm SHA256
- В центре сертификации MMC щелкните правой кнопкой мыши CA -> Все задачи -> Обновить сертификат CA
- В пустой MMC добавьте оснастку для сертификатов; выберите Локальный компьютер
- В разделе "Личные" -> "Сертификаты" найдите текущую запись, используемую LDAPS (тип шаблона проверки подлинности Kerberos) -> "Все задачи" -> "Дополнительные параметры" -> "Продлить этот сертификат с тем же ключом".
- В том же окне откройте новый сертификат CA -> Подробности -> Копировать в файл -> нет закрытого ключа -> X.509 в кодировке base64
- Скопируйте полученный файл в /usr/share/ca-Certificates / на сервере Mediawiki, затем запустите
sudo dpkg-reconfigure ca-certificates
и выберите новый сертификат CA для включения.
PS В целях SEO, в зависимости от того, какой режим я использовал, сообщения об ошибках включали:
ldap_start_tls(): Unable to start TLS: Connect error in /var/www/mediawiki/extensions/LdapAuthentication/LdapAuthenticationPlugin.php
в журнале ошибок HTTPldap_start_tls(): Unable to start TLS: Can't contact LDAP server in [...]
Failed to start TLS.
в журнале отладки Mediawiki (при использованииwgLDAPEncryptionType
знак равноssl
, т.е. зашифрованный порт LDAP, 636)Failed to bind as CN=foobar,CN=Users,DC=myOrgName,DC=local
в журнале отладки Mediwiki (при использованииwgLDAPEncryptionType
знак равноtls
, т.е. STARTTLS на незашифрованном порту LDAP, 389)
Мое решение / обходной путь заключается в использовании
/etc/ldap/ldap.conf:
#TLS_CACERT /etc/ssl/certs/ca.crt
TLS_REQCERT never
Если у вас есть идея получше, пожалуйста, оставьте другой ответ.
Путь для ldap.conf
в винде исправлено:
C:\ OpenLDAP \sysconf\ldap.conf
Для применения изменений может потребоваться перезагрузка веб-сервера.
В системах на основе Debian:
Установите пакет:
ldap-utils
и в файле/etc/ldap/ldap.conf
отредактируйте строку:TLS_CACERT /etc/ldap/cacerts/cacert.asc
Создать каталог
/etc/ldap/cacerts
и скопировать каскад в/etc/ldap/cacerts/cacert.asc
Запустить снова
apache
,В системах на основе Redhat:
Установите пакет:
openldap-clients
и в файле/etc/openldap/ldap.conf
отредактируйте строку:TLS_CACERT /etc/openldap/cacerts/cacert.asc
Создать каталог
/etc/openldap/cacerts
и скопировать каскад в/etc/openldap/cacerts/cacert.asc
Запустить снова
httpd
Я смог заставить это работать должным образом с openldap на Amazon Linux (Elastic Beanstalk PHP 7.0) с MacOS Server 5 LDAP, с TLS, установленным по требованию.
в /etc/openldap/ldap.conf:
TLS_REQCERT спрос
TLS_CACERT /etc/openldap/certs/yourcacert.pem
(обратите внимание, что если вы не используете openldap, путь будет /etc/ldap/certs/yourcacert.pem). Эта настройка не работала, пока я не поместил сертификат в папку certs; это не сработало ни с какого другого пути.
Сертификат для размещения в этом пути НЕ является сертификатом TLS сервера. Это сертификат CA (центра сертификации) того органа, который выпустил сертификат TLS для конкретного сервера / домена. Только сертификат CA, помещенный в этот путь, позволит TLS работать до попытки привязки LDAP в php. Получите сертификат CA со своего сервера или загрузите его с сайта органа, они находятся в свободном доступе.
Чтобы проверить, работает ли связывание LDAP даже без TLS, никогда не устанавливайте TLS_REQCERT временно (может потребоваться закомментировать # TLS_CACERT). Если вы получаете "Не удается подключиться к LDAP", это не ошибка TLS; он просто не может подключиться к серверу, и вам, вероятно, нужно открыть порт 389 (не 636 для TLS).
Не забывайте перезапускать сервер Apache каждый раз, когда вы вносите изменения в файл конфигурации или сертификат.
Некоторая дополнительная помощь для других, решение для сертификата здесь решило мое ldapsearch
проблема с командной строкой, но PHP все еще жаловался **Can't contact LDAP server**
Оказалось, что SELinux на RHEL7 ( CentOS7) блокирует HTTPD от использования портов LDAP 389 и 636 по умолчанию, вы можете разблокировать с помощью:
setsebool -P httpd_can_network_connect 1
Проверьте файл журнала аудита SELinux на предмет блокировки.