Ssl-Certificate

OpenLDAP 伺服器:SSL 證書連結(讓我們加密)無法按預期工作

  • December 24, 2020

好吧,我擔心這會很長。請多多包涵。

環境

我有一個在 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 瀏覽器沒有獲得中間證書但知道根證書並隨後以某種方式檢索中間證書,那麼 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.pemcat 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.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

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文件中

    • 後綴:

    添加tls_ca_cert_file = imedrootbundle.pem到您的所有cf文件中,用作後綴字典來查詢您的目錄

但是請記住,根證書不是由 let’s encrypt 的 certbot 提供的,並且將來可能會更改,從而使您的中間證書、根證書無用。我用 certbot 設置了一個鉤子腳本,它檢查中間證書的頒發者,並嘗試根據我所知道的選擇正確的根證書。如果找不到,它會抱怨。這至少在流程的早期以受控方式破壞了一切。

正如@Timor 所說:

OpenLDAP 的 slapd 根本不會在 TLS 握手時將證書鏈發送給客戶端,即使已將一束伺服器證書、中間證書作為其證書提供給它。

當我使用olcSyncrepl複制 ldaps 伺服器時遇到了這個問題,tls_reqcert=demand並且 slapd 正在生成ldap_sasl_bind_s failed (-1)錯誤。

我發現一個簡單的解決方法是將中間證書放入文件(可能/etc/ssl/certs/ca-certificates.crt在 ubuntu 中)並tls_cacert=/etc/ssl/certs/ca-certificates.crt放入olcSyncrepl.

引用自:https://serverfault.com/questions/1042815