Ruby has some tools for interacting with websites. I guess they are mainly wrappers around
cURL. When the target website uses SSL (e.g.
https://github.com/...) then the server will present a certificate to identify itself. The Ruby script needs to verify the Certificate Authority (CA) that issued this certificate, otherwise you might be downloading from an imposter site.
The list of CAs is maintained in one or more
.pem files in a known place in your file system. At least that’s true on Linux and OS X, but not Windows. Windows is different and CA verification in Ruby is broken. Windows is a minority platform for Rails developers so this isn’t a big issue for them and it has remained unfixed through several version of Ruby and Rails. If you try to connect to an SSL site on Windows you’ll get these sort of messages:
C:/Ruby1.9.2/lib/ruby/1.9.1/net/http.rb:678:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
You can work around this in your code by downloading a
.pem file containing CA certificates and putting it a known place, then setting
http.ca_path to the folder containing the
.pem file. Or you can turn off verification altogether by setting
http.verify_mode = OpenSSL::SSL::VERIFY_NONE. Neither of these solutions is ideal but that’s what you’re stuck with if you insist on developing Rails apps on Windows.
But if it’s not your app that’s broken but Rails itself then you need to dig into the internals a bit to fix this. I came across the error when using a template from GitHub to create a new Rails app:
rails new myapp -m https://github.com/russfrisch/h5bp-rails/raw/master/h5bp.rb
I finally found a fix by hacking the
open-uri.rb file in
C:/Ruby1.9.2/lib/ruby/1.9.1/ (of course your path might be different). I simply changed the default SSL verification mode to
OpenSSL::SSL::VERIFY_NONE as described above. In my version it was line 288 and I changed it to read like this:
http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_NONE
There may be other approaches: the stack trace from the original error pointed at the Thor gem which is responsible for applying the template. This may give us a clue to why the problem hasn’t been fixed: the Rails gem, the Thor gem and the core Ruby scripts
/net/http.rb are all maintained by different developers. All their code probably works as intended in isolation – it’s the combination that gives us a problem in one particular environment.
I’d raise a bug but I don’t know which door to lay it at.