这是我第一次尝试使用XMLRPC::Client库与远程API交互,但我一直收到此错误:
warning: peer certificate won't be verified in this SSL session
我四处搜索,发现很多人都遇到过这个错误。通常是自签名证书,他们只是想让它消失,所以他们做了一些肮脏的事情,比如猴子补丁XMLRPC::Client打开它的http会话的方式。
我一开始以为这只是客户端不关心证书是否有效,所以我继续搜索,发现了this gem。它只是强制验证所有SSL证书,如果无法验证,则抛出一个硬错误。这正是我想要的。我包含了它,再次运行代码,现在我得到了以下结果:
OpenSSL:SSL::SSLError:
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:
certificate verify failed
当然!证书是坏的!但是我仔细检查了一下,以确保使用openssl的内置s_client,如下所示:
openssl s_client -connect sub.example.com:443
我得到了什么
CONNECTED(00000003)
---
Certificate chain
<snip>
Verify return code: 0 (ok)
所以现在我们来回答我的问题。OpenSSL(命令行版本)说证书是好的。OpenSSL(Ruby库)不同意。我所有的Web浏览器都说证书是好的。
一些可能有用的附加细节。证书是通配符,但对域有效。openssl s_client在Ruby代码之外的几秒钟内在同一台机器上运行。这是Ruby 1.8.7 p357,它是随RVM安装的。
Ruby是否使用了主机操作系统提供的CA包之外的东西?是否有方法告诉Ruby使用特定的CA包或系统的CA包?
3条答案
按热度按时间ql3eal8s1#
如果您只对如何使Ruby的行为与OpenSSL
s_client
或您的浏览器相同感兴趣,您可以跳到最后一节,我将在下面介绍细节。默认情况下,用于建立连接的
OpenSSL::X509::Store
根本不使用任何受信任证书。根据您对应用程序域的了解,您通常会为X509::Store
示例提供与您的应用程序相关的受信任证书。为此,有以下几个选项:“浏览器”方法
这与浏览器、Java(cacerts),或者Windows有自己的内部存储的可信证书,take.在那里,软件预先配备了一组可信证书,在软件供应商看来,这些证书被认为是“好的”.一般来说,这是一个不错的主意,但如果你实际上查看这些集合,那么你很快就会注意到证书太多了,一个人无法真正判断是否应该盲目地信任所有这些证书。
Ruby方法
另一方面,典型的Ruby应用程序的要求与浏览器的要求有很大的不同。浏览器必须能够让您导航到任何带有TLS证书并通过https提供服务的“合法”网站。但在典型的Ruby应用程序中,您只需处理少数使用TLS或需要证书验证的服务。
Ruby方法还有一个好处--尽管它需要更多的手工工作,但最终您将得到一个手工定制的解决方案,该解决方案完全信任在给定应用程序上下文中它应该信任的证书。这很乏味,但这种方法的安全性要高得多,因为暴露的攻击面要少得多。以最近的事件为例:如果您从未将DigiNotar或任何其他受危害的根包含在您的信任集中,则此类违规行为不会影响您。
但是,正如您已经注意到的,这样做的缺点是,默认情况下,如果您不主动添加可信证书,OpenSSL扩展将无法验证 * 任何 * 对等证书。为了使其正常工作,您必须手动设置配置。
这种不便导致了许多可疑的措施来绕过它,最糟糕的是全局设置
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
。请不要这样做。我们甚至开玩笑说,如果我们遇到这种黑客攻击,可以添加代码让您的应用程序随机崩溃:)如果手动信任设置看起来太复杂,我现在将提供一个简单的替代方案,使OpenSSL扩展的行为与
s_client
等OpenSSL CLI命令完全相同。为什么s_client可以验证证书
OpenSSL使用类似于浏览器和Windows的方法。典型的安装会将一组可信证书放在硬盘上的某个地方(类似于
/etc/ssl/certs/ca-bundle.crt
),这将作为默认的可信证书集。s_client
需要验证对等证书时会查找该位置,这也是您的实验成功的原因。让Ruby像s_client一样运行
如果您仍然希望在使用Ruby验证证书时获得相同的舒适度,您可以通过调用
OpenSSL::X509::Store#set_default_paths
来告诉它使用OpenSSL受信任证书包(如果系统上有)。更多信息可以在此处找到。要在XMLRPC::Client
中使用此功能,只需确保set_default_paths
在其使用的X509::Store
上被调用。txu3uszq2#
多亏了emboss的回答帮助我解决了这个问题。下面是我的解决方案,monkeypatch可以全局启用系统信任证书,而无需更改客户端代码。它适用于依赖
net/http
的gem。例如rest-client
jaql4c8m3#
如果您有ca-certificates文件,只需执行以下操作: