关于php:ldap_bind()失败,并显示“无法联系LDAP服务器”

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"

这将返回用户编码器上的预期数据。

转向PHP,我试图使用相同的凭据绑定到同一台服务器并通过(sapass)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    // 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,该脚本将起作用:

1
TLS_REQCERT never

一旦我注释掉,脚本将失败,并显示"无法联系LDAP服务器"。

如果将TLS_CACERTDIR /etc/openldap/certs添加到ldap.conf,则从命令行调用该脚本时效果很好。

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

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

我看过PHP / LDAP设置教程,了解如何使用EL6,并且我正在运行EL7。


解决了!

SELinux正在运行Enforced。 如果我暂时禁用SELinux,则ldap测试脚本在浏览器中可以正常工作。

这使我想到了这个有用的答案以及SELinux上的CentOS Wiki。 在这里我们学习:

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

啊。 事实证明,SELinux具有许多细粒度的开关,以允许来自不同进程的特定活动。 就我而言,SELinux已开箱即用地配置为不允许LDAP连接(即使在firewalld中启用了ldaps)。

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

1
getsebool -a | grep httpd

返回:

1
2
3
4
5
6
7
8
9
[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网络连接:

1
setsebool -P httpd_can_network_connect on

无需重启Apache。 从那时起,我的ldap脚本运行良好。

如上所述,请确保从/etc/openldap/ldap.conf中删除TLS_REQCERT never,并使用setenforce 1将SELinux设置回Enforcing

希望这对其他人有帮助。