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

时间:2016-05-01 12:29:51

标签: ruby ssl openssl ssl-certificate net-http

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

require 'net/http'

Net::HTTP.get URI('https://www.google.com')
# => "<HTML>...</HTML>"

# 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本地缓存有关。
  • 此问题可能在证书续订前已存在。我无法确定。但是,正如我在this question中讨论的那样,更新确实会导致我们使用的第三方出现类似的问题。
  • 证书安装已由Namecheap验证为正确,在线检查程序显示一切正常,所有主要浏览器都将证书显示为有效。

解决方案

在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默认情况下不使用任何证书。将证书from COMODO下载到comodo.pem(索引here)后,运行以下命令可以防止出现警告:

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

然而,这不会也不会影响Ruby OpenSSL接口。 This article使我的事情变得更加清晰,其作者创建的SSL doctor script也很有帮助,因为它证实了这一假设。文章建议查看OpenSSL::X509::DEFAULT_CERT_FILE,对我而言/usr/local/etc/openssl/cert.pem。该文件在我的机器上不存在,这意味着Apple的OpendSSL补丁正在使用Keychain App。无论出于何种原因,将comodo.pem导入我的钥匙串并根据this post将其标记为受信任不起作用。

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

3 个答案:

答案 0 :(得分:3)

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

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

在linux中,证书库通常位于/etc/ssl/certs,而在OSX下,它应该是/System/Library/OpenSSL(其他选项请参阅this article)。

您应该在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 here下载(所有证书的索引是here)。

更多信息:在调查结果时,事实证明Comodo CA实际上有两个不同的证书认证链。一个是较旧的,是上面列出的根CA的那个。较新的验证链使用链中的“外部CA根”证书。 This forum post进一步解释了以及OSX的具体说明,以便将这些证书标记为可信。

答案 1 :(得分:0)

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

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

crlrefresh rpv

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

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

答案 2 :(得分:0)

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

我正在使用:

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/<redacted>/.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: <redacted>
  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

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

$ cd /etc/ssl/certs

并且(使用COMODO_RSA_Organization_Validation_Secure_Server_CA来自issuer文字的<redacted>:/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_Organization_Validation_Secure_Server_CA.crt

我去了COMODO RSA Organization Validation Secure Server CA pem所在的COMODO网站。我将证书复制到桌面上名为crt的新文件中(即使您需要pem证明内容,但有些说明会使用pem扩展名而不是<redacted>:~/Desktop$ sudo cp COMODO_RSA_Organization_Validation_Secure_Server_CA.crt /usr/share/ca-certificates/COMODO_RSA_Organization_Validation_Secure_Server_CA.crt <redacted>:~/Desktop$ sudo dpkg-reconfigure ca-certificates

然后,在these instructions之后,我做了:

sudo dpkg-reconfigure ca-certificates

然后我做了:

<redacted>:~/Desktop$ ruby doctor.rb host:443
/home/<redacted>/.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

然后:

{{1}}

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