簡體   English   中英

LDAP 和 PHP 連接失敗

[英]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) - 盡管我認為這不是您遇到問題的原因。

  • 您要連接到哪種 LDAP 服務器類型? OpenLDAP、Active Directory 或其他什么?
  • 運行您的 PHP 程序的計算機的操作系統是什么?
  • 您是否在 LDAP 服務器上使用自簽名 SSL 證書,並且運行 PHP 程序的機器是否信任給定證書的證書頒發機構?
  • LDAP 服務器運行在哪個端口上? 636 將是 LDAPS 的“官方”端口。 也許您可以將端口顯式添加到服務器地址: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM