作为一个版本控,总是希望保持电脑中各种软件到最新版本。
最近通过 brew 升级 OpenSSL 和 ruby-build 到最新,尤其是 ruby-build 支持最新的 Ruby 2.2.1,新版 Ruby 中针对 Symobl GC 的改进很让人期待,升级步骤略暴力,采用自毁重装的方式:
rm -rf ~/.rbenv
rbenv install 2.2.1
rbenv global 2.2.1
升级后发现所有的 ssl 的请求,都会报告证书验证错误
,具体错误信息如下:
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
暂时的解决方案,bypass 掉 SSL 的证书验证步骤,在 Rails 的 initalizers
中增加一个文件 bypass_ssl_verification.rb
,只一行代码:
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
不过 bypass 证书验证步骤只是权宜之计,在本地开发倒是无所谓,生产环境下必须不能这么干!因为如果不验证证书的话,其实是留下了安全隐患。造成证书验证错误问题的原因可能有三种:
首先检查证书不存在或者路径不对,brew 安装的 openssl 会把证书位置存放在这里:
/usr/local/etc/openssl/cert.pem
Ruby 运行环境中的 OpenSSL 的默认证书位置:
ruby -e "require 'openssl'; puts OpenSSL::X509::DEFAULT_CERT_FILE"
检查后发现 Ruby 运行环境中的结果跟 brew 安装的 OpenSSL 证书的位置完全对得上,且证书文件存在,说明不是证书丢失或者路径问题,最大的可能是证书过期了。
如果之前没有通过 brew 安装过 openssl 的话,ruby-build 会在编译 Ruby 的过程中自动下载并编译一份 openssl 到 ~/.rbenv
目录下,但是我亲测下来 ruby-build 自带的 openssl 也会产生同样的错误,所以最后还是决定保留 brew 安装的 openssl 版本,然后手动下载更新 ca root 证书的方式解决问题:
wget -c http://curl.haxx.se/ca/cacert.pem
mv cacert.pem /usr/local/etc/openssl/cert.pem
检查了一下,在 cert.pem 的头部有证书生成时间,是 2015 年 2 月 25 日,还算蛮新的。
##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: Wed Feb 25 04:12:04 2015
##