简体   繁体   English

无法“openssl verify”letsencrypt证书

[英]Unable to `openssl verify' letsencrypt certificate

I gererate a certificate with Letsencrypt using the Certbot container: 我使用Certbot容器与Letsencrypt建立证书:

$ mkdir /home/$USER/letsencrypt
$ docker run -it --rm -p 80:80 -p 443:443 -v /home/$USER/letsencrypt:/etc/letsencrypt certbot/certbot certonly --standalone --email user@example.com --agree-tos -d example.com

I navigate to the generated certificate: 我导航到生成的证书:

$ cd /home/$USER/letsencrypt/live/example.com

I can verify chain.pem : 我可以验证chain.pem

$ openssl verify chain.pem 
chain.pem: OK

And I can see what's in chain.pem : 我可以看到chain.pem

$ openssl x509 -noout -in chain.pem -subject -issuer
subject=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
issuer=O = Digital Signature Trust Co., CN = DST Root CA X3

I can't verify cert.pem (presumably because it needs the chain): 我无法验证cert.pem (可能是因为它需要链):

$ openssl verify cert.pem
CN = example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error cert.pem: verification failed

But I also can't verify fullchain.pem either: 但我也无法验证fullchain.pem

$ openssl verify fullchain.pem
CN = example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error fullchain.pem: verification failed

The certificate seems to work in the browser, but is failing in curl (and an Android http client, which is the real issue): 证书似乎在浏览器中工作,但在curl失败(和Android http客户端,这是真正的问题):

$ curl https://example.com
curl: (60) SSL certificate problem: unable to get local issuer certificate

I've double-checked that fullchain.pem is a concatenation of cert.pem and chain.pem . 我已经仔细检查过fullchain.pemcert.pemchain.pem的串联。

So: I don't understand why fullchain.pem doesn't verify? 所以:我不明白为什么fullchain.pem不验证?

I figured this out from man verify , reading the description of untrusted . 我从man verify这一点,阅读了untrusted的描述。 Turns out untrusted is actually how you specify the certificate chain of trust (seems counterintuitive when you put it like that). 事实证明, untrusted实际上是指定信任证书链的方式(当你这样说时,似乎违反直觉)。

So, the command you need to verify a Letsencrypt cert is: 因此,验证Letsencrypt证书所需的命令是:

openssl verify -untrusted chain.pem cert.pem

Where cert.pem is your certificate and chain.pem is the LE intermediate cert. cert.pem是您的证书, chain.pem是LE中间证书。 There's no need to use fullchain.pem for this. 没有必要使用fullchain.pem

I was struggling with the same issue for 3 days. 我在同样的问题上奋斗了3天。 But the error was a result of a configuration error in the in my Apache configuration. 但该错误是我的Apache配置中的配置错误的结果。

I found out by Command openssl s_client -connect advertentiekracht.nl:443 returned: 我发现命令openssl s_client -connect advertentiekracht.nl:443返回:

Certificate chain
 0 s:/CN=advertentiekracht.nl
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3

inclusive the "Unable to get local issuer certificate" 包含“无法获得本地发行人证书”

Command : [root@srv ssl]# openssl x509 -noout -in /etc/letsencrypt/live/advertentiekracht.nl/chain.pem -subject -issuer showed the missing chain: 命令:[root @srv ssl] #openssl x509 -noout -in /etc/letsencrypt/live/advertentiekracht.nl/chain.pem -subject -issuer显示缺失的链:

subject= /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
issuer= /O=Digital Signature Trust Co./CN=DST Root CA X3

I am certainly not familiar with openssl and certificates. 我当然不熟悉openssl和证书。 There certainly can be a lot of reasons leading to "Unable to get local issuer certificate. But before you start digging like I did, check your http server configuration . For me that is Apache. I had typos in the where the SSL certificate hocus pocus is defined. The httpd toke the erroneous lines below 肯定会有很多原因导致“无法获得本地颁发者证书。 但在你开始像我一样挖掘之前,请检查你的http服务器配置 。对我来说就是Apache。我在SSL证书的重点是错误的已定义.httpd将下面的错误行改为

        SSLCertificateFile /etc/letsencrypt/live/advertentiekracht.nl/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/advertentiekracht.nl/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

Mind the first line SSLCertificateFile shoud be SSLCertificateChainFile, and I missed the references to the cert.pem and the chain.pem. 注意第一行SSLCertificateFile应该是SSLCertificateChainFile,我错过了对cert.pem和chain.pem的引用。 The lines below solved my problem: 以下几行解决了我的问题:

        SSLCertificateChainFile /etc/letsencrypt/live/advertentiekracht.nl/fullchain.pem
    SSLCertificateFile /etc/letsencrypt/live/advertentiekracht.nl/cert.pem
    SSLCertificateChainFile /etc/letsencrypt/live/advertentiekracht.nl/chain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/advertentiekracht.nl/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

Result, a complete chain: 结果,一个完整的链:

    Certificate chain
 0 s:/CN=advertentiekracht.nl
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3

Counterintuitively, I finally got openssl verify to work by adding the root certificate to the chain. 与直觉相反,我最终通过将根证书添加到链中来进行openssl verify It feels like the Letsencrypt CA should already be available, so I'm not convinced this is the right thing to do (and would welcome comments). 感觉Letsencrypt CA应该已经可用,所以我不相信这是正确的做法(并欢迎评论)。

The steps were: 步骤是:

  • Chrome developer tools > Security tab > View Certificate > Details tab > Select root certificate ("Builtin Object Token:DST Root CA X3") Chrome开发者工具>安全选项卡>查看证书>详细信息选项卡>选择根证书(“内置对象令牌:DST根CA X3”)
  • Click Export, export as Base64-Encoded ASCII, Single certificate (I named it ca.pem ) 单击导出,导出为Base64编码的ASCII,单个证书(我将其命名为ca.pem

Concatenate the root to the chain: 将根连接到链:

$ ca.pem fullchain.pem > cachain.pem

Then verify: 然后验证:

$ openssl verify cachain.pem
cachain.pem: OK

This feels "wrong" so I'd like to understand whether this is a false positive. 这感觉“错误”,所以我想了解这是否是误报。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM