繁体   English   中英

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

[英]Heroku Rails Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

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

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

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

  • Heroku Dyno运行Cedar 14(正在运行Cedar 10,升级到Cedar 14,看它是否会影响问题 - 没有快乐)
  • Rails 3.2.14rc2
  • Ruby 2.1.2

“修复”我尝试过:

  • 运行certified gem (实际上似乎有助于通过Omniauth和Google的API进行通信)
  • Monkey-patch从验证方法列表中删除SSLv2,SSLv3 当我在Heroku的服务器上的控制台中尝试这个时,它似乎对GET方法运行良好,但在尝试运行Net::HTTP::Post.new而不是Net::HTTP::Get.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根目录。 (可能)

从shell中尝试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提供了正确的中间证书链,并且它应该可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM