public
Last active

Download a cacert.pem for RailsInstaller

  • Download Gist
README.md
Markdown

Why?

There is a long standing issue in Ruby where the net/http library by default does not check the validity of an SSL certificate during a TLS handshake. Rather than deal with the underlying problem (a missing certificate authority, a self-signed certificate, etc.) one tends to see bad hacks everywhere. This can lead to problems down the road.

From what I can see the OpenSSL library that Rails Installer delivers has no certificate authorities defined. So, let's go fetch some from the curl website. And since this is for ruby, why don't we download and install the file with a ruby script?

Installation

The Ruby Way! (Fun)

This assumes your have already installed the Rails Installer for Windows.

Download the ruby script to your Desktop folder from https://gist.github.com/raw/867550/win_fetch_cacerts.rb. Then in your command prompt, execute the ruby script:

ruby "%USERPROFILE%\Desktop\win_fetch_cacerts.rb"

Now make ruby aware of your certificate authority bundle by setting SSL_CERT_FILE. To set this in your current command prompt session, type:

set SSL_CERT_FILE=C:\RailsInstaller\cacert.pem

To make this a permanent setting, add this in your control panel.

The Manual Way (Boring)

Download the cacert.pem file from http://curl.haxx.se/ca/cacert.pem. Save this file to C:\RailsInstaller\cacert.pem.

Now make ruby aware of your certificate authority bundle by setting SSL_CERT_FILE. To set this in your current command prompt session, type:

set SSL_CERT_FILE=C:\RailsInstaller\cacert.pem

To make this a permanent setting, add this in your control panel.

win_fetch_cacerts.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
require 'net/http'
 
# create a path to the file "C:\RailsInstaller\cacert.pem"
cacert_file = File.join(%w{c: RailsInstaller cacert.pem})
 
Net::HTTP.start("curl.haxx.se") do |http|
resp = http.get("/ca/cacert.pem")
if resp.code == "200"
open(cacert_file, "wb") { |file| file.write(resp.body) }
puts "\n\nA bundle of certificate authorities has been installed to"
puts "C:\\RailsInstaller\\cacert.pem\n"
puts "* Please set SSL_CERT_FILE in your current command prompt session with:"
puts " set SSL_CERT_FILE=C:\\RailsInstaller\\cacert.pem"
puts "* To make this a permanent setting, add it to Environment Variables"
puts " under Control Panel -> Advanced -> Environment Variables"
else
abort "\n\n>>>> A cacert.pem bundle could not be downloaded."
end
end

Excellent!!!! Thanks a lot! :)

Excellent!
If you are using JRuby - just locate the file in lib\ruby\somedirectory under the jruby folder and assign the system environment variable

Using is more convient, imho:

config/initializers/ssl_configuration.rb

ENV["SSL_CERT_FILE"] = "/usr/local/rvm/usr/ssl/certs/cacerts"

How do I specify a path with a space on Windows? I would like to do

cacert_file = File.join(%w{c: Users "User Name" cacert.pem})

Where "User Name" is something like Zeno Davatz.

How would that work?

Best
Zeno

cacert_file = File.join(%w{c: Users Zeno\ Davatz cacert.pem})

I am getting this error like this using Ruby On Rails
Error:SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed,

I am following manual step
Stil i am getting same error,I am using win7 OS
pls help me

I am following first step also getting error

C:\Users\RUBY\Desktop>ruby win_fetch_cacerts.rb
win_fetch_cacerts.rb:2: syntax error, unexpected '<'
<!-- saved from url=(0063)http...
^
win_fetch_cacerts.rb:2: syntax error, unexpected tIDENTIFIER, expecting keyword_
do or '{' or '('
<!-- saved from url=(0063)https://gist.githu...
^
win_fetch_cacerts.rb:2: syntax error, unexpected tIDENTIFIER, expecting $end
...<!-- saved from url=(0063)https://gist.github.com/fnichol/86...
... ^

Thank you! It worked after I added it in control panel.

This is really useful info. If it wasn't for your gist, I wouldn't have ever known about the SSL_CERT_FILE variable. I've been tearing my hair out trying to get Bundler to talk to https://rubygems.org/; now, finally, it works!

This is great, thank you!

Thank you so much for posting this! This error was driving me nuts. If anyone's interested, in order to make the fix self-contained to the Ruby script, I did this:

  1. Download cacerts.pem to same directory as ruby script (or the /config" sub-dir in my case)
  2. Add the following to your script:
    # Fixes SSL Connection Error in Windows execution of Ruby
    # Based on fix described at: https://gist.github.com/fnichol/867550
    ENV['SSL_CERT_FILE'] = File.expand_path(File.dirname(__FILE__)) + "/config/cacert.pem"

This may be worthwhile if you're distributing the script and don't want to make users have to set the environment variable.

I tried the above fix but I still get this error

C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/bundler-1.3.5/lib/bundler/v
endor/net/http/persistent/ssl_reuse.rb:70:in `connect': An established connectio
n was aborted by the software in your host machine. - SSL_connect (Errno::ECONNA
BORTED)

Thanks a lot, works like a charm ! :D

For the uninitiated : It works without Rails Installer also. Just copy cacert.pem to any folder of your choice and set the environment variable path accordingly.

I still get this error...
WARNING: Error fetching data: SSL_connect returned=1 errno=0 state=SSLv3 read s
erver certificate B: certificate verify failed (https://rubygems.org/latest_spec
s.4.8.gz)
Updating rubygems-update
ERROR: While executing gem ... (TypeError)
can't modify frozen object

Thanks...This was really useful !!

I'm new to anything related to Ruby. I'm using WinXP Pro.

I notice that all google posts on any site seem to relate to rails. Therefore all the suggested solutions relate to rails.

I don't use rails. I want to use Watir and Watir-WebDriver for testing web applications.

So, my question is: how do I solve the SSL problem for the command:

gem install mini_magick -v 3.5 --no-document
ERROR: Could not find a valid gem 'mini_magick' (= 3.5), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect retur
ned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (
https://s3.amazonaws.com/production.s3.rubygems.org/specs.4.8.gz)

BTW: mini_magick is part of DevKit, which is needed before installing Watir.

Thanks!!! This work for me to install the net-sftp gem on my Windows!!!

Thank you ! that saved me a lot of trouble !

Wow, thanks! That was really easy to solve!

Thank you for this post ! Fixed my ssl cert. error.

@sschwartzman - I like your idea of adding the cacerts.pem to the config, and then using it to set ENV['SSL_CERT_FILE']. I tried this in my Ruby command-line application, but it wasn't working - I was still getting the same error.

The problem is that when I build my gem, the "executable" that RubyGems generates has bootstrap code where it attempts to load my gem (which causes the OpenSSL error) before I ever have a chance to affect the ENV[] statement. Here is the generated bootstrap code:

C:\RailsInstaller\Ruby1.9.3\bin>type my_gem
#!C:/RailsInstaller/Ruby1.9.3/bin/ruby.exe
#
# This file was generated by RubyGems.
#
# The application 'my_gem' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/
    version = $1
    ARGV.shift
  end
end

gem 'my_gem', version
load Gem.bin_path('my_gem', 'my_gem', version)

C:\RailsInstaller\Ruby1.9.3\bin>

And here is the error; you can see ruby running through the bootstrap code above, getting to the "load" line, and processing a 'require' statement in one of my dependencies (mixpanel_client), which eventually barfs.

C:\Sites>my_gem
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:799:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verif
y failed (OpenSSL::SSL::SSLError)
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:799:in `block in connect'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:799:in `connect'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/net/http.rb:744:in `start'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:306:in `open_http'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:775:in `buffer_open'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:203:in `block in open_loop'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:201:in `catch'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:201:in `open_loop'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:146:in `open_uri'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:677:in `open'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/open-uri.rb:685:in `read'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/mixpanel_client-3.1.2/lib/mixpanel/uri.rb:22:in `get'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/mixpanel_client-3.1.2/lib/mixpanel/client.rb:55:in `request'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/my_gem-0.0.6/lib/my_gem/mixpanel_services.rb:233:in `getVersions'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/my_gem-0.0.6/lib/my_gem/mixpanel_services.rb:287:in `<module:MixpanelSer
vices>'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/my_gem-0.0.6/lib/my_gem/mixpanel_services.rb:12:in `<top (required)>'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/my_gem-0.0.6/lib/my_gem/runner.rb:13:in `require_relative'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/my_gem-0.0.6/lib/my_gem/runner.rb:13:in `<top (required)>'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
        from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/my_gem-0.0.6/bin/my_gem:11:in `<top (required)>'
        from C:/RailsInstaller/Ruby1.9.3/bin/my_gem:23:in `load'
        from C:/RailsInstaller/Ruby1.9.3/bin/my_gem:23:in `<main>'

C:\Sites>

I wonder, is there any way to tell RubyGems to put the ENV[] in its generated output. Probably not easily (I suppose I could hand-edit the file it generates, but this is not scalable).

Thanks for the suggestion!

Thanks, this worked well!

Thank you. It worked pretty well.

Thank you for this amazing Work.

Cheers

Same error as @mandlaanilbabu here.

The Ruby way works for me. But how do I make it permanent? What should I paste in the environment variables?

I followed your instruction, but it didn't work. Any alternative?

I tried the first command that gave me an error.
Why am i not able to run win_fetch_cacerts.rb ruby file thats there in my desktop?

C:\Users\punitha\aggregator>ruby "%USERPROFILE%\Desktop\win_fetch_cacerts.rb"
ruby: No such file or directory -- C:/Users/punitha/Desktop/win_fetch_cacerts.rb
(LoadError)

thanks it works happily :-)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.