OpenLDAP 服务器:SSL 证书链接(让我们加密)无法按预期工作

OpenLDAP 服务器:SSL 证书链接(让我们加密)无法按预期工作

好吧,恐怕这会是一篇很长的文章。请忍耐一下。

环境

我有一台在 Alpine 3.12.1 上运行的 OpenLDAP 2.4.50 服务器。它仅使用 let's encrypt 暂存证书来提供 LDAPS(目前,但生产环境在证书方面不会有不同)。具体来说,它使用中cert.pem的引用。一切正常,我可以使用 ApacheDirectoryStudio 连接并使用它(承认我信任主机,尽管证书似乎有问题)。与任何 OpenLDAP 客户端(例如或)连接都需要中的 -entry,其中包含。这就是事情变得有趣的地方。olcTLSCertificateFilecn=configldapsearchldapmodifyTLS_CACERT/etc/openldap/ldap.confcat intermediate.pem root.pem > rootchain.pem

使用过 let's encrypt 的人都知道,let's encrypt(或者更确切地说是 certbot)通常会为我们提供以下内容:

  • privkey.pem- 私钥
  • cert.pem- 服务器的证书
  • chain.pem- 服务器证书和 CA 之间的中间证书
  • fullchain.pem- 从我们的服务器证书到无根的根证书的链条,又名。cat cert.pem chain.pem > fullchain.pem

不是root.pem,不是root-chain.pem,后者是cat chain.pem root.pem > rootchain.pem

网络上的人们声称,如果网络浏览器没有获得中间证书,但知道根证书并以某种方式检索中间证书,那么它们就会施展一些黑魔法,根据我自己的经验,我可能会倾向于相信这一点。这些人说:对于“普通”服务器,只需向 CA 提供证书链,而无需将实际的 CA 证书作为您向服务器软件提供的证书(例如确保证书链正确)在更彻底地了解了这一切之后,这完全是有道理的,因为rfc 4346,第 7.4.2 节状态

“certificate_list
这是 X.509v3 证书的序列(链)。发送者的证书必须位于列表的首位。每个后续证书都必须直接认证其前一个证书。”

据此我应该能够提供fullChain.pem(即cat cert.pem chain.pem > fullchain.pemolcTLSCertificateFilecn=config根证书客户端/etc/openldap/ldap.conf应该TLS_CACERT可以正常运行。简而言之,不,它们不能。

有趣的事实

openssl verify -CAfile root.pem somechain.pem仅成功,如果根据 rfc 应该是错误的......?somechain.pemcat chain.pem cert.pem > somechain.pem

结论

总结一下:

  • 提供形式的链式 PEMcat server.pem intermediate_lowest.pem intermediat_mid.pem intermediate-highest.pem作为服务器证书是否正确?
  • 如果是或者不是,我该如何使用 OpenLDAP 正确地执行此操作?

根据评论中的要求,以下是两者的输出openssl s_client -connect,仅使用根证书和使用中间证书链,后跟根证书。在请求时,slapd配置为使用fullchain.pemaka。cert.pem后跟chain.pem

  • 仅限根证书
    openssl s_client -showcerts -CAfile fakelerootx1.pem -connect directory.domain.tld:636 < /dev/null > with-rootcert.log 2>&1
depth=0 CN = *.domain.tld
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = *.domain.tld
verify error:num=21:unable to verify the first certificate
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:CN = *.domain.tld
   i:CN = Fake LE Intermediate X1
-----BEGIN CERTIFICATE-----
[ cert data removed, it is the single cert.pem from lets encrypt ]
-----END CERTIFICATE-----
---
Server certificate
subject=CN = *.domain.tld

issuer=CN = Fake LE Intermediate X1

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1899 bytes and written 401 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 21 (unable to verify the first certificate)
---
DONE
  • 由中间体和根组成的链
    openssl s_client -showcerts -CAfile fakerootchain.pem -connect directory.domain.tld:636 < /dev/null > with-root_and_intermediate_cert.log 2>&1
depth=2 CN = Fake LE Root X1
verify return:1
depth=1 CN = Fake LE Intermediate X1
verify return:1
depth=0 CN = *.domain.tld
verify return:1
CONNECTED(00000003)
---
Certificate chain
 0 s:CN = *.domain.tld
   i:CN = Fake LE Intermediate X1
-----BEGIN CERTIFICATE-----
[ cert data removed, it is the single cert.pem from lets encrypt, again ]
-----END CERTIFICATE-----
---
Server certificate
subject=CN = *.domain.tld

issuer=CN = Fake LE Intermediate X1

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1899 bytes and written 401 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
DONE

答案1

正如@Timor所说:

OpenLDAP 的 slapd 在 TLS 握手时根本不会将证书链发送给客户端,即使已经向它提供了一捆服务器证书、中间证书作为其证书。

olcSyncrepl当我使用复制 ldaps 服务器并且tls_reqcert=demandslapd 生成错误时,我遇到了这个问题ldap_sasl_bind_s failed (-1)

我发现一个简单的解决方法是将中间证书放入一个文件中(可能/etc/ssl/certs/ca-certificates.crt在 ubuntu 中)并tls_cacert=/etc/ssl/certs/ca-certificates.crt放入olcSyncrepl.

答案2

OpenLDAPslapd在 TLS 握手时不会将证书链发送给客户端,即使捆绑了服务器证书、中间证书已提供给它作为其证书。

不关闭客户端上的证书验证的唯一合适的解决方法如下。

  • 创建证书包中间证书、根证书
  • 让客户端使用此包作为受信任的 CA 证书,以便它可以分解完整链并进行验证;这至少适用于针对 OpenLDAP 库编译的软件
    • OpenLDAP 命令行客户端为ldapmodify, ldapsearch:
      添加TLS_CACERT imedrootbundle.pem~/.ldaprc或系统范围的/etc/openldap/ldap.conf
    • dovecot:
      添加tls_ca_cert_file = imedrootbundle.pem到您的/etc/dovecot/dovecot-ldap.conf.ext文件
    • postfix:
      添加tls_ca_cert_file = imedrootbundle.pem到所有cf文件,用作后缀字典来查询目录

但请记住,根证书不是由 let's encrypt 的 certbot 提供的,并且将来可能会发生变化,从而导致您的中间证书、根证书没用。我使用 certbot 设置了一个钩子脚本,它会检查中间证书的颁发者,并尝试根据我所知道的根证书选择正确的根证书。如果找不到,它会发出抱怨。这至少在流程早期以可控的方式破坏了一切。

答案3

我使用 Let's Encrypt 证书和 OpenLDAP 已经有一段时间了,但对我来说,创建包含链的文件并不是必要的。我只有来自 certbot renew-hook 脚本的内容:

cp /etc/letsencrypt/live/$domain/* /etc/ldap/ssl/
chown -R openldap:openldap /etc/ldap/ssl/
chmod 640 /etc/ldap/ssl/*
/etc/init.d/slapd force-reload >/dev/null

相关内容