[英]LDAP and PHP connection failure
我正在尝试通过 PHP 连接到安全的 LDAP 服务器(使用 LDAP),但我遇到了问题。 我收到以下错误
警告:ldap_bind() [function.ldap-bind]:无法绑定到服务器:无法在第 16 行的 /var/www/test.php 中联系 LDAP 服务器
我尝试在没有 LDAP 的情况下进行连接时工作,但我必须使用 LDAP,因为我将处理敏感信息。
我正在使用以下代码
<?php
// basic sequence with LDAP is connect, bind, search, interpret search
// result, close connection
echo "<h3>LDAP query test</h3>";
echo "Connecting ...";
$ds=ldap_connect("ldaps://server"); // must be a valid LDAP server!
print $ds;
if ($ds) {
echo "<br><br>Binding ...";
$r=ldap_bind($ds); // this is an "anonymous" bind, typically
// read-only access
echo "Bind result is " . $r . "<br />";
echo "Searching for (sn=S*) ...";
// Search surname entry
$sr=ldap_search($ds, "ou=people,o=server.ca,o=server", "uid=username*");
echo "Search result is " . $sr . "<br />";
echo "Number of entires returned is " . ldap_count_entries($ds, $sr) . "<br />";
echo "Getting entries ...<p>";
$info = ldap_get_entries($ds, $sr);
echo "Data for " . $info["count"] . " items returned:<p>";
print_r($info);
// for ($i=0; $i<$info["count"]; $i++) {
// echo "dn is: " . $info[$i]["dn"] . "<br />";
// echo "first cn entry is: " . $info[$i]["cn"][0] . "<br />";
// echo "first email entry is: " . $info[$i]["mail"][0] . "<br /><hr />";
// }
echo "Closing connection";
ldap_close($ds);
} else {
echo "<h4>Unable to connect to LDAP server</h4>";
}
?>
该问题与实际绑定过程(无效凭据)无关,因为如果 LDAP 服务器无法验证您的凭据,警告将是不同的。 但是正如Paul Dixon指出的ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
应该需要使用ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
- 尽管我认为这不是您遇到问题的原因。
ldaps://<<server>>:636
。 ext/ldap
在 SSL/TLS 安全连接方面存在一些问题。 您可以尝试添加
TLS_REQCERT never
到ldap.conf
(基于 *nix 的系统上的/etc/ldap.conf
或/etc/ldap/ldap.conf
)或对于 Windows 机器,在C:\\OpenLDAP\\sysconf\\ldap.conf
创建具有上述内容的ldap.conf
C:\\OpenLDAP\\sysconf\\ldap.conf
(路径必须完全匹配,因为它被硬编码到扩展名中)。
虽然很老,但我遇到了同样的问题,并希望为未来的读者提供一些见解。
部分问题是过时的 OpenSSL 库,0.9.6 与 1.0.0(有效)。
在服务器上更新 OpenSSL 后,有人注意到 PHP 失去了对 OpenSSL 的支持。
您可以从命令行使用以下命令检查对模块的支持:
php -m
要么
echo phpinfo(INFO_MODULES);
从浏览器。
此外,根据我的专业经验,在使用 OCI8/Oracle LDAP 库时,LDAP 的 SSL 支持存在很多问题。 在 Debian 平台上,Libldap-2.4.2-dev 软件包效果最好。
此外,您应该查看 LDAP 服务器上的连接日志。 我几乎可以保证您会看到一个错误,指的是 SSLv3 并且缺少证书的 CA。
默认情况下,PHP 在 UNIX 系统中查找 CA 文件,确保它可以被 PHP 调用者(通过 cli 的用户、Apache 用户等)读取:
/etc/pki/CA
这不一定是 PHP 问题,而是安全 LDAP 的配置问题。 请参阅此PHP 错误报告和此OpenLDAP 线程。
上面的 OpenLDAP 线程有一个可用的 OpenLDAP 配置片段供参考。
其他一些需要检查的是 /etc/services 中的服务定义。 确保您具备以下条件:
ldaps 636/tcp # LDAP over SSL
ldaps 636/udp
在某些具有最新 PHP 版本的服务器上使用 SSL/TLS 似乎是一个问题。 不知道为什么。 您可以参考我的帖子: 使用 PHP 安全绑定到 Active Directory 的问题
更可能的原因之一是来自 Stefan 的原因。 要确保确实如此,您可以使用:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
在你的 ldap_connect 之前。 这将打印更合理的错误消息以记录(通常 ssl 证书无效,参考 Stefan Gehrig)
我认为您只需要将 ldap 协议版本设置为 3
echo "<h3>LDAP query test</h3>";
echo "Connecting ...";
$ldap_server = 'ldaps://server';
$ldap_port = '636';
$ds = ldap_connect($ldap_server, $ldap_port);
if ($ds)
{
//add this
if (!ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3))
{
fatal_error("Failed to set LDAP Protocol version to 3, TLS not supported.");
}
echo "<br><br>Binding ...";
$r=ldap_bind($ds); // this is an "anonymous" bind, typically
// read-only access
echo "Bind result is " . $r . "<br />";
echo "Searching for (sn=S*) ...";
// Search surname entry
$sr=ldap_search($ds, "ou=people,o=server.ca,o=server", "uid=username*");
echo "Search result is " . $sr . "<br />";
echo "Number of entires returned is " . ldap_count_entries($ds, $sr) . "<br />";
echo "Getting entries ...<p>";
$info = ldap_get_entries($ds, $sr);
echo "Data for " . $info["count"] . " items returned:<p>";
print_r($info);
// for ($i=0; $i<$info["count"]; $i++) {
// echo "dn is: " . $info[$i]["dn"] . "<br />";
// echo "first cn entry is: " . $info[$i]["cn"][0] . "<br />";
// echo "first email entry is: " . $info[$i]["mail"][0] . "<br /><hr />";
// }
echo "Closing connection";
ldap_close($ds);
}
else
{
echo "<h4>Unable to connect to LDAP server</h4>";
}
在 UNIX 上 "man ldap.conf" = ... 概要 /usr/local/etc/openldap/ldap.conf ...
在 /usr/local/etc/openldap/ldap.conf 中写入TLS_REQCERT never并设置 ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)
这在我的 Nginx+PHP-fpm 项目中工作:nginx/1.6.0 php55-5.5.15 php55-ldap-5.5.15 openldap-client-2.4.39_1
在阅读并尝试了来自整个网络和 SO 的解决方案后,拯救我的一天是使用一个没有指定端口的 ldaps uri 。
所以代替这个: ldaps://example.com:636
我不得不使用这个: ldaps://example.com
现在它就像一个魅力。
我在 Ubuntu 16.04 上设置了这个,PHP7.3 通过 Nginx 和 php-fpm 运行。
完整的代码示例:
try{
$ldapUri = "ldaps://example.com";
$ldapUsername = 'username';
$ldapPassword = 'password';
$ldapConn = ldap_connect($ldapUri);
if($ldapConn){
ldap_set_option($ldapConn,LDAP_OPT_NETWORK_TIMEOUT,10);
if(!ldap_set_option($ldapConn,LDAP_OPT_PROTOCOL_VERSION,3)){
print 'Failed to set ldap protocol to version 3<br>';
}
ldap_set_option($ldapConn, LDAP_OPT_REFERRALS,0);
$ldapBind = ldap_bind($ldapConn, $ldapUsername, $ldapPass);
if ($ldapBind) {
echo "LDAP bind successful...";
//DO LDAP search and stuff
ldap_unbind($ldapConn);
} else {
echo "LDAP bind failed...";
}
}
}catch(Exception $e){
print($e->getMessage();
}
尝试在您的 LDAP 服务器上启用“匿名绑定”或使用正确的绑定(用户名/密码)。
像cn=ldapauthuser,ou=accounts,dc=example,dc=com
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.