PHP ldap_connect使用ldaps连接到Active Directory获取未知CA错误



我正试图在Windows 2012服务器上使用PHP 7连接到MS Active Directory(运行apache 2.4,但这与我遇到的问题无关)。

我还应该注意到,我可以通过命令行和apache服务器使用非安全LDAP从PHP连接到AD。

当我执行以下PHP测试文件时,源代码:http://muzso.hu/2012/04/02/php-ldap-ssl-ldaps-authentication-in-windows-running-apache,来自web服务器上的命令行:


$AD_search_bind_DN = 'CN=someuser,OU=Users,DC=example,DC=com';
$AD_search_bind_PW = 'secret123';
ini_set('display_errors', 1);
error_reporting(E_ALL);
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
$conn = ldap_connect('ldaps://SomeDC.example.com/') or die("Failed to connect to ldap server.");
ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind($conn, $AD_search_bind_DN, $AD_search_bind_PW) or die("Failed to bind to ldap server: " + ldap_error($conn));
echo "Successful LDAP bind.";

我得到以下输出(我突出显示了错误):


ldap_url_parse_ext(ldap://localhost/)
ldap_init:正在尝试%SYSCONFDIR%\ldap.conf
ldap_init:HOME env为NULL
ldap初始化:正在尝试ldaprc
IDAp_init:LDACONF env为空
ldap初始化:LDARC env为NULL
创建ldap_create
ldap_url_parse_ext(ldaps://SomeDC.example.com/)
ldap_sasl_bind_s
ldap_sasl-bind
ldap_send_initial_request
1 ldap_new_connection 1 1 0
ldap_int_open_connection
ldap connect_to_host:TCP SomeDC.example.com:636
2ldap_new_socket:244
lparepare_socket:244
ldap connect_to_host:正在尝试{已删除SomeDC的IP地址}:636
ldap_pvt_connect:fd:244 tm:-1 async:0<br]尝试连接:>
连接成功
TLStrace:SSL_connect:在/connect初始化之前
TLS跟踪:SSL_connect:SSLv2/v3写入客户端hello A
TLS跟踪:SSL/connect:SSLv3读取服务器hello A
TLS证书验证:深度:1,错误:20,主题:/DC=com/DC=example/C
N=Self_Named-SHA256-SubCA,颁发者:/CN=ITSS-Ent-SHA256-Root
TLS证书校验:错误,无法获取本地颁发者证书
TLS跟踪:SSL3警报写入:致命:未知CA
TLS跟踪:SSL_connect:错误中的错误
TLS追踪:SSL_connect:错误中的错误
TLS:无法连接:错误:14090086:SSL
例程:SSL3_get_server_certificate:证书验证失败(无法获取本地发布者证书)
ldap_err2string
PHP警告:ldap_bind():无法绑定到服务器:无法联系第10行上C:\test_bind.PHP中的ldap服务器


我在php.ini文件中对php_ldap和php_opensl扩展名都进行了UN注释。

我有DER和PEM格式的AD CA证书副本,但我不确定将这些文件放在我的web服务器上的哪里。有很多与linux操作系统相关的帖子只是简单地说,将"TLS_CACERT C:\openldap\sysconf\accert.pem"放在我的ldap.conf文件中。我没有运行openLDAP,也没有ldap.conf文件。

我安装了openSSL,但我不完全确定配置是否正确:

  • openssl.cfg文件保持不变:http://pastebin.com/KxnWThXh
  • 我添加了一个指向OpenSSL.cfg文件的环境变量"OpenSSL">
  • 当我从cmd行执行"openssl version-a"时,它显示:OPENSSLDIR:/usr/local/ssl这显然对windows没有意义。完整的输出可以在这里看到:http://pastebin.com/h3ei3Pwp

==第1版:====================================

加布里埃尔,谢谢你的建议/推荐信。

我现在也尝试过这些东西,但没有成功:

  • 创建了一个ldap.conf和一个openldap.onf文件(根据各种文章建议使用许多不同的格式,请参阅我在这里尝试的变体:http://pastebin.com/aP94Nh4Y)在C:\和C:\openldap\sysconf中
  • 这篇文章(https://www.reddit.com/r/PHPhelp/comments/3tykpc/php_7_and_ldap/)说要创建一个名为"LDACONF"的环境变量,该变量指向ldap.conf文件(C:\openldap\sysconf\ldap.conf)。我做到了。没有变化
  • 我在执行测试php脚本的输出中注意到了这一点(输出的第2行):ldap_init:trying%SYSCONFDIR%\ldap.conf。SYSCONFDIR环境变量还不存在,所以我添加了一个值为"C:\openldap\sysconf"的变量。——没有变化
  • 在我的ldap.conf/openldap.conf文件的所有位置引入了一个明显的语法错误,看看我是否可以更改测试脚本输出,以知道它至少在查看其中一个文件——什么都没有改变

==第2版:====================================

Gabriel,谢谢你的过程监控提示。我现在至少可以确认PHP 7正在使用"LDACONF"环境值路径来定位和读取这个ENV变量所指向的ldap.conf文件。

另外,PHP 7似乎没有正确处理"SYSCONFDIR"环境变量,因为它首先尝试打开以下文本路径中的文件:E:\httpd\www\%SYSCONFDIR%\ldap.conf

它仍然不起作用,但现在我可以集中精力调整我知道它正在读取的一个文件。

如果有人有任何其他的配置技巧,或者可以分享他们的ldap.conf文件,我将不胜感激。


我现在仍然被卡住,不知道还能做什么。请帮忙!

这里的答案应该会有所帮助:https://stackoverflow.com/a/6047293/1202807

在Windows上的XAMPP下,ldap.conf必须位于system(c:\ldap.conf,PHP 5.3.3,如果我没记错的话)或C: \openldap\sysconf\,具体取决于PHP版本。这条路不可配置,因为在Windows PHP DLL中进行了硬编码。请参阅上的评论http://se2.php.net/manual/en/ref.ldap.php

因此,如果ldap.conf文件还不存在,请在c:\或c:\openldap\sysconf\中创建它,并在其中放入TLS_CACERT行。

我也有类似的问题,我已经花了一些时间来解决它。这种行为是PHP中的OpenLDAP错误。我已经报告了它,它已经修复,很快就会发布。参见:PHP BUG#73243(https://bugs.php.net/bug.php?id=73243)

如果你需要立即修复,这有点黑客攻击,试试这个(风险自负):

  • 使用一些二进制编辑器(例如HexEdit)来编辑php_ldap.dll
  • 找到表达式"%SYSCONFDIR%\ldap.conf",然后
  • 将其替换为"c:\ldap_conf\ldap.conf",新常量的长度必须与替换的常量的长度相同
  • 将ldap配置复制到新位置

希望,它有帮助:-)

我知道我有点迟到了,但对我来说,以下代码行解决了颁发者证书的问题:

ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_ALLOW);

如果您使用ldaprecard包,则需要将LDAP_DEFAULT_OPT_X_TLS_REQUIRE_CERT=LDAP_OPT_X_TLS_ALLOW添加到.env文件.中

最新更新