好吧,我担心这会很长。请多多包涵。
环境
我有一个在 Alpine 3.12.1 上运行的 OpenLDAP 2.4.50 服务器。它仅使用 let's encrypt 暂存证书为 LDAPS 提供服务(目前,在证书方面,prod 环境将没有什么不同)。具体来说,它使用incert.pem
引用。一切正常,我可以使用 ApacheDirectoryStudio 连接和使用它(承认我信任主机,尽管证书看起来很臭)。与任何OpenLDAP客户端(例如或)连接需要一个由. 这就是事情变得有趣的地方。olcTLSCertificateFile
cn=config
ldapsearch
ldapmodify
TLS_CACERT
/etc/openldap/ldap.conf
cat 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
。
整个 webz 的人都认为,如果 Web 浏览器没有获得中间证书但知道根证书并以某种方式检索中间证书,那么他们会做一些黑魔法,我可能会根据自己的经验相信这一点。这些人说:对于“普通”服务器,只需向 CA 提供一个证书链,而不需要实际的 CA 证书作为您对服务器软件的证书(例如Get your certificate chain right)。在对这一切进行了更彻底的研究之后,这完全有道理,正如rfc 4346 第 7.4.2 节所述
“certificate_list
这是一个 X.509v3 证书的序列(链)。发送者的证书必须在列表中排在第一位。后面的每个证书必须直接证明它前面的证书。”
根据这一点,我应该能够向in和客户端提供fullChain.pem
(即cat cert.pem chain.pem > fullchain.pem
)根证书,并且每个客户端都应该正常运行。简单地说,不,他们没有。olcTLSCertificateFile
cn=config
/etc/openldap/ldap.conf
TLS_CACERT
有趣的事实
openssl verify -CAfile root.pem somechain.pem
只有成功,如果根据 rfc 应该是错误的...?somechain.pem
!cat chain.pem cert.pem > somechain.pem
结论
所以总结这一切:
- 提供形式
cat server.pem intermediate_lowest.pem intermediat_mid.pem intermediate-highest.pem
为服务器证书的链式 PEM 是否正确? - 如果是这样或不是,我如何使用 OpenLDAP 正确执行此操作?
根据评论中的要求,这里有openssl s_client -connect
两者的输出,仅带有根证书,并且带有中间证书链,后跟根证书。在请求时,slapd
配置为使用fullchain.pem
aka。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