简体   繁体   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

I have a Rails app running on a Heroku server and I'm having trouble communicating with an external server using Net::HTTP over HTTPS. 我有一个在Heroku服务器上运行的Rails应用程序,我在通过HTTPS使用Net :: HTTP与外部服务器通信时遇到问题。 The error I'm receiving whenever I attempt to POST to an external proprietary API over HTTPS is: 每当我尝试通过HTTPS POST到外部专有API时,我收到的错误是:

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

I've done quite a few hours of Googling around for an answer to the issue I'm encountering, but to no avail. 我已经花了几个小时的谷歌搜索来解决我遇到的问题,但无济于事。 Here's my environment: 这是我的环境:

  • Heroku Dyno running Cedar 14 (was running Cedar 10, upgraded to Cedar 14 to see if it would affect the issue - no joy) Heroku Dyno运行Cedar 14(正在运行Cedar 10,升级到Cedar 14,看它是否会影响问题 - 没有快乐)
  • Rails 3.2.14rc2 Rails 3.2.14rc2
  • Ruby 2.1.2 Ruby 2.1.2

"Fixes" I have tried: “修复”我尝试过:

  • Running the certified gem (which has actually seemed to help out with communication via Omniauth and Google's API) 运行certified gem (实际上似乎有助于通过Omniauth和Google的API进行通信)
  • Monkey-patch removing SSLv2, SSLv3 from the list of verification methods . Monkey-patch从验证方法列表中删除SSLv2,SSLv3 When I attempt this in the console on Heroku's server, it appears to work well enough for GET methods, but appears ignore the adjustments completely when attempting to Run Net::HTTP::Post.new instead of Net::HTTP::Get.new 当我在Heroku的服务器上的控制台中尝试这个时,它似乎对GET方法运行良好,但在尝试运行Net::HTTP::Post.new而不是Net::HTTP::Get.new时,似乎完全忽略调整Net::HTTP::Get.new
  • Manually overriding the certificate file location . 手动覆盖证书文件位置 I've specified it to use the authority file of the operating system (which on the Cedar-14 stack is up-to-date), but still no dice. 我已经指定它使用操作系统的权限文件(在Cedar-14堆栈上是最新的),但仍然没有骰子。
  • I have also tried manually specifying in on the Net::HTTP object to use ssl_version="TLSv1_2" with no luck (it even keeps reporting the same SSLv3 related error) 我也尝试在Net :: HTTP对象上手动指定使用ssl_version="TLSv1_2"而没有运气(它甚至报告了相同的SSLv3相关错误)

The communication appears to be working just fine when run locally in development (I've used the RVM override method suggested here ), but the moment I try things on the Heroku server, I'm out of luck. 在开发中本地运行时,通信似乎工作得很好(我已经使用了这里建议RVM覆盖方法 ),但是当我在Heroku服务器上尝试时,我运气不好。

UPDATE: It appears this is not working locally either even with the RVM update. 更新: 即使使用RVM更新,它似乎也无法在本地运行。

Last, but not least, here is an abstracted variant of the code I'm running: 最后,但并非最不重要的,这是我正在运行的代码的抽象变体:

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)

Anyone have any advice on what else I should be looking at? 任何人对我还应该关注什么有任何建议?

Heroku can't verify your server's certificate is validly signed by a CA root it recognizes. Heroku无法验证您的服务器证书是否由其识别的CA根有效签名。 This can be because either: 这可能是因为:

  1. Your cert isn't signed by a CA or intermediate (ie, self-signed) 您的证书未经CA或中级签署(即自签名)
  2. Your cert is signed by a CA that Heroku doesn't know about (unlikely) 您的证书由Heroku不知道的CA签署(不太可能)
  3. The API server isn't providing the correct intermediate certs to help Heroku connect it to a valid CA root. API服务器未提供正确的中间证书,以帮助Heroku将其连接到有效的CA根目录。 (likely) (可能)

Try openssl s_client -showcerts -connect your-api-host.com:443 from your shell. 从shell中尝试openssl s_client -showcerts -connect your-api-host.com:443 You should see something like: 你应该看到类似的东西:

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

You're specifically looking to make sure that all certs in the chain return verify return: 1 . 您特别希望确保链中的所有证书都返回verify return: 1 If this works from your shell, then your machine likely has root certs installed that your Heroku instance doesn't. 如果这可以从您的shell运行,那么您的计算机可能已安装了您的Heroku实例没有的根证书。

Without knowing exactly what certs your API server is returning, it's hard to answer this definitively, but you probably need to be serving an intermediate cert bundle along with the SSL cert itself. 在不确切知道您的API服务器返回哪些证书的情况下,很难明确地回答这个问题,但您可能需要提供中间证书捆绑以及SSL证书本身。 This intermediate cert bundle will be provided by your SSL certificate signer, and can be provided in Apache via SSLCertificateChainFile , or in nginx by concatening the intermediates with your cert (per this documentation ). 此中间证书包将由您的SSL证书签名者提供,并可通过SSLCertificateChainFile在Apache中提供,或通过将中间人与您的证书(根据此文档 )连接在nginx中提供。

If you can't alter the configuration of the API server, then your "Manually overriding the certificate file location" solution is probably very close to correct (it's the same thing as the server providing the intermediate cert, except the client does it), but you are likely not providing the correct certificate chain bundle for your API server's certificates. 如果您无法更改API服务器的配置,那么您的“手动覆盖证书文件位置”解决方案可能非常接近正确(这与提供中间证书的服务器相同,除了客户端执行此操作),但您可能没有为API服务器的证书提供正确的证书链包。 Make sure that you have the correct intermediate certificate chain provided to OpenSSL, and it should work as desired. 确保为OpenSSL提供了正确的中间证书链,并且它应该可以正常工作。

暂无
暂无

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

相关问题 OpenSSL :: SSL :: SSLError-SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败 - OpenSSL::SSL::SSLError - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed OpenSSL :: SSL :: SSLError(返回的SSL_connect = 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败) - OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed) OpenSSL :: SSL :: SSLError SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败 - OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败 - OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败-向外部API耙任务 - OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed - rake task to external API SSL_connect 返回=1 errno=0 state=SSLv3 读取服务器证书B:证书验证失败 - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:Mac上的证书验证失败 - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed on Mac OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器会话票证A:sslv3警报证书已吊销 - OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server session ticket A: sslv3 alert certificate revoked Google Oauth SSL错误 - SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败 - Google Oauth SSL error - SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed 检索PEM证书:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败 - Retrieve PEM cert: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM