如何在PHP中解决ldap_start_tls()“无法启动TLS:连接错误”?

时间:2010-04-22 09:33:11

标签: php certificate ssl

我得到了:

  

警告:ldap_start_tls()   [function.ldap-start-tls]:无法   启动TLS:连接错误   第Y行/var/www/X.php

/etc/ldap/ldap.conf:

TLS_CACERT     /etc/ssl/certs/ca.crt

ca.crt是签署LDAP服务器证书的CA. LDAP服务器上的证书已过期,我无法更改它。

7 个答案:

答案 0 :(得分:26)

您可以通过发出

来忽略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发生之前完成。

答案 1 :(得分:3)

问题中提出的特定情况-带有无法更改的过期证书-似乎需要在LDAP客户端上禁用证书验证。

但是,我怀疑像我一样,很多人都到达此页面,以找到接收不透明LDAP TLS错误的其他根本原因,在这些情况下,禁用TLS证书的验证是不合适的。

在我的情况下-在Ubuntu 18.04 LTS服务器上使用Mediawiki的LDAP身份验证扩展名,并在Windows Server 2012服务器上对Active Directory进行身份验证-身份验证在2020年1月/ 2月停止工作。服务器证书和CA证书仍然都是有效的,并且MediaWiki服务器上的openssl s_client -verify 2 -connect <AD server>:636通过得很好。

最终,我注意到AD / LDAP提供的SSL证书中的签名算法是SHA1,我记得最近遭受first known chosen-prefix collision exploit的困扰。这使我研究了系统上最近更新的软件包的变更日志,该日志在gnutls28 changelog circa January 8th, 2020中显示“将SHA1标记为证书签名不安全”。 (来自Ubuntu 18.04的php-ldap软件包的依赖链到php7.2-ldap-> libldap-2.4-2-> libgnutls30,其源软件包为gnutls28。)

我遵循了一些instructions to update the Windows CA to use SHA256,然后有选择地遵循了instructions to renew the AD/LDAP cert,在我的Mediawiki服务器上安装了新的CA证书,问题得以解决!简要地说,这些步骤包括:

  1. 在AD服务器上的Admin PowerShell中,运行certutil -setreg ca\csp\CNGHashAlgorithm SHA256
  2. 在证书颁发机构MMC中,右键单击CA->所有任务->续订CA证书
  3. 在空白的MMC中,添加证书的管理单元;选择本地计算机
  4. 在“个人”->“证书”下,找到LDAPS(Kerberos身份验证模板类型)使用的当前条目->“所有任务”->“高级选项”->“使用相同密钥续订此证书”
  5. 在同一窗口中,打开新的CA证书->详细信息->复制到文件->无私钥-> base64编码的X.509
  6. 将生成的文件复制到Mediawiki服务器上的/ usr / share / ca-certificates /中,然后运行sudo dpkg-reconfigure ca-certificates并选择要包含的新CA证书。



附言出于搜索引擎优化的目的,根据我使用的模式,错误消息包括:

    HTTP错误日志中的
  • ldap_start_tls(): Unable to start TLS: Connect error in /var/www/mediawiki/extensions/LdapAuthentication/LdapAuthenticationPlugin.php
  • ldap_start_tls(): Unable to start TLS: Can't contact LDAP server in [...]
  • {wiki调试日志中的Failed to start TLS.(使用wgLDAPEncryptionType = ssl时,即加密的LDAP端口636)
  • Medilib调试日志中的
  • Failed to bind as CN=foobar,CN=Users,DC=myOrgName,DC=local(使用wgLDAPEncryptionType = tls时,即未加密LDAP端口上的STARTTLS,389)

答案 2 :(得分:2)

我的解决方案/解决方法是使用

/etc/ldap/ldap.conf:
#TLS_CACERT /etc/ssl/certs/ca.crt
TLS_REQCERT never

如果您有任何更好的想法,请发布另一个答案。

答案 3 :(得分:1)

Windows中ldap.conf的路径已修复:

  

C:\ OpenLDAP的\的sysconf \的ldap.conf

可能需要重新启动Web服务器才能应用更改。

答案 4 :(得分:1)

  1. 在基于debian的系统中:

    安装软件包:ldap-utils并在文件中 /etc/ldap/ldap.conf,编辑一行:

    TLS_CACERT /etc/ldap/cacerts/cacert.asc
    

    创建目录/etc/ldap/cacerts并将cacert复制到 /etc/ldap/cacerts/cacert.asc

    重新启动apache

  2. 在基于redhat的系统中:

    安装软件包:openldap-clients并在文件中 /etc/openldap/ldap.conf编辑该行:

    TLS_CACERT /etc/openldap/cacerts/cacert.asc
    

    创建目录/etc/openldap/cacerts并将cacert复制到 /etc/openldap/cacerts/cacert.asc

    重新启动httpd

答案 5 :(得分:0)

其他人的一些额外帮助,这里的证书解决方案解决了我的ldapsearch命令行问题,但PHP仍抱怨**Can't contact LDAP server**

原来是RHEL7上的SELinux(CentOS7)默认使用LDAP端口389和636来阻止HTTPD,你可以解锁:

setsebool -P httpd_can_network_connect 1

检查SELinux审核日志文件中是否有被阻止的内容。

答案 6 :(得分:0)

我能够通过带有MacOS Server 5 LDAP的Amazon Linux(Elastic Beanstalk PHP 7.0)上的openldap正常工作,并将TLS设置为需求。

/etc/openldap/ldap.conf中的

TLS_REQCERT需求

TLS_CACERT /etc/openldap/certs/yourcacert.pem

(请注意,如果您不使用openldap,则路径为/etc/ldap/certs/yourcacert.pem)。在我将证书放在certs文件夹中之前,此设置无效;它没有任何其他途径。

要放在该路径中的证书不是服务器的TLS证书。它是颁发服务器/域特定TLS证书的颁发机构的CA(证书颁发机构)证书。只有放在该路径中的CA证书才允许TLS在php中尝试LDAP绑定之前工作。从您的服务器获取CA证书或从授权网站下载它们,它们是免费提供的。

要测试LDAP绑定是否在没有TLS的情况下工作,请暂时不要设置TLS_REQCERT(可能需要注释#out TLS_CACERT)。如果你得到&#34;无法连接到LDAP&#34;它不是TLS错误;它根本无法连接到服务器,您可能需要打开端口389(TLS不是636)。

每次更改配置文件或证书时,请记住重新启动Apache服务器。