【问题标题】:LDAP and PHP connection failureLDAP 和 PHP 连接失败
【发布时间】:2009-06-26 15:10:53
【问题描述】:

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

【问题讨论】:

  • 我不想问显而易见的问题,但是“ldaps://server”是一个有效的 LDAP 服务器吗?在我看来,这不是一个有效的 URI...
  • 它是一个有效的服务器。为了安全起见,我没有在那里写真实的服务器名
  • 抱歉,我从来没有真正解决过这个问题
  • 这个问题还没有解决吗?

标签: php ldap


【解决方案1】:

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

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

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

TLS_REQCERT never

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

【讨论】:

  • 此选项也可以通过 LDAP 初始化选项设置(无论如何,在 python 上,ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER))
  • IMO,这对于除了简单调试之外的任何事情都是非常糟糕的建议。将 TLS_REQCERT 设置为 never 将禁用所有 TLS 证书检查。这首先破坏了使用 TLS 的全部目的。设置此选项后,无法保证连接是安全的。
【解决方案2】:

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

更可能的原因之一是 Stefan 的原因。为确保确实如此,您可以使用:

ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);

在您的 ldap_connect 之前。这将打印一个更理智的错误消息来记录(通常是 ssl 证书无效,参考 Stefan Gehrig)

【讨论】:

    【解决方案3】:

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

    问题的一部分是过时的 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 bug report 和此OpenLDAP thread

    上面的 OpenLDAP 线程有一个工作 OpenLDAP 配置的 sn-p 供参考。

    需要检查的其他一些事情是 /etc/services 中的服务定义。确保您具备以下条件:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 对不起,这不起作用。它从来没有抛出你的错误信息,也没有很好地绑定
      【解决方案5】:

      在 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

      【讨论】:

        【解决方案6】:

        在阅读并尝试了整个网络和 SO 的解决方案后,节省了我一天的时间是使用没有指定端口的 ldaps uri

        所以我不得不使用这个:ldaps://example.com 而不是这个:ldaps://example.com:636,它现在就像一个魅力。

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

        【讨论】:

          【解决方案7】:

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

          点赞cn=ldapauthuser,ou=accounts,dc=example,dc=com

          【讨论】:

            猜你喜欢
            • 2016-08-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-01
            • 1970-01-01
            • 2016-03-19
            相关资源
            最近更新 更多