LDAP和PHP连接失败

时间:2009-06-26 15:10:54

标签: php ldap

我正在尝试通过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>";
}
?>

7 个答案:

答案 0 :(得分:8)

问题与实际绑定过程(无效凭据)无关,因为如果LDAP服务器无法验证您的凭据,则警告将是不同的。但正如Paul Dixon所指出的,应该要求使用ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3) - 即使我认为这不是导致问题的原因。

  • 您要连接哪种LDAP服务器类型? OpenLDAP,Active Directory还是别的什么?
  • 运行PHP程序的计算机的操作系统是什么?
  • 您是否在LDAP服务器上使用自签名SSL证书,并且是运行PHP程序的计算机信任的给定证书的证书颁发机构?
  • LDAP服务器在哪个端口上运行? 636将成为LDAPS的“官方”端口。也许您可以将端口显式添加到服务器地址:ldaps://<<server>>:636

ext/ldap在SSL / TLS安全连接方面存在一些问题。您可以尝试添加

TLS_REQCERT never

到基于* nix的系统上的ldap.conf/etc/ldap.conf/etc/ldap/ldap.conf)或Windows机器在ldap.conf中创建一个C:\OpenLDAP\sysconf\ldap.conf以上内容(路径必须完全匹配,因为它已硬编码到扩展名中)。

答案 1 :(得分:2)

在使用最新PHP版本的某些服务器上使用SSL / TLS似乎存在问题。不知道为什么。您可以参考我的帖子:Problems with secure bind to Active Directory using PHP

其中一个更可能的原因是斯特凡的原因。为确保确实如此,您可以使用:

ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
在你的ldap_connect之前

。这将打印更合理的错误消息到日志(通常ssl证书无效,参考Stefan Gehrig)

答案 2 :(得分:2)

虽然陈旧,但我遇到了同样的问题,并想为未来的读者提供一些见解。

部分问题是过时的OpenSSL库,0.9.6 vs 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 bug report和此OpenLDAP thread

上面的OpenLDAP线程有一个工作OpenLDAP配置的片段供参考。

要检查的其他一些事项是/ etc / services中的服务定义。确保您拥有以下内容:

ldaps           636/tcp                         # LDAP over SSL
ldaps           636/udp

答案 3 :(得分:0)

我认为你只需要将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>";
}

答案 4 :(得分:0)

在UNIX上“man ldap.conf”= ... SYNOPSIS /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的客户端 - 2.4.39_1

答案 5 :(得分:0)

从网络和SO上阅读并试用解决方案后,省下了我的一天,是使用没有指定端口的ldaps uri

因此,我不得不使用以下命令:ldaps://example.com:636,而不是这样:ldaps://example.com,它现在就像一种魅力。

我在Ubuntu 16.04上通过Nginx和php-fpm运行PHP7.3进行了设置。

完整的代码示例:

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();
}

答案 6 :(得分:-1)

尝试在LDAP服务器上启用“匿名绑定”或使用正确的绑定(用户名/密码)。

喜欢cn=ldapauthuser,ou=accounts,dc=example,dc=com