这是我第一次尝试使用XMLRPC :: Client库与远程API进行交互,并且我一直收到此错误:
warning: peer certificate won't be verified in this SSL session
在我周围搜索我发现了很多人犯了这个错误。通常它带有自签名证书,他们只是想让它消失,所以他们做了像Monkey patch那样脏的东西,就像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库)不同意。我的所有网络浏览器都说证书很好。
可能有用的一些其他细节。证书是通配符,但对域有效。 openssl s_client在距离Ruby代码几秒钟的同一台机器上运行。这是与Windows一起安装的Ruby 1.8.7 p357。
Ruby是否使用主机操作系统提供的CA捆绑以外的东西?有没有办法告诉Ruby使用特定的CA捆绑包或系统?
答案 0 :(得分:111)
如果您只对如何使Ruby的行为与OpenSSL s_client
或浏览器的行为一样感兴趣,您可以跳到最后一部分,我将在下面的内容中介绍细则。
默认情况下,用于建立连接的OpenSSL::X509::Store
根本不使用任何受信任的证书。根据您对应用程序域的了解,您通常会为X509::Store
的实例提供与您的应用程序相关的可信证书。有几种选择:
这与方法浏览器,Java(cacerts)或具有自己的可信证书内部存储的Windows相反。在那里,软件预先配备了一组可信证书,在软件供应商看来,这些证书被认为是“好的”。一般来说,这不是一个坏主意,但如果您真正研究这些集合,那么您很快就会注意到证书太多了。个人无法确定是否应盲目信任所有这些证书。
另一方面,典型Ruby应用程序的要求与浏览器的要求有很大不同。浏览器必须能够让您导航到任何带有TLS证书的“合法”网站,并通过https提供。但是在典型的Ruby应用程序中,您只需要处理一些使用TLS的服务,否则需要进行证书验证。
Ruby方法的好处 - 虽然它需要更多的手动工作,但最终会得到一个手动定制的解决方案,它完全信任它在给定应用程序上下文中应该信任的证书。这很乏味,但这种方式的安全性要高得多,因为你暴露了更少的攻击面。最近的事件:如果您从未在您的信任集中包含DigiNotar或任何其他受到破坏的根,那么这些违规行为不会对您产生影响。
然而,正如您已经注意到的那样,默认情况下,如果您不主动添加受信任证书,OpenSSL扩展将无法验证任何对等证书一点都不为了使工作正常,您必须手动设置配置。
这种不便导致了许多可疑的措施来规避它,最糟糕的是全球设定OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
。请不要这样做。我们甚至开了一些关于添加代码的笑话,如果我们遇到黑客攻击,你的应用程序会随机崩溃:)
如果手动信任设置看起来过于复杂,我现在提供一个简单的替代方案,使OpenSSL扩展的行为与s_client
等OpenSSL CLI命令完全相同。
OpenSSL使用与浏览器和Windows类似的方法。典型的安装会在硬盘上的某处放置一捆可信证书(类似/etc/ssl/certs/ca-bundle.crt
),这将作为默认的可信证书集。这是s_client
在需要验证对等证书时所看到的位置,这就是您的实验成功的原因。
如果您在使用Ruby验证证书时仍然希望获得相同的舒适度,您可以通过调用OpenSSL::X509::Store#set_default_paths
告诉它使用您系统上可用的OpenSSL可信证书包。可以找到其他信息here。要将其与XMLRPC::Client
一起使用,只需确保set_default_paths
在其使用的X509::Store
上进行调用。
答案 1 :(得分:0)
如果您有ca-certificates文件,请执行以下操作:
http.ca_file = <YOUR CA-CERT FILE PATH>
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.verify_depth = 5