我无法理解以下问题。使用 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 中存在错误的域配置,也可能证书链本身存在问题。我该如何检查最后一个问题(我在 Google 上搜索了很多,但大多数搜索结果都是关于openssl verify
不同-CAfile
的证书颁发者)?
我需要检查根证书包那么具体怎么做呢?
有没有类似-addtrust
旗帜为了certbot certonly?
答案1
尝试 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>
对于这些旧装置
交叉签名的 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 就是这种情况。因此,在 RHEL/CentOS 7 上运行的使用 OpenSSL 的程序很可能无法验证新的证书链或建立 TLS 连接。在这样的平台上升级到较新的 Openssl 版本并不简单。
有几个选项:在客户端更新信任库(删除 DST Root CA X3 根证书 - 一旦删除,影响应该是最小的)(或者)在服务器端更改证书链。
对于 Nginx
对于 Nginx,只有一个参数可以指定证书文件。您应该使用fullchain.pem
certbot 提供的参数才能使其正常工作。
给定虚拟主机的服务器块中的正确配置如下:
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;
}