You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CentOS7下PHP7.0经SSL连接LDAP 636端口绑定失败问题咨询

环境基础

运行环境为CentOS 7 + PHP 7.0,已安装php-ldap扩展,安装与验证命令如下:

# yum install -y php php-ldap
...
# php -m
...
ldap
...

通过389端口非加密连接LDAP服务可正常运行,测试代码如下:

<?php
$ldapconn = ldap_connect("dc.example.com", 389) or die("Could not connect to LDAP server.");
    
if ($ldapconn) {
    $ldaprdn  = 'username';
    $ldappass = 'password';

    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
    
    if ($ldapbind) {
        echo "LDAP bind successful...";
    } else {
        echo "LDAP bind failed...";
    }
}

$Result = ldap_search($ldapconn, "DC=example,DC=com", "(sAMAccountName=johndoe)");
$data = ldap_get_entries($ldapconn, $Result);

print_r($data);
?>

上述代码可正常完成LDAP连接、绑定操作,能成功搜索到用户johndoe并返回其完整AD属性信息。

故障现象

切换为636端口SSL连接方式时,使用如下测试代码:

<?php
putenv('LDAPTLS_REQCERT=require');
putenv('LDAPTLS_CACERT=/var/www/html/servercert.der'); // 临时存放路径
$ldapconn = ldap_connect("dc.example.com", 636) or die("Could not connect to LDAP server.");

ldap_set_option($ldapconn, LDAP_OPT_DEBUG_LEVEL, 7);
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);

if ($ldapconn) {
    $ldaprdn  = 'username';
    $ldappass = 'password';

    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
    
    if ($ldapbind) {
        echo "LDAP bind successful...";
    } else {
        echo "LDAP bind failed...";
    }
}

$Result = ldap_search($ldapconn, "DC=example,DC=com", "(sAMAccountName=johndoe)");
$data = ldap_get_entries($ldapconn, $Result);

print_r($data);
?>

执行后返回如下错误:

Warning: ldap_bind(): Unable to bind to server: Can't contact LDAP server in /var/www/html/index.php on line 14
LDAP bind failed...
Warning: ldap_search(): Search: Can't contact LDAP server in......

已完成前置验证:

  • Windows AD服务器端已开放636端口,当前PHP Web服务器可正常连通该端口
  • 服务器证书本身为有效状态
遗漏配置与修复方法

共有4处关键配置不符合LDAPS连接要求,按优先级修复即可:

  1. 缺少LDAPS协议前缀
    PHP ldap扩展连接加密LDAP服务时,必须在地址前显式添加ldaps://前缀,仅指定域名+636端口不会触发SSL握手流程,客户端会直接向636端口发送明文LDAP请求,被服务端直接断开连接。
    修复方式:将连接行修改为
$ldapconn = ldap_connect("ldaps://dc.example.com", 636);
  1. 证书格式不兼容
    PHP ldap扩展底层依赖OpenLDAP库,该库默认仅识别PEM格式的证书,当前使用的DER格式证书无法被正常读取,会直接导致SSL证书校验失败。
    修复方式:执行以下命令将DER证书转为PEM格式:
openssl x509 -inform DER -in /var/www/html/servercert.der -out /var/www/html/servercert.pem

随后将代码中LDAPTLS_CACERT对应的路径修改为转换后的pem文件路径。

  1. 证书文件权限不足
    Web服务运行用户(通常为apache、nginx、www-data身份)需要对CA证书文件有读取权限,当前将证书放在Web根目录,如果默认权限配置过严,会导致OpenLDAP无法读取证书文件,握手失败。
    修复方式:执行命令给证书添加全局读权限,更稳妥的方式是将证书移动到OpenLDAP默认证书目录/etc/openldap/certs/下,不要存放在Web根目录:
chmod 644 /var/www/html/servercert.pem
  1. 可选调试配置
    如果完成上述修改后仍连接失败,可临时将LDAPTLS_REQCERT的值改为never关闭证书强校验,先确认SSL链路是否能正常连通,连通后再调回require排查证书域名匹配、证书链信任等问题。

修正后可正常运行的代码参考:

<?php
putenv('LDAPTLS_REQCERT=require');
putenv('LDAPTLS_CACERT=/etc/openldap/certs/servercert.pem');
// 注意添加ldaps://前缀
$ldapconn = ldap_connect("ldaps://dc.example.com", 636) or die("Could not connect to LDAP server.");

ldap_set_option($ldapconn, LDAP_OPT_DEBUG_LEVEL, 7);
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);

if ($ldapconn) {
    $ldaprdn  = 'username';
    $ldappass = 'password';

    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
    
    if ($ldapbind) {
        echo "LDAP bind successful...";
    } else {
        echo "LDAP bind failed...";
    }
}

$Result = ldap_search($ldapconn, "DC=example,DC=com", "(sAMAccountName=johndoe)");
$data = ldap_get_entries($ldapconn, $Result);

print_r($data);
?>

内容的提问来源于stack exchange,提问作者夏期劇場

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 04:42:27