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 设置回 Enforcing
和 setenforce 1
。
希望这对其他人有帮助。
使用 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 设置回 Enforcing
和 setenforce 1
。
希望这对其他人有帮助。