Heroku Rails Net :: HTTP:OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败

戴夫·谢泼德

我有一个在Heroku服务器上运行的Rails应用,但在通过HTTPS使用Net :: HTTP与外部服务器通信时遇到问题。每当我尝试POST通过HTTPS访问外部专有API时收到的错误是:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

我已经花了几个小时的时间来Google搜索,以解决我遇到的问题,但无济于事。这是我的环境:

  • Heroku Dyno运行Cedar 14(运行Cedar 10,已升级到Cedar 14,以查看是否会影响该问题-没什么高兴)
  • 导轨3.2.14rc2
  • Ruby 2.1.2

我尝试过的“修复”:

  • 运行certifiedgem(实际上似乎有助于通过Omniauth和Google的API进行通信)
  • 猴子补丁从验证方法列表中删除SSLv2,SSLv3当我在Heroku服务器的控制台中尝试此操作时,它似乎可以很好地用于GET方法,但是在尝试运行Net::HTTP::Post.new而不是运行时,似乎完全忽略了调整Net::HTTP::Get.new
  • 手动覆盖证书文件位置我已指定它使用操作系统的授权文件(在Cedar-14堆栈上是最新的),但仍然没有骰子。
  • 我也尝试过在Net :: HTTP对象上手动指定要使用ssl_version="TLSv1_2",但没有运气(它甚至一直报告相同的SSLv3相关错误)

当在开发环境中本地运行时,通信似乎运行良好(我已经使用了此处建议RVM覆盖方法),但是当我在Heroku服务器上尝试操作时,我很不走运。

更新:看来,即使使用RVM更新,它也不在本地工作。

最后但并非最不重要的是,这是我正在运行的代码的抽象变体:

uri = URI.parse("https://api.mysite.com/api/v1")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == "https")
request = Net::HTTP::Post.new(uri.path, {'Content-Type' =>'application/json'})
request_body = "{\"post_body\": \"data1\"}"
response = http.request(request)

有人对我还要看的东西有什么建议吗?

克里斯·希尔德

Heroku无法验证服务器的证书是否由其识别的CA根有效签名。这可能是因为:

  1. 您的证书未由CA或中间机构签名(即,自签名)
  2. 您的证书是由Heroku不知道的CA签名的(不太可能)
  3. API服务器未提供正确的中间证书来帮助Heroku将其连接到有效的CA根目录。(可能)

尝试openssl s_client -showcerts -connect your-api-host.com:443从您的外壳。您应该看到类似以下内容:

depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = www.coffeepowered.net
verify return:1

您特别希望确保链中的所有证书都返回verify return: 1如果这在您的Shell上有效,则您的计算机可能安装了Heroku实例未安装的根证书。

在不确切知道您的API服务器将返回什么证书的情况下,很难确定答案,但是您可能需要将中间证书包与SSL证书本身一起提供。此中间证书捆绑包将由您的SSL证书签名者提供,并且可以通过SSLCertificateChainFile在Apache中提供,或者通过将中间件与您的证书连接(在本文档中在nginx中提供

如果您无法更改API服务器的配置,则您的“手动覆盖证书文件位置”解决方案可能非常接近正确(这与提供中间证书的服务器相同,只是客户端可以这样做),但是您可能没有为API服务器的证书提供正确的证书链捆绑包。确保您具有正确的提供给OpenSSL的中间证书链,并且该链应该可以按需工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档