22

I have Rails API server hosted on Heroku, which makes an asynchronous POST request to a callback url specified in an initial API request by the client.

I have a problem when I try to POST to one of my clients' webapp over SSL.

connection = Faraday::Connection.new('https://subdomain.some_client.com', ssl: { ca_file: '/usr/lib/ssl/certs/ca-certificates.crt' })
connection.get '/test'

The following throws an error:

Faraday::Error::ConnectionFailed: SSL_connect returned=1 errno=0 state=error: certificate verify failed

However, if I post to another server over HTTPS, for example google, it works fine

connection = Faraday::Connection.new('https://www.google.com', ssl: { ca_file: '/usr/lib/ssl/certs/ca-certificates.crt' })
connection.get '/'

Does this mean the fault is on the client's SSL configuration? and if so, how can I assist them in debugging the problem?

UPDATE:

I can cURL POST to the client's webapp without problems, it's only when I do it through ruby's HTTP libraries it fails

Much appreciated Thanks

Tarlen
  • 3,657
  • 8
  • 30
  • 54

1 Answers1

19

My guess is that there is a problem with the SSL cert for your client's web app. Perhaps there is a certificate that is out of date or invalid. You could try this answer.

If you need to get around this (but probably not a good permanent solution, because of the potential security hole) you should be able to turn off the certificate verification by putting this before Bundler.require in your application.rb:

require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
rlarcombe
  • 2,958
  • 1
  • 17
  • 22
  • 3
    I tried that and it works, but it is obviously not suitable for a production environment – Tarlen Nov 12 '15 at 10:59
  • 5
    This test shows you are missing an intermediate or root cert in your ca-certificates.crt file. Are you still needing an answer? – Rodrigo Murillo May 19 '16 at 16:29
  • 1
    If the cert is out of date or invalid, curl would have reported similar error. – Akash Nov 15 '19 at 13:01
  • 1
    Variant if you get the "already initialized constant" warning: use `OpenSSL::SSL.send(:remove_const, :VERIFY_PEER)` before ([example code](https://gist.github.com/siruguri/66926b42a0c70ef7119e)). – tanius Mar 30 '20 at 20:19
  • @RodrigoM did you mean to ask the Tarlen? Since he wasn't tagged he may not have sen your comment – stevec May 31 '20 at 18:28
  • If you're using the Net::HTTP library, you have to do this instead: `http.verify_mode = OpenSSL::SSL::VERIFY_NONE` [reference](https://blog.engineyard.com/ruby-ssl-error-certificate-verify-failed) – Nejuf Mar 22 '21 at 23:51
  • You can put `OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE` in your config/environments/development.rb instead of in config/application.rb. That keeps it out of your production environment. – Beer Me Jun 22 '21 at 18:10