我们最近更新了我们网站的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
crlrefresh rpv
清除OSX系统范围的CRL缓存。我该如何解决这个问题?
注意:
在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
不再失败。
答案 0 :(得分:3)
如果它包含COMODO_RSA_Certification_Authority.pem
证书,我会尝试仔细检查可信证书库。在我的(Linux)设置中,该站点工作正常,但是当我暂时从证书存储中删除COMODO证书颁发机构的证书时,我得到与您完全相同的错误(在浏览器中它仍然有效,因为它们拥有自己的证书库)。
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}}
之后我的代码运行正常。谢谢,谢谢,谢谢!