无法在 Docker 中联系 LDAP 服务器(使用 ldaps)

无法在 Docker 中联系 LDAP 服务器(使用 ldaps)

我正在尝试做这样的 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

好吧,我在网上搜索了好久,终于让我的程序运行起来了。以下是我做的。

  1. 使用以下命令从 LDAP 服务器获取证书:
    openssl s_client -connect example.com:636
  2. 复制 -----BEGIN CERTIFICATE----- 和 -----END CERTIFICATE----- 之间的所有内容,包括
  3. 将其保存到文件中。例如 ca.pem
  4. 编辑 ldap.conf 文件(可能位于 /etc/ldap 或 /etc/openldap 目录中),并添加以下行。TLS_CACERT 行应指向您在上一步中保存文件的位置。

TLS_CACERT /etc/ssl/certs/ca.pem
TLS_REQCERT 从不

4a. 我出于内部原因添加了 TLS_REQCERT。请根据自己的需求/风险使用该设置。

  1. 运行 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

相关内容