I'm using Ubuntu 12.04LTS Desktop to develop a Shopify App (using the shopify_app gem), and I ran into this problem when processing the callback URL.
Faraday::Error::ConnectionFailed (Connection reset by peer - SSL_connect)
Looking at the shopify-app-discuss group here and here, it seems that the problem is with Ubuntu 12.04 and its OpenSSL.
I tried to install the most up-to-date OpenSSL, but nothing. One alternative that I found was to use a different, older OpenSSL, one that RVM provides.
$ rvm remove 1.9.3 (or whatever version of ruby you are using)
$ rvm pkg install openssl
$ rvm install 1.9.3 --with-openssl-dir=$rvm_path/usr
And now the Shopify App is working fine. It can connect to the API. (This tip may help other Ubuntu 12.04 users!)
So, my question is: Is this the best solution? I'm a little bit concerned about the older OpenSSL version. It might have some security issues. Is it safe to develop the app with this?
And when I deploy the app (e.g. Heroku), is there going to be a security issue with an older OpenSSL?
Thanks in advance!
The other suggestions didn't work for us. Specifically we needed to force :SSLv3
instead of :TLSv1
. (For both the stock Ubuntu 12.04.01 Ruby 1.9.3 and the one that we use from the Passenger PPM.)
Also, there needs to be a check for @ssl_options
being defined. I copied the one from the ActiveResource Implementation.
We dropped this in config/initializers/shopify_ssl.rb
and everything is peachy:
require 'active_resource/connection'
class ActiveResource::Connection
def apply_ssl_options_with_ssl_version(http)
apply_ssl_options_without_ssl_version(http)
return http unless defined?(@ssl_options)
http.ssl_version = @ssl_options[:ssl_version] if @ssl_options[:ssl_version]
http
end
alias_method_chain :apply_ssl_options, :ssl_version
end
ShopifyAPI::Base.ssl_options = { :ssl_version => :SSLv3 }
Whilst latest version of OpenSSL is a holy matrimony of not-yet-discovered security holes, I'd say that you should use the library that works for you at that particular moment. There's no software without security holes, and unless you can influence server-side to upgrade to something compatible with latest SSL versions I'm afraid your options are limited.
When using the most recent OpenSSL library, your client is most likely trying to connect using TLS 1.2, one of the more recent SSL/TLS protocols used in HTTPS. Our load balancing hardware has a known problem with TLS 1.2, although we weren't aware of it until I independently stumbled upon this bug myself.
I've made the rest of the Operations team aware of this, and I expect we'll be fixing this as soon as possible. Until then, you can use
http.ssl_version = :TLSv1
to force Ruby to use TLS 1.0 instead.
Here's an example of how to apply this workaround to ActiveResource, the gem that the shopify_api
gem uses internally:
require 'active_resource/connection'
class ActiveResource::Connection
def apply_ssl_options_with_ssl_version(http)
apply_ssl_options_without_ssl_version(http)
http.ssl_version = @ssl_options[:ssl_version] if @ssl_options[:ssl_version]
http
end
alias_method_chain :apply_ssl_options, :ssl_version
end
Now you can use
ShopifyAPI::Base.ssl_options = {:ssl_version => :TLSv1}
to work around the problem.
Thou shalt always use the last version of OpenSSL.