Ssl-Certificate

如何使用letsencrypt / certbot修復證書鏈?

  • October 4, 2021

我無法解決以下問題。使用 openssl 驗證伺服器證書失敗,鏈不完整。

免責聲明:我不是管理員,也沒有過多地使用證書。

使用 OpenSSL 進行驗證

$ openssl verify -CAfile /etc/letsencrypt/live/co2-avatar.com/fullchain.pem  /etc/letsencrypt/live/co2-avatar.com/cert.pem

# /etc/letsencrypt/live/co2-avatar.com/cert.pem: C = US, O = Internet Security Research Group, CN = ISRG Root X1
# error 2 at 2 depth lookup:unable to get issuer certificate

檢查證書中的域之一

openssl s_client -connect co2avatar.org:443 -servername co2avatar.org
# CONNECTED(00000003)
# depth=0 CN = gitlab.sustainable-data-platform.org
# verify error:num=20:unable to get local issuer certificate
# verify return:1
# depth=0 CN = gitlab.sustainable-data-platform.org
# verify error:num=21:unable to verify the first certificate
# verify return:1
# ---
# Certificate chain
#  0 s:CN = gitlab.sustainable-data-platform.org
#    i:C = US, O = Let's Encrypt, CN = R3
# ---
# Server certificate
# -----BEGIN CERTIFICATE-----

或執行

curl -v https://co2avatar.org
# *   Trying 85.214.38.88:443...
# * TCP_NODELAY set
# * Connected to co2avatar.org (85.214.38.88) port 443 (#0)
# * ALPN, offering h2
# * ALPN, offering http/1.1
# * successfully set certificate verify locations:
# *   CAfile: /etc/ssl/certs/ca-certificates.crt
#   CApath: /etc/ssl/certs
# * TLSv1.3 (OUT), TLS handshake, Client hello (1):
# * TLSv1.3 (IN), TLS handshake, Server hello (2):
# * TLSv1.2 (IN), TLS handshake, Certificate (11):
# * TLSv1.2 (OUT), TLS alert, unknown CA (560):
# * SSL certificate problem: unable to get local issuer certificate
# * Closing connection 0
# curl: (60) SSL certificate problem: unable to get local issuer certificate

可能兩者都有,我的 Apache VHost 中的域配置錯誤以及證書鏈本身的問題。我如何檢查最後一個(我搜尋了很多,但大多數點擊是關於openssl verify-CAfile關於不同的證書頒發者)?

我是否需要檢查根證書包以及如何檢查?

有沒有類似certbot certonly-addtrust標誌

嘗試 openssl s_client 並讓您顯示證書。命令是:

$ openssl s_client -connect co2avatar.org:443 -servername co2avatar.org -showcerts

您會發現您的伺服器返回一個證書CN = gitlab.sustainable-data-platform.org和一個主題備用名稱,其中包括您的域DNS:co2-avatar.com。所以證書本身沒問題。

如果您想將所有內容組合到一個命令管道中以查看證書的內容:

echo | openssl s_client -connect co2avatar.org:443 -servername co2avatar.org -showcerts 2>/dev/null |sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | openssl x509 -noout -text

缺少的是中間證書。這也應該由伺服器發送,但第一個命令顯示它不存在 - 只有證書是由您的伺服器發送的。

所以失敗的 openssl 是正確的,因為確實缺少中間證書。

所以要解決它,你需要調整你的 apache 配置。這就是您的配置的樣子:

文件名應該類似於/etc/apache2/sites-enabled/co2-avatar.com-le-ssl.conf

<IfModule mod_ssl.c>
SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)
<VirtualHost *:443>
       ServerName co2-avatar.com
       ServerAlias www.co2-avatar.com
#... 
#... insert your other stuff here...
#...

SSLCertificateFile /etc/letsencrypt/live/co2-avatar.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/co2-avatar.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLUseStapling on
</VirtualHost>
</IfModule>

根據您的描述,我最好的猜測是您的配置中的以下行是錯誤的: SSLCertificateFile /etc/letsencrypt/live/co2-avatar.com/cert.pem. 它應該替換為SSLCertificateFile /etc/letsencrypt/live/co2-avatar.com/fullchain.pem, 以便也發送中間體。

解決方案更新(討論後)

在討論中發現,在這個 CentOS 伺服器上使用的 openssl 和 Apache 版本只是舊的,所以一些特性是不受支持的。(Apache 2.4.6,OpenSSL 1.0.2k,中間配置,無 HSTS,無 OCSP)

根據Mozilla SSL 配置生成器,在這種情況下可以使用以下通用配置:

<VirtualHost *:443>
   SSLEngine on
   SSLCertificateFile      /path/to/signed_certificate
   SSLCertificateChainFile /path/to/intermediate_certificate
   SSLCertificateKeyFile   /path/to/private_key
</VirtualHost>

轉換為這種特定情況,生成的工作配置如下:

<VirtualHost *:443>
   ServerName  sustainable-data-platform.org
   ServerAlias co2-avatar.com
   ServerAlias ... <include all other SAN names here>
   
   SSLEngine on
   SSLCertificateFile      /etc/letsencrypt/live/co2-avatar.com/cert.pem
   SSLCertificateChainFile /etc/letsencrypt/live/co2-avatar.com/fullchain.pem
   SSLCertificateKeyFile   /etc/letsencrypt/live/co2-avatar.com/privkey.pem

</VirtualHost>

作為此類舊裝置的說明

Cross-Signed Let’s Encrypt R3 和 DST Root CA X3,中間證書和根證書將分別於 2021 年 9 月 29 日和 2021 年 9 月 30 日到期。所以自 2021 年 5 月 4 日起,新頒發的證書使用更長的鏈,並帶有交叉簽名的 ISRG Root X1 作為中間證書。

不幸的是,由於證書路徑的建構和驗證方式,並非所有 TLS 實現都能成功驗證交叉簽名。OpenSSL 1.0.2 就是這種情況。因此,在使用 OpenSSL 的 RHEL/CentOS 7 上執行的程序可能無法驗證新證書鍊或建立 TLS 連接。在此類平台上升級到較新的 Openssl 版本並不簡單。

有幾個選項:在客戶端更新信任庫(刪除 DST Root CA X3 根證書 - 一旦刪除,影響應該是最小的)(或)更改伺服器端的證書鏈。

對於 Nginx

對於 Nginx,只有一個參數來指定證書文件。您應該使用fullchain.pemcertbot 提供的來使其正常工作。

給定虛擬主機的伺服器塊中的正確配置如下:

server {
 ...
 ssl_certificate /etc/letsencrypt/live/co2-avatar.com/fullchain.pem;  -> replaced cert.pem for fullchain.pem
 ssl_certificate_key /etc/letsencrypt/live/co2-avatar.com/privkey.pem;
}

參考

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