php - TLS 协商失败:ldap_connect 与默认端口以外的端口
问题描述
在客户端上运行 centos 6
在服务器上运行 centos 7
开放LDAP 2.4.44
php 5.3
证书是自签名的
php 程序在更改默认端口和设置 TLS 之前工作
php程序
$username = "uid=" . $userLogin . ",ou=Users,dc=XX,dc=XXX,dc=edu";
$ldap_host = "XXX.XX.XXX.edu";
$ldap_port = "1636";
$ldap_dn = "dc=XX,dc=XXX,dc=edu";
$filter = "(uid=".$userLogin.")";
// limit attributes we want to look for
$attr = array("uid","cn","givenName","sn","mail");
// turn on debugging before you open a connection
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
$ldap = @ldap_connect($ldap_host, $ldap_port) or die("Could not connect to $ldap_host");
ldap 服务器上的错误
slapd[11651]: conn=1001 fd=12 closed (TLS negotiation failure)
客户端上的 error_log
ldap_create
ldap_bind_s
ldap_simple_bind_s
ldap_sasl_bind_s
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP XX.XX.XXX.edu:1636
ldap_new_socket: 21
ldap_prepare_socket: 21
ldap_connect_to_host: Trying XXX.XXX.XX.XXX:1636
ldap_pvt_connect: fd: 21 tm: -1 async: 0
attempting to connect:
connect success
ldap_open_defconn: successful
ldap_send_server_request
ldap_result ld 0x7f1b0c78f6b0 msgid 1
wait4msg ld 0x7f1b0c78f6b0 msgid 1 (infinite timeout)
wait4msg continue ld 0x7f1b0c78f6b0 msgid 1 all 1
** ld 0x7f1b0c78f6b0 Connections:
* host: XXX.XX.XXX.edu port: 1636 (default)
refcnt: 2 status: Connected
last used: Wed Jul 11 11:46:03 2018
** ld 0x7f1b0c78f6b0 Outstanding Requests:
* msgid 1, origid 1, status InProgress
outstanding referrals 0, parent count 0
ld 0x7f1b0c78f6b0 request count 1 (abandoned 0)
** ld 0x7f1b0c78f6b0 Response Queue:
Empty
ld 0x7f1b0c78f6b0 response count 0
ldap_chkResponseList ld 0x7f1b0c78f6b0 msgid 1 all 1
ldap_chkResponseList returns ld 0x7f1b0c78f6b0 NULL
ldap_int_select
read1msg: ld 0x7f1b0c78f6b0 msgid 1 all 1
ldap_err2string
ldap_free_request (origid 1, msgid 1)
ldap_free_connection 1 1
ldap_free_connection: actually freed
消息登录客户端 httpd:登录失败:绑定错误#012请重试。
服务器上的 ldap.conf 文件
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#BASE dc=example,dc=com
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666
URI ldaps://XXX.XX.XX.edu:1636
BASE dc=XX,dc=XXX,dc=edu
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
# start TLS
SSL ON
TLS_CACERTDIR /etc/openldap/certs
TLSCertificateFile /etc/openldap/certs/paldapcert.pem
TLSCertificateKeyFile /etc/openldap/certs/paldapkey.pem
TLSVerifyClient allow
# Turning this off breaks GSSAPI used with krb5 when rdns = false
#SASL_NOCANON on
客户端上的 ldap.conf
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#BASE dc=example,dc=com
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
TLS_CACERTDIR /etc/openldap/certs
TLS_CERT /etc/openldap/certs/paldapcert.pem
TLS_KEY /etc/openldap/certs/paldapkey.pem
URI ldaps://XXX.XX.XXX.edu:1636
BASE dc=XX,dc=XXX,dc=edu
#start TLS
SSL ON
TLS_REQCERT allow
#TLS_CACERTDIR /etc/openldap/cacerts
密码
/etc/openldap/certs
在服务器上
-rw-r--r--. 1 ldap ldap 1472 Mar 16 10:36 paldapcert.pem
-rw-r--r--. 1 ldap ldap 1704 Mar 16 10:36 paldapkey.pem
在客户端
-rw-r--r--. 1 root root 65536 Aug 11 2014 cert8.db
-rw-r--r--. 1 root root 16384 Aug 11 2014 key3.db
-rw-r--r--. 1 root root 1472 Jul 6 11:05 paldapcert.pem
-rw-r--r--. 1 root root 1704 Jul 6 11:05 paldapkey.pem
-r--------. 1 root root 45 Aug 11 2014 password
-rw-r--r--. 1 root root 16384 Aug 11 2014 secmod.db
猫证书.ldif
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/paldapcert.pem
dn: cn=config
changetype: modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/paldapkey.pem
猫 /etc/sysconfig/slapd
# OpenLDAP server configuration
# see 'man slapd' for additional information
# Where the server will run (-h option)
# - ldapi:/// is required for on-the-fly configuration using client tools
# (use SASL with EXTERNAL mechanism for authentication)
# - default: ldapi:/// ldap:///
# - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:///
# - SLAPD_URLS="ldapi:/// ldap://127.0.0.1/
ldap://XXX.XXX.XXX.XXX:1389/ ldaps://XXX.XXX.XXX.XXX:1636/"
SLAPD_URLS="ldapi:/// ldap:/// ldaps://XXX.XXX.XXX.XXX:1636/"
# Any custom options
#SLAPD_OPTIONS=""
# Keytab location for GSSAPI Kerberos authentication
#KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab"
网络统计-antup | grep -i 1636 tcp 0 0 XXX.XXX.XX.XXX:1636 0.0.0.0:*
LISTEN 11651/slapd
在客户端:
/etc/nslcd.conf
tls_reqcert allow
uid nslcd
gid ldap
# This comment prevents repeated auto-migration of settings.
uri ldaps://XXX.XX.XX.XX:1636
base dc=XX,dc=XXX,dc=edu
ssl yes
tls_cacertdir /etc/openldap/certs
ldapsearch -p 1636 -D "cn=ldapadmin,dc=XX,dc=XXX,dc=edu" -W -h ldaps://XXX.XX.XXX.edu -b "dc=XX,dc=XX,dc =edu" -s sub "cn=砖块 *"
来自客户端的 ldapsearch 工作
还在客户端上运行 openssl 以测试连接
openssl s_client -connect xxx.xx.xxx.edu:1636 -servername xxx.xx.xxx.edu -showcerts |openssl x509 -text -noout
verify error:num=18:self signed certificate verify return:1 没有看到任何错误,除了这个关于自签名证书的注释
预先感谢您的任何帮助。
解决方案
现在不鼓励使用ldap_connect
with两个参数。它只能创建一个未加密的 LDAP 连接到给定的服务器$host
和在给定的端口上$port
。
现在,您应该使用包含方案(ldap
或ldaps
)、服务器和可选端口的 LDAP-URI(如果它不是方案的默认端口)。然后忽略第二个参数。
所以在我们的例子中,你应该使用这样的东西:
$ldap_uri = "ldap://XXX.XX.XXX.edu:1636";
$ldap = @ldap_connect($ldap_uri);
另请注意文档中有关返回值的信息:
当使用 OpenLDAP 2.xx 时,ldap_connect() 将始终返回一个资源,因为它实际上并不连接,而只是初始化连接参数。实际连接发生在下一次调用 ldap_* 函数时,通常使用 ldap_bind()
答案扩展了我有用的问题;-)
推荐阅读
- r - 如何使用两个规则有效地将数据框子集到列表列表中
- swift - 以模态方式呈现 VC 时,导航栏样式不会改变
- php - Laravel 没有使用正确的表
- android - 购买应用程序付费版本的简化方式
- sql - 使用单元格值范围内的条件运行 SQL 查询列表
- microsoft-teams - MS Teams 和 WebHook 连接器是否支持 AdaptiveCards?
- java - 如何使 GraphQL 在 Java 中进行异步/并行/并发查询?(里面的代码示例)
- javascript - React 警告:当我使用 Object.assign() 时,函数作为 React 子级无效
- plsql - 如何使用 zxjdbc 调用程序并取回 OUT 参数?
- php - PHP PDO 从内存中读取 SQLLite DB(变量)