Как решить 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, и проблема была решена! Вкратце, эти шаги включали:

  1. В административной оболочке PowerShell на сервере AD запустите certutil -setreg ca\csp\CNGHashAlgorithm SHA256
  2. В центре сертификации MMC щелкните правой кнопкой мыши CA -> Все задачи -> Обновить сертификат CA
  3. В пустой MMC добавьте оснастку для сертификатов; выберите Локальный компьютер
  4. В разделе "Личные" -> "Сертификаты" найдите текущую запись, используемую LDAPS (тип шаблона проверки подлинности Kerberos) -> "Все задачи" -> "Дополнительные параметры" -> "Продлить этот сертификат с тем же ключом".
  5. В том же окне откройте новый сертификат CA -> Подробности -> Копировать в файл -> нет закрытого ключа -> X.509 в кодировке base64
  6. Скопируйте полученный файл в /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 в журнале ошибок HTTP
  • ldap_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

Для применения изменений может потребоваться перезагрузка веб-сервера.

  1. В системах на основе Debian:

    Установите пакет: ldap-utils и в файле/etc/ldap/ldap.confотредактируйте строку:

    TLS_CACERT /etc/ldap/cacerts/cacert.asc
    

    Создать каталог /etc/ldap/cacerts и скопировать каскад в/etc/ldap/cacerts/cacert.asc

    Запустить снова apache,

  2. В системах на основе 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 на предмет блокировки.

Другие вопросы по тегам