我正在尝试做这样的 ldapsearch:
ldapsearch -x -D "uid=username,ou=people,dc=example" -w passw0rd -H ldaps://example.com "(objectClass=example)"
但它给了我这个错误:
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
经过调试,结果是:
ldap_url_parse_ext(ldaps://example.com)
ldap_create
ldap_url_parse_ext(ldaps://example.com:636/??base)
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP example.com:636
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying X.X.X.X:636
ldap_pvt_connect: fd: 3 tm: -1 async: 0
ldap_err2string
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
我以为是 SSL 连接的问题。但不是,因为这个命令成功了:
openssl s_client -connect example.com:636
所以我不知道问题出在哪里...
有关更多信息,我在一个带有 Ubuntu 映像的容器(Docker)中,我的 LDAP 配置是:
BASE dc=example
URI ldaps://example.com
TLS_REQCERT demand
TLS_CACERT /etc/ldap/certificates/CA-cert.pem
答案1
您可以在 /etc/ldap.conf 中设置
TLS_REQCERT 允许
正如您所猜测的,它不会在未知的证书颁发机构上失效。查看 man ldap.conf
TLS_REQCERT <level>
Specifies what checks to perform on server certificates in a TLS
session, if any. The <level> can be specified as one of the fol‐
lowing keywords:
never The client will not request or check any server certifi‐
cate.
allow The server certificate is requested. If no certificate is
provided, the session proceeds normally. If a bad cer‐
tificate is provided, it will be ignored and the session
proceeds normally.
try The server certificate is requested. If no certificate is
provided, the session proceeds normally. If a bad cer‐
tificate is provided, the session is immediately termi‐
nated.
demand | hard
These keywords are equivalent. The server certificate is
requested. If no certificate is provided, or a bad cer‐
tificate is provided, the session is immediately termi‐
nated. This is the default setting.
一旦您验证了 ldapsearch 正在运行,那么正确的做法就是获取 CA 根证书的副本并将其导入到您的 ubuntu 系统存储中。
显然这是像图中显示的那样完成的:这个超级用户问题
或者您可以忽略它并继续您正在做的事情而不验证证书,但是您应该尽可能尝试验证它。
答案2
好吧,我在网上搜索了好久,终于让我的程序运行起来了。以下是我做的。
- 使用以下命令从 LDAP 服务器获取证书:
openssl s_client -connect example.com:636 - 复制 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE----- 之间的所有内容,包括
- 将其保存到文件中。例如 ca.pem
- 编辑 ldap.conf 文件(可能位于 /etc/ldap 或 /etc/openldap 目录中),并添加以下行。TLS_CACERT 行应指向您在上一步中保存文件的位置。
TLS_CACERT /etc/ssl/certs/ca.pem
TLS_REQCERT 从不
4a. 我出于内部原因添加了 TLS_REQCERT。请根据自己的需求/风险使用该设置。
- 运行 ldapsearch 命令。我使用 ldapsearch -x -Z -d1 -H ldaps://example.com:636 -D " 你的绑定 dn" -w " 你的绑定密码" -b" 你的基准 dn" "(cn= 你的 cn )"
希望这可以帮助。
答案3
您会注意到,调试输出并未显示通信的 SSL/TLS 部分。如果我没记错的话,为了让 ldapsearch 输出此类信息,您需要使用选项-v2 -d
(可能具有更高的调试级别)。
请注意,openssl 可以工作,但这并不意味着 ldapsearch(openldap 库)会在同一位置查找证书信息。另请注意,openssl s_client 默认不验证证书。
您可以尝试将 TLS_REQCERT 设置为 never 作为调试辅助。
我还建议使用strace -e trace=file -f ldapsearch ...
作为辅助来发现哪些文件实际上正在寻找(以及是否有权限阻碍等)
Linux 系统往往有多个 ldap 配置文件(pam_ldap、nss_ldap、openldap 命令等)。您使用了哪个文件?
我通常会问那些在工作中向我询问类似问题的人一个问题,即客户端是用哪种语言堆栈编写的(或者更确切地说,使用的是哪种 LDAP 客户端 API -- 例如,带有 OpenSSL 的 OpenLDAP,或没有 High Security 附加组件的 Java 1.7,这样我就可以弄清楚哪些问题需要考虑得比其它问题要多)。因此,一旦您获得了有效的 调用,就不要指望 Java API 之类的东西能够正常工作ldapsearch
。
答案4
谢谢纳乔阿森霍对于上面的帖子。这正是我所需要的,但我想补充一点,至少对于我的系统(Ubuntu 22.04 LTS),ldap.conf 文件的位置应该是,/etc/ldap/ldap.conf
而不是/etc/ldap.conf
如上所述。
我在 Dockerfile 中使用以下代码来预填充文件,效果很好:
RUN mkdir /etc/ldap/ && \
echo 'TLS_REQCERT allow' >> /etc/ldap/ldap.conf