证书续订后,Ruby Net :: HTTP响应OpenSSL :: SSL :: SSLError“证书validation失败”

我们最近更新了我们网站的SSL证书,以下内容发生在Mac OS El Capitan 10.11.3上:

require 'net/http' Net::HTTP.get URI('https://www.google.com') # => "..." # The site whose certificate got renewed Net::HTTP.get URI('https://www.example.com') # => OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed 

我在Google和StackOverflow上的所有搜索都提出了表明Ruby安装存在问题的答案,但它们似乎与较旧的Ruby版本有关,我认为这不是这种情况。 这是我尝试过的:

  • brew update
  • brew upgrade openssl
  • rvm osx-ssl-certs update all
  • rvm install ruby-2.3.1 --disable-binary --with-openssl-dir="$(brew --prefix openssl)" (之前我没有这个版本)
  • rvm requirements
  • 根据Uzbekjon的建议, crlrefresh rpv清除OSX系统范围的CRL缓存。

我该如何解决这个问题?

笔记:

  • 新安装的Linux Docker容器上没有Ruby 2.2.3就不会出现这个问题。 所以也许这与Mac OS或SSL本地缓存有关。
  • 在证书续订之前可能存在此问题。 我无法确定。 但是,正如我在这个问题中讨论的那样,更新确实会导致我们正在使用的第三方出现类似的问题。
  • Namecheapvalidation证书安装是否正确,在线检查器显示一切正常,并且所有主要浏览器都将证书显示为有效。

在BoraMa的帮助下,现在可以清楚地知道发生了什么。 COMODO添加了一个名为COMODO RSA Certification Authority的新根,而不是之前的COMODO Certification Authority 。 新的root用户未在Mac的钥匙串中注册,导致此问题。

我们尝试调试此方法的一种方法是运行:

 openssl s_client -connect www.mysite.com:443 

其中显示警告verify error:num=20:unable to get local issuer certificate 。 此警告不是问题,因为openssl s_client默认情况下不使用任何证书。 将证书从COMODO下载到comodo.pem ( 此处为索引)后,运行以下命令可以防止出现警告:

 openssl s_client -connect www.mysite.com:443 -CAfile comodo.pem 

但是,这不能也不会影响Ruby OpenSSL接口。 这篇文章让我更加清楚,其作者创建的SSL医生脚本也很有帮助,因为它证实了这一假设。 文章建议查看OpenSSL::X509::DEFAULT_CERT_FILE ,对我来说是/usr/local/etc/openssl/cert.pem 。 该文件在我的机器上不存在,这意味着Apple的OpendSSL补丁正在使用Keychain App。 无论出于何种原因,将comodo.pem导入我的钥匙串并根据此post将其标记为受信任不起作用。

因此,解决方案是手动创建cert.pem文件。 我转到了钥匙串应用程序,并将所有系统根证书导出到system_root.pem 。 然后: cat system_root.pem comodo.pem > cert.pem并将该文件移动到/usr/local/etc/openssl/就可以了。 在Ruby中运行Net::HTTP.get不再失败。

如果它包含COMODO_RSA_Certification_Authority.pem证书,我会尝试仔细检查可信证书库。 在我的(Linux)设置中,该站点正常工作,但是当我暂时从证书存储中删除COMODO证书颁发机构的证书时,我得到与您完全相同的错误(在浏览器中它仍然有效,因为它们有自己的证书库)。

顺便说一句,同样的错误也可以使用curl识别,因为它似乎也使用与ruby相同的可信证书存储,因此您可能首先确保该站点在curl下工作。

在linux中,cert存储通常位于/etc/ssl/certs而在OSX下它应该是/System/Library/OpenSSL (有关其他选项,请参阅此文章 )。

您应该在cert store目录中看到类似以下内容的内容:

 root@apsara:/etc/ssl/certs$ ls -l | grep COMODO_RSA_Certification_Authority.pem lrwxrwxrwx 1 root root 73 úno 28 10:24 COMODO_RSA_Certification_Authority.pem -> /usr/share/ca-certificates/mozilla/COMODO_RSA_Certification_Authority.crt lrwxrwxrwx 1 root root 38 úno 28 10:24 d4c339cb.0 -> COMODO_RSA_Certification_Authority.pem lrwxrwxrwx 1 root root 38 úno 28 10:24 d6325660.0 -> COMODO_RSA_Certification_Authority.pem 

以下是此根CA证书的一些属性:

 $ openssl x509 -in COMODO_RSA_Certification_Authority.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 4c:aa:f9:ca:db:63:6f:e0:1f:f7:4e:d8:5b:03:86:9d Signature Algorithm: sha384WithRSAEncryption Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority Validity Not Before: Jan 19 00:00:00 2010 GMT Not After : Jan 18 23:59:59 2038 GMT Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:91:e8:54:92:d2:0a:56:b1:ac:0d:24:dd:c5:cf: ... Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: BB:AF:7E:02:3D:FA:A6:F1:3C:84:8E:AD:EE:38:98:EC:D9:32:32:D4 X509v3 Key Usage: critical Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha384WithRSAEncryption ... 

证书可以在这里从Comodo下载(所有证书的索引都在这里 )。

更多信息 :在调查过程中,事实certificateComodo CA实际上有两个不同的证书认证链。 一个是较旧的,是上面列出的根CA的那个。 较新的validation链使用链中的“外部CA根”证书。 此论坛post进一步解释了OSX的具体说明,用于将这些证书标记为可信任。

听起来问题在于您的OSX证书缓存。 我猜你在旧证书到期之前更新了你的证书?

尝试通过运行以下命令清除OSX系统范围的CRL缓存:

 crlrefresh rpv # p - purges cache, r - refreshes them, v - run in verbose mode 

这是一个内置的命令行工具,可以更新和维护系统范围的CRL缓存。 在其man页( mand crlrefresh )中阅读更多相关信息。

因为这个错误,我整个早上一直把头发拉出来。 这个问题和答案使我得到了一个适合我的解决方案。 我不是在这里添加新信息,而只是我所做的具体细节,以防在类似我的平台上使用此错误的任何人使用它。

我正在使用:

 Ubuntu 16.04 ruby 2.3.0 rails 4.2.7.1 HTTParty 

我正在访问使用COMODO SSL证书保护的API。 在我的代码中,当我尝试时:

 HTTParty.get(secured_url).tap{|response| puts response} 

我有:

 SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError) 

我也使用上面提到的SSL医生脚本。 当我运行脚本(用我的实际api服务器地址代替host )时,我得到了:

 $ ruby doctor.rb host:443 /home//.rvm/rubies/ruby-2.3.0/bin/ruby (2.3.0-p0) OpenSSL 1.0.2g 1 Mar 2016: /usr/lib/ssl SSL_CERT_DIR="" SSL_CERT_FILE="" HEAD https://host:443 OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed The server presented a certificate that could not be verified: subject:  issuer: /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA error code 20: unable to get local issuer certificate 

在一个单独的终端中,我进入了我的certs目录:

 $ cd /etc/ssl/certs 

并且(使用从上面的issuer文本派生的COMODO_RSA_Organization_Validation_Secure_Server_CA ):

 :/etc/ssl/certs$ openssl x509 -in COMODO_RSA_Organization_Validation_Secure_Server_CA.pem -noout -text Error opening Certificate COMODO_RSA_Organization_Validation_Secure_Server_CA.pem 140455648364184:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('COMODO_RSA_Organization_Validation_Secure_Server_CA.pem','r') 140455648364184:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400: unable to load certificate 

我去了COMODO RSA组织validation安全服务器CA pem所在的COMODO站点。 我将证书复制到我桌面上名为COMODO_RSA_Organization_Validation_Secure_Server_CA.crt的新文件中(即使您需要pem证书内容,一些说明也会使用crt扩展而不是pem )。

然后,按照这些说明 ,我做了:

 :~/Desktop$ sudo cp COMODO_RSA_Organization_Validation_Secure_Server_CA.crt /usr/share/ca-certificates/COMODO_RSA_Organization_Validation_Secure_Server_CA.crt :~/Desktop$ sudo dpkg-reconfigure ca-certificates 

然后我做了:

 sudo dpkg-reconfigure ca-certificates 

然后:

 :~/Desktop$ ruby doctor.rb host:443 /home//.rvm/rubies/ruby-2.3.0/bin/ruby (2.3.0-p0) OpenSSL 1.0.2g 1 Mar 2016: /usr/lib/ssl SSL_CERT_DIR="" SSL_CERT_FILE="" HEAD https://host:443 OK 

之后我的代码运行正常。 谢谢你,谢谢你,谢谢你!