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

查看:147
本文介绍了Heroku Rails Net :: HTTP:OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0 state = SSLv3读取服务器证书B:证书验证失败

为了解决我遇到的问题,我花了不少时间搜索Google,但无济于事。这是我的环境:


  • 运行Cedar 14的Heroku Dyno(运行Cedar 10,升级到Cedar 14,看它是否会影响问题 - 没有喜悦)

  • Rails 3.2.14rc2

  • Ruby 2.1.2



Fixes我试过了:



在开发本地运行时,通信似乎正常工作(我使用此处建议使用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)
pre>

任何人都有什么建议,我应该看看什么?

解决方案

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


  1. 您的证书未由CA或中间人签名(即自签名)

  2. 您的证书由Heroku不知道的CA签名(不太可能)

  3. API服务器没有提供正确的中间证书来帮助Heroku连接它到一个有效的CA根。 (很可能)

尝试 openssl s_client -showcerts -connect your-api-host.com:443从你的shell。您应该看到如下所示的内容:

  depth = 3 C = SE,O = AddTrust AB,OU = AddTrust External TTP Network,CN = AddTrust External CA Root 
验证返回:1
depth = 2 C = GB ST =更大的曼彻斯特L = Salford O = COMODO CA有限公司CN = COMODO RSA证书颁发机构
验证返回:1
depth = 1 C = GB,ST =更大的曼彻斯特,L =索尔福德,O = COMODO CA有限公司,CN = COMODO RSA域验证安全服务器CA
验证返回:1
深度= 0 OU =域控制验证,OU =正面SSL,CN = www.coffeepowered.net
验证退货:1

您特别希望确保链中的所有证书都返回 verify return:1 。如果这从你的shell运行,那么你的机器可能已经安装了根证书,而你的Heroku实例没有。



不知道你的API服务器返回的证书是什么,它是很难明确回答这个问题,但是您可能需要提供中间证书包以及SSL证书本身。该中间证书包将由您的SSL证书签名者提供,并且可以通过 SSLCertificateChainFile ,或者在nginx中将中间体与您的证书进行连接(每个

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. The error I'm receiving whenever I attempt to POST to an external proprietary API over HTTPS is:

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)
  • Rails 3.2.14rc2
  • 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)
  • Monkey-patch removing SSLv2, SSLv3 from the list of verification methods. 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
  • 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.
  • 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)

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.

UPDATE: It appears this is not working locally either even with the RVM update.

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. This can be because either:

  1. Your cert isn't signed by a CA or intermediate (ie, self-signed)
  2. Your cert is signed by a CA that Heroku doesn't know about (unlikely)
  3. The API server isn't providing the correct intermediate certs to help Heroku connect it to a valid CA root. (likely)

Try openssl s_client -showcerts -connect your-api-host.com:443 from your shell. 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. If this works from your shell, then your machine likely has root certs installed that your Heroku instance doesn't.

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. 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).

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. Make sure that you have the correct intermediate certificate chain provided to OpenSSL, and it should work as desired.

这篇关于Heroku Rails Net :: HTTP:OpenSSL :: SSL :: SSLError:SSL_connect返回= 1 errno = 0状态= SSLv3读取服务器证书B:证书验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆