OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certif
Posted
技术标签:
【中文标题】OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed【英文标题】: 【发布时间】:2012-05-30 12:03:51 【问题描述】:我使用 RVM 在 Ubuntu 12.04 上安装 Ruby 1.9.3
rvm pkg install openssl
rvm install 1.9.3 --with-openssl-dir=$rvm_path/usr
然后当我尝试按照以下方式运行时:
require 'open-uri'
open('https://www.google.com/')
我收到错误:
我该如何解决这个问题?我有很多类似的线程,人们在 OSX 中遇到这个问题,但是我如何在 Ubuntu 中解决它?
感谢您的帮助。
【问题讨论】:
【参考方案1】:如果未使用本机 OpenSSL 库正确设置默认的“OpenSSL 目录”,有时会发生这种情况。 open-uri 使用OpenSSL::X509::Store#set_default_paths
来告诉 OpenSSL 在 OpenSSL 目录中查找包含 OpenSSL 默认信任的受信任根证书的文件。
在您的情况下,此查找失败。您可以通过设置一个覆盖默认设置并告诉 OpenSSL 查找该目录的环境变量来使其成功:
export SSL_CERT_FILE=/etc/pki/tls/cert.pem
这是我的 Fedora 16 64 位上根 CA 包的默认位置,其他常用位置是 /etc/ssl/ca-bundle.crt 等。在您的情况下,RVM 使用的 OpenSSL 库位于 $rvm_path /usr,所以你应该在那里寻找一个合适的默认根 CA 文件的候选者。环境变量设置正确后,调用open-uri就成功了。
要使环境变量永久化,请使用常用方法,例如在 .bashrc、/etc/profile 或任何最适合您的情况下定义导出。
【讨论】:
在我的 Ubuntu 安装中,我必须设置export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
+1 解决了我的问题,具体解释了问题所在!【参考方案2】:
将“认证”gem 添加到您的 Gemfile。
更多信息:https://rubygems.org/gems/certified
【讨论】:
Windows 用户请遵循此解决方案。如果我之前遇到过这个解决方案,我会节省更多时间。 如何使用它?我在我的机器上安装了 gem,但是之后呢? @SaifAlFalah 应该是这样,gem 会安装一个证书包供 openssl 使用,如果它找不到的话。请注意,这也是 3 岁,所以事情可能已经改变...... 是的,它确实适用于 Windows :) 我浪费了很多时间试图解决这个问题。谢谢@Meekohi 在 Debian 和 Ubuntu 上为我工作。其他解决方案对我不起作用。【参考方案3】:rvm 安装的 openssl 中缺少 cacert.pem 文件。
$ cd $rvm_path/usr/ssl
$ sudo curl -O http://curl.haxx.se/ca/cacert.pem
$ sudo mv cacert.pem cert.pem
【讨论】:
【参考方案4】:请参阅http://jjinux.blogspot.nl/2012/02/ruby-working-around-ssl-errors-on-os-x.html 作为您问题的替代答案,它应该适用于 Ubuntu 和 Mac OS X 用户,并且不需要更改环境变量。
来自上述链接的解决方案:
# config/initializers/fix_ssl.rb
#
# Work around errors that look like:
#
# SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
require 'open-uri'
require 'net/https'
module Net
class HTTP
alias_method :original_use_ssl=, :use_ssl=
def use_ssl=(flag)
# Ubuntu
if File.exists?('/etc/ssl/certs')
self.ca_path = '/etc/ssl/certs'
# MacPorts on OS X
# You'll need to run: sudo port install curl-ca-bundle
elsif File.exists?('/opt/local/share/curl/curl-ca-bundle.crt')
self.ca_file = '/opt/local/share/curl/curl-ca-bundle.crt'
end
self.verify_mode = OpenSSL::SSL::VERIFY_PEER
self.original_use_ssl = flag
end
end
end
【讨论】:
谢谢你。除此之外,我需要将证书从我的 Ubuntu 上传到 Debian 服务器,并将 ca_path 指向上传目录。当我更新 Debian 软件包时,我的证书被搞砸了。【参考方案5】:这确实对我有用。当我运行“brew doctor”时,事情开始起作用了,这让我找到了诸如“unset SSL_CERT_DIR”之类的线索
【讨论】:
【参考方案6】:检查你的系统时钟!!
长时间(1 周)未使用虚拟机后出现此错误。更新我的系统时钟立即解决了这个问题。
如果您正在运行 ntpd
,那么 ntpdate -b -u pool.ntp.org
将为您执行此操作。
【讨论】:
以上是关于OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certif的主要内容,如果未能解决你的问题,请参考以下文章
使用 Ruby on Rails 的 HTTP GET 请求:OpenSSL::SSL::SSLError
带有 fb_auth.exchange_token 的 OpenSSL::SSL::SSLError
OpenSSL::SSL::SSLError(主机名“smtp.mandrillapp.com”与服务器证书不匹配)
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certif
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv3/TLS write client hello
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certif