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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2689629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 07:21:27  来源:igfitidea点击:

How do I solve ldap_start_tls() "Unable to start TLS: Connect error" in PHP?

phpcertificatessl

提问by user323094

I'm getting:

我越来越:

Warning: ldap_start_tls() [function.ldap-start-tls]: Unable to start TLS: Connect error in /var/www/X.php on line Y

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

/etc/ldap/ldap.conf:

/etc/ldap/ldap.conf:

TLS_CACERT     /etc/ssl/certs/ca.crt

ca.crtis the CA which signed the LDAP server certificate. The certificate on the LDAP server is expired and I can't change it.

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

回答by Jon Skarpeteig

You can ignore the validity in windows by issuing

您可以通过发出忽略 Windows 中的有效性

putenv('LDAPTLS_REQCERT=never');

in your php code. In *nix you need to edit your /etc/ldap.confto contain

在你的 php 代码中。在 *nix 你需要编辑你/etc/ldap.conf的包含

TLS_REQCERT never

Another thing to be aware of is that it requires version 3 (version 2 is php default):

要注意的另一件事是它需要版本 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);

To get a better idea of what's going on, you can enable debug logging by:

为了更好地了解发生了什么,您可以通过以下方式启用调试日志记录:

ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);

This can be done before the ldap_connecttakes place.

这可以在ldap_connect发生之前完成。

回答by user323094

My solution/workaround is to use

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

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

If you have any better idea, please post another answer.

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

回答by David R. Hedges

The specific scenario presented in the question--with an expired certificate that can't be changed--does appear to require disabling certificate validation on the LDAP client.

问题中提出的特定场景——证书过期且无法更改——似乎需要在 LDAP 客户端上禁用证书验证。

However, I suspect a lot of people, like me, reach this page for other root causes of receiving opaque LDAP TLS errors, where disabling validation of TLS certificates is not an appropriate answer.

但是,我怀疑很多人,像我一样,访问此页面以了解接收不透明 LDAP TLS 错误的其他根本原因,其中禁用 TLS 证书的验证不是一个合适的答案。

In my case--using the LDAP Authentication extension for Mediawiki on an Ubuntu 18.04 LTS server, and authenticating against Active Directory on a Windows Server 2012 server--authentication stopped working in January/February 2020. The server certificate and the CA certificate were still both valid, and openssl s_client -verify 2 -connect <AD server>:636from the Mediawiki server passed just fine.

就我而言——在 Ubuntu 18.04 LTS 服务器上使用 Mediawiki 的 LDAP 身份验证扩展,并在 Windows Server 2012 服务器上对 Active Directory 进行身份验证——身份验证在 2020 年 1 月/2 月停止工作。服务器证书和 CA 证书仍然存在两者都有效,并且openssl s_client -verify 2 -connect <AD server>:636从 Mediawiki 服务器通过就好了。

Eventually I noticed that the signature algorithm in the SSL certificate served by AD/LDAP was SHA1, which I remembered recently suffered from the first known chosen-prefix collision exploit. This led me to investigate the changelog for packages that had recently been updated on the system, which turned up "Mark SHA1 as insecure for certificate signing" in the gnutls28 changelog circa January 8th, 2020. (The chain of dependencies from the php-ldap package in Ubuntu 18.04 goes to php7.2-ldap -> libldap-2.4-2 -> libgnutls30, whose source package is gnutls28.)

最后我注意到 AD/LDAP 提供的 SSL 证书中的签名算法是 SHA1,我记得它最近遭受了第一个已知的选择前缀冲突漏洞攻击。这让我调查了系统上最近更新的软件包的变更日志,该日志在大约 2020 年 1 月 8 日gnutls28 变更日志中显示“将 SHA1 标记为证书签名不安全” 。(Ubuntu 18.04 中 php-ldap 包的依赖链为 php7.2-ldap -> libldap-2.4-2 -> libgnutls30,其源包为 gnutls28。)

I followed some instructions to update the Windows CA to use SHA256and then selectively followed instructions to renew the AD/LDAP cert, installed the new CA cert on my Mediawiki server, and the problem was solved! Briefly, these steps included:

我按照一些说明更新 Windows CA 以使用 SHA256,然后有选择地按照说明更新 AD/LDAP 证书,在我的 Mediawiki 服务器上安装新的 CA 证书,问题解决了!简而言之,这些步骤包括:

  1. In an Admin PowerShell on the AD server, run certutil -setreg ca\csp\CNGHashAlgorithm SHA256
  2. In the Certification Authority MMC, right click on the CA -> All Tasks -> Renew CA Certificate
  3. In a blank MMC, add snap-in for Certificates; select Local Computer
  4. Under Personal -> Certificates, find the current entry used by LDAPS (Kerberos Authentication template type) -> All Tasks -> Advanced Options -> Renew This Certificate with the Same Key
  5. In the same window, open the new CA certificate -> Details -> Copy to file -> no private key -> base64-encoded X.509
  6. Copy the resulting file to /usr/share/ca-certificates/ on the Mediawiki server, then run sudo dpkg-reconfigure ca-certificatesand select the new CA cert for inclusion.
  1. 在 AD 服务器上的 Admin PowerShell 中,运行 certutil -setreg ca\csp\CNGHashAlgorithm SHA256
  2. 在证书颁发机构 MMC 中,右键单击 CA -> 所有任务 -> 更新 CA 证书
  3. 在空白 MMC 中,为证书添加管理单元;选择本地计算机
  4. 在 Personal -> Certificates 下,找到 LDAPS(Kerberos 身份验证模板类型)使用的当前条目 -> 所有任务 -> 高级选项 -> 使用相同密钥更新此证书
  5. 在同一窗口中,打开新的 CA 证书 -> 详细信息 -> 复制到文件 -> 无私钥 -> base64 编码的 X.509
  6. 将生成的文件复制到 Mediawiki 服务器上的 /usr/share/ca-certificates/,然后运行sudo dpkg-reconfigure ca-certificates并选择要包含的新 CA 证书。



P.S. For SEO purposes, depending on the mode I was using, error messages included:



PS 出于 SEO 的目的,根据我使用的模式,错误消息包括:

  • ldap_start_tls(): Unable to start TLS: Connect error in /var/www/mediawiki/extensions/LdapAuthentication/LdapAuthenticationPlugin.phpin the HTTP error log
  • ldap_start_tls(): Unable to start TLS: Can't contact LDAP server in [...]
  • Failed to start TLS.in the Mediawiki debug log (when using wgLDAPEncryptionType= ssl, i.e. encrypted LDAP port, 636)
  • Failed to bind as CN=foobar,CN=Users,DC=myOrgName,DC=localin the Mediwiki debug log (when using wgLDAPEncryptionType= tls, i.e. STARTTLS on the unencrypted LDAP port, 389)
  • 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,即未加密的 LDAP 端口上的 STARTTLS,389)

回答by Encelado

The path for ldap.confin Windows is fixed:

ldap.confWindows 中的路径是固定的:

c:\openldap\sysconf\ldap.conf

c:\openldap\sysconf\ldap.conf

A restart of the web server may be required to apply changes.

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

回答by Nehal J Wani

  1. In debian based systems:

    Install the package: ldap-utilsand in the file /etc/ldap/ldap.conf, edit the line:

    TLS_CACERT /etc/ldap/cacerts/cacert.asc
    

    Create the directory /etc/ldap/cacertsand copy the cacert to /etc/ldap/cacerts/cacert.asc

    Restart apache.

  2. In redhat based systems:

    Install the package: openldap-clientsand in the file /etc/openldap/ldap.confedit the line:

    TLS_CACERT /etc/openldap/cacerts/cacert.asc
    

    Create the directory /etc/openldap/cacertsand copy the cacert to /etc/openldap/cacerts/cacert.asc

    Restart httpd

  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

回答by WhoIsRich

Some additional help for others, the certificate solution here solved my ldapsearchcommand line issue, but still PHP complained **Can't contact LDAP server**

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

Turned out to be SELinux on RHEL7 ( CentOS7 ) blocks HTTPD from using LDAP ports 389 and 636 by default, you can unblock with:

原来是 RHEL7 (CentOS7) 上的 SELinux 默认阻止 HTTPD 使用 LDAP 端口 389 和 636,您可以通过以下方式解除阻止:

setsebool -P httpd_can_network_connect 1

Check your SELinux audit log file for things being blocked.

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

回答by thundersnow

I was able to get this working properly with openldap on Amazon Linux (Elastic Beanstalk PHP 7.0) with MacOS Server 5 LDAP, with TLS set to demand.

我能够在 Amazon Linux (Elastic Beanstalk PHP 7.0) 和 MacOS Server 5 LDAP 上使用 openldap 正常工作,TLS 设置为按需。

in /etc/openldap/ldap.conf:

在 /etc/openldap/ldap.conf 中:

TLS_REQCERT demand

TLS_REQCERT 需求

TLS_CACERT /etc/openldap/certs/yourcacert.pem

TLS_CACERT /etc/openldap/certs/yourcacert.pem

(note that if you are not using openldap, the path will be /etc/ldap/certs/yourcacert.pem). This setup did not work until I placed the certificate inside the certs folder; it did not work from any other path.

(请注意,如果您不使用 openldap,路径将为 /etc/ldap/certs/yourcacert.pem)。直到我将证书放入 certs 文件夹后,此设置才起作用;它在任何其他路径上都不起作用。

The certificate to be placed in that path is NOT the TLS certificate of the server. It is the CA (Certificate Authority) certificate of the authority whom issued the server/domain specific TLS certificate. Only the CA certificate placed in that path will allow TLS to work before attempting an LDAP bind in php. Get the CA certificate from your server or download it from the authority's site, they are freely available.

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

To test if LDAP bind is even working without TLS, set TLS_REQCERT never temporarily (may need to comment # out TLS_CACERT). If you get "Can't connect to LDAP" it is not a TLS error; it simply cannot connect to the server and you likely need to open port 389 (not 636 for TLS).

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

Remember to restart your Apache server every time you make a change to the config file or certificate.

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