ldap_bind() 失败 "Can't contact LDAP server"

ldap_bind() fails with "Can't contact LDAP server"

使用 PHP 5.6 和 openldap 2.4.40 在 EL7 系统上工作。

我可以使用 ldapsearch 查询远程 ldaps 服务器:

ldapsearch -H ldaps://ldap.example.com -D "CN=serviceaccount,OU=Services,DC=example,DC=com" -x -w "sapass" -LLL -b "DC=example,DC=com" cn="acoder"

这 returns 预期用户编码器上的数据。

转到 PHP,我正在尝试使用上面的相同凭据和传递 (sapass) 绑定到同一服务器。

    // server settings
    $srvc_id        = 'serviceaccount';
    $srvc_pass      = "somepass";
    $ldap_host          = "ldaps://ldap.example.com";
    $srvc_dn            = "CN=$srvc_id,OU=Services,DC=example,DC=com";
    $user_filter        = "(uid=$form_user)";

    $ldap_conn = ldap_connect($ldap_host);
    if ($ldap_conn)
    {
        echo "<p>Connected to $ldap_host $ldap_host at line ";

        $r = ldap_bind($ldap_conn, $srvc_dn, $srvc_pass);
        if (!$r)
        {
            echo "<p>failed to bind with service account credentials.";

        } else {
            echo "<p>binded OK.";
        }
    }

如果我暂时将其添加到 /etc/openldap/ldap.conf,脚本会起作用:

TLS_REQCERT never

一旦我将其注释掉,脚本就会失败并显示 "Can't contact LDAP server"。

如果我将 TLS_CACERTDIR /etc/openldap/certs 添加到 ldap.conf,脚本在从命令行调用时工作正常。

TLS_CACERTDIR   /etc/openldap/certs
# TLS_REQCERT never  ### only use for testing ###

httpd 似乎没有读取必要的证书,因此无法与远程 LDAP 服务器通信。

我看过的 PHP/LDAP 设置教程适用于 EL6,我是 运行 EL7。

已解决!

SELinux 运行 强制执行。如果我暂时禁用 SELinux,ldap 测试脚本在浏览器中运行良好。

这让我想到了 helpful answer and this CentOS Wiki on SELinux。我们在这里学习:

SELinux doesn't allow your httpd daemon to talk to the LDAP server on the same machine.

啊。事实证明,SELinux 有大量细粒度的开关来允许来自不同进程的特定 activity。在我的例子中,SELinux 被配置为禁止 LDAP 连接(即使在 firewalld 中启用了 ldaps)。

您可以使用以下命令检查 httpd 的 SELinux 配置:

getsebool -a | grep httpd

哪个returns:

[acoder@myboxen]# getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off

通过 httpd 启用 SELinux 网络连接:

setsebool -P httpd_can_network_connect on

无需重新启动 Apache。从那一刻起,我的 ldap 脚本运行良好。

如上所述,请务必从 /etc/openldap/ldap.conf 中删除 TLS_REQCERT never,当然还要将 SELinux 设置回 Enforcingsetenforce 1

希望这对其他人有帮助。